Kubernetes入门之本地集群minikube
随着科技的发展,互联网技术更新迭代也越来越快。我们也进入了大数据、微服务、智能AI、物联网、区块链、云的时代。Docker
和DevOps
的快速发展,企业的架构也发生了重大变化。Kubernetes
的出现也让大家的服务更加自动化更加高可用。这篇文章将介绍Kubernetes
和基本的使用方法。
什么是Kubernetes
Kubernetes
是一个可移植,可扩展的开源平台,用于管理容器化工作负载和服务,有助于声明性配置和自动化。它拥有庞大,快速发展的生态系统。 Kubernetes服务,支持和工具广泛可用。它有自己的学习曲线,因为它引入了各种概念,如Node
,Pod
,Replication Controller
,Health Checks
,Services
,Labels
等。在未来的文章中,我们将分解这些构建块,以了解在Kubernetes中如何协调。
Kubernetes
根据Google一个内部项目演变出来的,并且已经运行了十多年的工作量
为什么需要Kubernetes
容器是捆绑和运行应用程序的好方法。在生产环境中,您需要管理运行应用程序的容器并确保没有停机时间。例如,如果容器发生故障,则需要启动另一个容器。如果系统处理这种行为会不会更容易?
这就是为什么需要Kubernetes!Kubernetes为您提供了一个弹性运行分布式系统的框架。它负责您的扩展要求,故障转移,部署模式等。例如,Kubernetes可以轻松管理系统的部署。
它提供终多功能:
-
服务发现和负载平衡
Kubernetes可以使用DNS名称或使用自己的IP地址公开容器。如果容器的流量很高,Kubernetes能够负载均衡并分配网络流量,以便部署稳定。
-
存储编排
Kubernetes允许您自动安装您选择的存储系统,例如本地存储,公共云提供商等。
-
自动部署和回滚
您可以使用Kubernetes描述已部署容器的所需状态,并且可以以受控速率将实际状态更改为所需状态。例如,您可以自动化Kubernetes为您的部署创建新容器,删除现有容器并将所有资源用于新容器。
-
自动装箱
Kubernetes允许您指定每个容器需要多少CPU和内存(RAM)。当容器指定了资源请求时,Kubernetes可以更好地决定管理容器的资源。
-
自动恢复
Kubernetes重新启动失败的容器,替换容器,杀死不响应用户定义的运行状况检查的容器,并且在它们准备好服务之前不会将它们通告给客户端。
-
秘钥和配置管理
Kubernetes允许您存储和管理敏感信息,例如密码,OAuth令牌和ssh密钥。您可以部署和更新机密和应用程序配置,而无需重建容器映像,也不会在堆栈配置中暴露机密。
Kubernetes不是一个传统的,包罗万象的PaaS(平台即服务)系统。由于Kubernetes在容器级而非硬件级运行,因此它提供了PaaS产品常用的一些通用功能,例如部署,扩展,负载平衡,日志记录和监控。但是,Kubernetes不是单片,而且这些默认解决方案是可选的和可插拔的。 Kubernetes提供了构建开发人员平台的构建块,但在重要的地方保留了用户选择和灵活性
安装
上面介绍了基础的概念,现在讲解下怎么安装,以Mac OS
为例子,Windows
和Linux
基本都是大同小异。各个平台的安装有很多种,选择自己平台最快捷的那个即可。具体可以查看各个平台的安装文档,以下Mac OS
的安装方式。
CURL安装
-
下载
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
-
更改权限
chmod +x ./kubectl
-
添加到PATH
sudo mv ./kubectl /usr/local/bin/kubectl
-
测试
kubectl version
Homebrew安装
-
安装
brew install kubernetes-cli
-
测试
kubectl version
zsh命令行中自动完成,将
source <(kubectl completion zsh)
加入到.zshrc
文件中,重启终端。
验证配置
为了让kubectl
能够查找和访问Kubernetes
集群,它需要一个kubeconfig
文件,该文件是在使用kube-up.sh
创建集群或成功部署Minikube
集群时自动创建的。默认情况下,kubectl配置位于 〜/.kube/config
。
通过获取群集状态检查kubectl是否已正确配置:
meshell@docker# kubectl cluster-info
在没有安装Minikube
之前命令会报下面的错误
Kubernetes master is running at http://localhost:8080
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server localhost:8080 was refused - did you specify the right host or port?
安装Minikube
Kubernetes
本地集群需要单独安装Minikube
工具。我们可以能过Homebrew
来进行安装.
brew cask install minikube
安装完成之后。执行启动命令来创建一个本地的集群服务.
minikube start
如果出现
machine does not exist
错误,你需要执行minikube delete
命令在启动
minikube start
之前,你需要安装HyperKit,VirtualBox, VMware Fusion其中一个. 当然你也可以使用无VM模式minikube start --vm-driver=none
此命令第一次需要等待很久。
启动成功会看到下面一样的输出,之后我们就可以愉快的玩耍Kubernetes
了.
�� minikube v1.2.0 on darwin (amd64)
�� Tip: Use 'minikube start -p <name>' to create a new cluster, or 'minikube delete' to delete this one.
�� Re-using the currently running virtualbox VM for "minikube" ...
⌛ Waiting for SSH access ...
�� Configuring environment for Kubernetes v1.15.0 on Docker 18.09.6
�� Downloading kubelet v1.15.0
�� Relaunching Kubernetes v1.15.0 using kubeadm ...
⌛ Verifying: apiserver proxy etcd scheduler controller dns
�� Done! kubectl is now configured to use "minikube"
如果需要使用本地的
Docker
服务,需要执行eval $(minikube docker-env)
命令. 这样本地的docker
可以和minikube
虚拟机中的docker
可以通信.
Dashboard
Dashboard是基于Web的Kubernetes用户界面。 您可以使用Dashboard将容器化应用程序部署到Kubernetes集群,对容器化应用程序进行故障排除,以及管理集群资源。 您可以使用Dashboard来概述群集上运行的应用程序,以及创建或修改单个Kubernetes资源(例如部署,作业,守护进程等)。 例如,您可以使用部署向导扩展部署,启动滚动更新,重新启动Pod或部署新应用程序。 仪表板还提供有关群集中Kubernetes资源状态以及可能发生的任何错误的信息。
启动好minikube start
之后,就可以执行minikube dashboard
自动打开浏览器再打开Dashboard
。
部署
完成安装之后,我们就可以发布,更新,回滚自己的程序。这个时候我们就需要了解Pod
、ReplicaSet
、Deployment
、Service
相关的概念。
Pod
Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。
一个Pod封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。Pod代表部署的一个单位:Kubernetes中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。
Docker是Kubernetes Pod中最常见的runtime ,Pods也支持其他容器runtimes。
Kubernetes中的Pod使用可分两种主要方式:
- Pod中运行一个容器。“one-container-per-Pod”模式是Kubernetes最常见的用法; 在这种情况下,你可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。
- Pods中运行多个需要一起工作的容器。Pod可以封装紧密耦合的应用,它们需要由多个容器组成,它们之间能够共享资源,这些容器可以形成一个单一的内部service单位 - 一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理
每个Pod都是运行应用的单个实例,如果需要水平扩展应用(例如,运行多个实例),则应该使用多个Pods,每个实例一个Pod。在Kubernetes中,这样通常称为Replication。Replication的Pod通常由Controller创建和管理。
ReplicaSet
ReplicaSet的目的是在任何给定时间维护一组稳定的副本Pod。因此,它通常用于保证指定数量的相同Pod的可用性。
如何使用ReplicaSet
大多数kubectl 支持Replication Controller 命令的也支持ReplicaSets。rolling-update命令除外,如果要使用rolling-update,请使用Deployments来实现。
虽然ReplicaSets可以独立使用,但它主要被Deployments用作pod机制的创建、删除和更新。当使用Deployment时,你不必担心创建pod的ReplicaSets,因为可以通过Deployment实现管理ReplicaSets。
何时使用ReplicaSet
ReplicaSet能确保运行指定数量的pod。然而,Deployment是一个更高层次的概念,它能管理ReplicaSets,并提供对pod的更新等功能。因此,我们建议你使用Deployment来管理ReplicaSets,除非你需要自定义更新编排。
这意味着你可能永远不需要操作ReplicaSet对象,而是使用Deployment替代管理 。
Deployment
Deployment为Pod和ReplicaSet(升级版的Replication Controller)提供声明式更新。
你只需要在Deployment中描述您想要的目标状态是什么,Deployment controller就会帮您将Pod和ReplicaSet的实际状态改变到您的目标状态。您可以定义一个全新的Deployment来创建ReplicaSet或者删除已有的Deployment并创建一个新的来替换。
Note: 您不该手动管理由Deployment创建的ReplicaSet,否则您就篡越了Deployment controller的职责!
典型的用例如下:
- 使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
- 然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
- 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
- 扩容Deployment以满足更高的负载。
- 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
- 根据Deployment的状态判断上线是否hang住了。
- 清除旧的不必要的ReplicaSet
创建第一个Deployment
从上面的描述得知,我们只需要创建好Deployment
就会自动完成ReplicaSet
和pod
。下面就创建一个Nginx
的Deployment。
在Kubernetes中创建对象时,必须提供描述其所需Status的对象Spec,以及关于对象(如name)的一些基本信息。当使用Kubernetes API创建对象(直接或通过kubectl)时,该API请求必须将该信息作为JSON包含在请求body中。通常,可以将信息提供给kubectl .yaml文件,在进行API请求时,kubectl将信息转换为JSON。
一个描述运行nginx:1.16.0
Docker镜像的部署:
apiVersion: extensions/v1beta1 # for versions before 1.16.0 use extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment # deployment的名称
spec:
selector:
matchLabels:
app: nginx # 选择器必须匹配 template中的metadata.labels
replicas: 3 # tells deployment to run 3 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.0
ports:
- containerPort: 80
执行下面命令:
meShell@k8s$ kubectl create -f ./nginx-deployment.yaml --record
deployment "nginx-deployment" created
将kubectl的–record的flag
设置为true可以在annotation
中记录当前命令创建或者升级了该资源。这在未来会很有用,例如,查看在每个 Deployment revision
中执行了哪些命令。
查看创建之后的效果:
meShell@k8s$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 5m23s
NAME
列出群集中的部署名称。DESIRED
显示应用程序的所需副本数,您在创建部署时定义这些副本。这是理想的状态。CURRENT
显示当前正在运行的副本数量。UP-TO-DATE
显示已更新以实现所需状态的副本数。AVAILABLE
显示用户可以使用的应用程序副本数。AGE
显示应用程序运行的时间。
所有的replica都已经是最新的了(包含最新的pod template),可用的(根据Deployment中的.spec.minReadySeconds声明,处于已就绪状态的pod的最少个数)。执行kubectl get rs
和kubectl get pods
会显示Replica Set(RS)和Pod已创建。
meShell@k8s$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-7d9d7464fb 3 3 3 9m44s
meShell@k8s$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-7d9d7464fb-mrc4h 1/1 Running 0 11m
nginx-deployment-7d9d7464fb-rn55g 1/1 Running 0 11m
nginx-deployment-7d9d7464fb-sdd5h 1/1 Running 0 11m
Service
一种抽象的方式暴露在一组运行的应用程序Pods
作为网络服务。
使用Kubernetes,您无需修改应用程序即可使用不熟悉的服务发现机制。Kubernetes为Pods提供了自己的IP地址和一组Pod的单个DNS名称,并且可以在它们之间进行负载均衡。
定义服务
Kubernetes中的服务是一个REST对象,类似于Pod。与所有REST对象一样,您可以POST向API服务器定义服务以创建新实例。
我们为刚才的nginx-deployment
创建服务对象:
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
type: NodePort # 为POD开放端口
ports:
- protocol: TCP
port: 80
nodePort: 30000 # 30000流量转到80端口
执行kubectl apply -f nginx-service.yaml
来创建Service
meShell@k8s$ kubectl apply -f nginx-service.yaml
service/nginx-service created
在静态端口(NodePort)上的每个节点的IP上公开服务。ClusterIP服务,向其中的NodePort服务的路由,自动创建。您可以NodePort通过请求从群集外部联系服务
如果你使用的是minikube
, 你通过minikube service nginx-service --url
来获取访问入口
meShell@k8s$ minikube service nginx-service --url
http://192.168.99.105:30000
NodePort
一般是配全externalIPs
一起使用。如果你是本地使用,你可以使用端口转发。下面的命令就建立了一个端口转发:
meShell@k8s$ kubectl port-forward nginx-deployment-7d9d7464fb-mrc4h 30001:80
Forwarding from 127.0.0.1:30001 -> 80
Forwarding from [::1]:30001 -> 80
在浏览器打开http://127.0.0.1:30001/
和上面是同样的效果。
kubectl port-forward
需要的是pod
名称, 你可以通过kubectl get pods
得到名称.
Ingress
上面我们是能过暴露外部的端口来进行访问服务。现在我们将使用Ingress来访问Pods
。Ingress将集群外部的HTTP和HTTPS路由暴露给集群中的 服务。流量路由由Ingress资源上定义的规则控制。
internet
|
[ Ingress ]
--|-----|--
[ Services ]
可以将Ingress配置为为服务提供外部可访问的URL,负载平衡流量,终止SSL/TLS以及提供基于名称的虚拟主机。一个入口控制器负责履行入口,通常有一个负载均衡器,虽然它也可以配置您的边缘路由器或额外的前端,以帮助处理流量。
Ingress不会暴露任意端口或协议。将除HTTP和HTTPS之外的服务暴露给互联网通常使用Service.Type = NodePort或 Service.Type = LoadBalancer类型的服务。
为了使Ingress资源正常工作,群集必须运行入口控制器(Ingress Controller
)。
与作为kube-controller-manager二进制文件一部分运行的其他类型的控制器不同,Ingress控制器不会自动与集群一起启动。使用此页面选择最适合您的群集的入口控制器实施。
Kubernetes
作为一个项目目前支持和维护GCE和nginx控制器。
在minikube
开启Ingress Controller
只需要执行下面的命令:
meShell@k8s$ minikube addons enable ingress
✅ ingress was successfully enabled
创建Ingress
定义下面的配置文件ingress-nginx.yaml
。执行“
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: \"false\"
spec:
rules:
- host: loocode.de # 定义hostname
http: # 访问协议
paths: # 路径
- path: / # 可以指定多个路径为不同的服务
backend:
serviceName: nginx-service
servicePort: 80
输入下面命令来创建对象:
meShell@k8s$ kubectl apply -f ingress-nginx.yaml
查看创建之后的服务
meShell@k8s$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
nginx-ingress loocode.de 10.0.2.15 80 14h
使用minikube ip
查集群IP
。通过修改/etc/hosts
将设定的host
指定到集群IP
meShell@k8s$ minikube ip
192.168.99.105
修改/etc/hosts
文件。
windows目录
C:\window\system32\drivers\etc\hosts
192.168.99.105 loocode.de
通过上面的介绍讲解,对kubernetes
有个基础的概念,对其的使用也是很基础。我们将在下期的文章主要讲解每一个对象和一些微服务的示例。