一、Pod控制器
- Master的各组件中,API Server仅负责将资源存储于etcd中,并将其变动通知给各相关的客户端程序,如kubelet、kube-scheduler、kube-proxy和kube-controller-manager等,kube-scheduler监控到处于未绑定状态的Pod对象出现时遂启动调度器为其挑选适配的工作节点。
- Kubernetes的核心功能之一还在于要确保各资源对象的当前状态(status)以匹配用户期望的状态(spec),使当前状态不断地向期望状态“和解”(reconciliation)来完成容器应用管理,而这些则是kube-controller-manager的任务。
- 创建为具体的控制器对象之后,每个控制器均通过API Server提供的接口持续监控相关资源对象的当前状态,并在因故障、更新或其他原因导致系统状态发生变化时,尝试让资源的当前状态向期望状态迁移和逼近。
二、控制器与Pod对象
- Pod控制器资源通过持续性地监控集群中运行着的Pod资源对象来确保受其管控的资源严格符合用户期望的状态,例如资源副本的数量要精确符合期望等。
- 一个Pod控制器资源至少应该包含三个基本的组成部分。
- 标签选择器:匹配并关联Pod资源对象,并据此完成受其管控的Pod资源计数。
- 期望的副本数:期望在集群中精确运行着的Pod资源的对象数量。
- Pod模板:用于新建Pod资源对象的Pod模板资源。
三、Pod资源模板
- Pod模板的配置信息中不需要apiVersion和kind字段,但除此之外的其他内容与定义自主式Pod对象所支持的字段几乎完全相同,这包括metadata和spec及其内嵌的其他各个字段。
- Pod控制器类资源的spec字段通常都要内嵌replicas、selector和template字段,其中template即为Pod模板的定义。
- 下面是一个定义在Deployment资源中的模板资源示例:
Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为,下面我们来介绍一下所有的控制器类型:
1、ReplicaSet控制器
2、Deployment控制器 适合无状态的服务部署
3、StatefulSet控制器 适合有状态的服务部署
4、DaemonSet控制器 一次部署,所有的node节点都会部署,例如一些典型的应用场景:
运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph 在每个Node上运行日志收集 daemon,例如 fluentd、 logstash 在每个Node上运行监控 daemon,例如 Prometheus Node Exporter
5、Job控制器 一次性的执行任务
6、CronJob控制器 周期性的执行任务
一、ReplicaSet控制器
1.1、作用:用于确保由其管控的Pod对象副本数在任一时刻都能精确满足期望的数量。ReplicaSet控制器资源启动后会查找集群中匹配其标签选择器的Pod资源对象,当前活动对象的数量与期望的数量不吻合时,多则删除,少则通过Pod模板创建以补足。
1.2、功能:
- 确保Pod资源对象的数量:ReplicaSet需要确保由其控制运行的Pod副本数量精确吻合配置中定义的期望值,否则就会自动补足所缺或终止所余。
- 确保Pod健康运行:探测到由其管控的Pod对象因其所在的工作节点故障而不可用时,自动请求由调度器于其他工作节点创建缺失的Pod副本。
- 弹性伸缩:业务规模因各种原因时常存在明显波动,在波峰或波谷期间,可以通过ReplicaSet控制器动态调整相关Pod资源对象的数量。
- 通过HPA(HroizontalPodAutoscaler)控制器实现Pod资源规模的自动伸缩
1.3、可以使用YAML或JSON格式的清单文件定义其配置它的spec字段一般嵌套使用以下几个属性字段。
| replicas | integer | 期望的Pod对象副本数 |
| — | — | — |
| selector | Object | 当前控制器匹配Pod对象副本的标签选择器,支持matchLabels和matchExpressions两种匹配机制 |
| template | Object | 用于补足Pod副本数量时使用的Pod模板资源 |
| minReadySeconds | integer | 新建的Pod对象,在启动后的多长时间内如果其容器未发生崩溃等异常情况即被视为“就绪”;默认为0秒,表示一旦就绪性探测成功,即被视作可用 |
创建rs-example.yaml文件
apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-example spec: replicas: 2 selector: matchLabels: app: rs-demo template: metadata: labels: app: rs-demo spec: containers: - name: nginx image: nginx ports: - name: http containerPort: 80
[root@k8s-master ~]# kubectl get pod -l app=rs-demo NAME READY STATUS RESTARTS AGE rs-example-vrg74 1/1 Running 0 31m rs-example-w2682 1/1 Running 0 31m [root@k8s-master ~]# kubectl get replicaset NAME DESIRED CURRENT READY AGE rs-example 2 2 2 32m [root@k8s-master ~]# kubectl get replicaset rs-example -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR rs-example 2 2 2 32m nginx nginx app=rs-demo [root@k8s-master ~]#
缺少Pod副本,任何原因导致的相关Pod对象丢失,都
会由ReplicaSet控制器自动补足。
- 手动删除上面列出的一个Pod对象
$ kubectl delete pods rs-example-vrg74
- 再次列出相关Pod对象的信息,可以看到
rs-example-vrg74
被删除,而新的Pod对象rs-example-9t5w2被rs-example控制器创建:[root@k8s-master ~]# kubectl delete pod rs-example-vrg74 pod "rs-example-vrg74" deleted [root@k8s-master ~]# kubectl get pod -l app=rs-demo NAME READY STATUS RESTARTS AGE rs-example-9t5w2 0/1 ContainerCreating 0 12s rs-example-w2682 1/1 Running 0 34m [root@k8s-master ~]# kubectl get pod -l app=rs-demo NAME READY STATUS RESTARTS AGE rs-example-9t5w2 1/1 Running 0 51s rs-example-w2682 1/1 Running 0 35m
- 强行修改隶属于控制器rs-example的Pod资源标签,会导致它不再被控制器作为副本计数,这也将触发控制器的Pod对象副本缺失补足机制。
例如,将rs-example-9t5w2的标签app的值改为rs:[root@k8s-master ~]# kubectl label pods rs-example-9t5w2 app=rs --overwrite pod/rs-example-9t5w2 labeled [root@k8s-master ~]# kubectl get pod -l app=rs-demo NAME READY STATUS RESTARTS AGE rs-example-r4hgb 0/1 ContainerCreating 0 3s rs-example-w2682 1/1 Running 0 38m [root@k8s-master ~]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS rs-example-9t5w2 1/1 Running 0 4m11s app=rs rs-example-r4hgb 1/1 Running 0 25s app=rs-demo rs-example-w2682 1/1 Running 0 38m app=rs-demo
- 多出pod副本:一旦被标签选择器匹配到的Pod资源数量因任何原因超出期望值,多余的部分都将被控制器自动删除。
- 例如,为pod-example手动为其添加“app: rs-demo”标签:
$ kubectl label pods rs-example-26fnb app=rs-demp --overwrite
- 再次列出相关的Pod资源,可以看到rs-example控制器启动了删除多余Pod的操作,pod-example正处于终止过程中:
[root@k8s-master ~]# kubectl label pods rs-example-9t5w2 app=rs-demo --overwrite pod/rs-example-9t5w2 labeled [root@k8s-master ~]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS rs-example-9t5w2 1/1 Running 0 8m50s app=rs-demo rs-example-rhrhl 0/1 Terminating 0 57s app=rs-demo rs-example-w2682 1/1 Running 0 43m app=rs-demo
这就意味着,任何自主式的或本隶属于其他控制器的Pod资源其标签变动的结果一旦匹配到了其他的副本数足额的控制器,就会导致这类Pod资源被删除。
删除ReplicaSet控制器资源
使用kubectl delete命令删除ReplicaSet对象时默认会一并删除其管控的各Pod对象。 $ kubectl delete replicasets rs-example
查看replicaset资源信息
1、查看所有replicaset(子资源)信息 [root@k8s-master ~]# kubectl get rs NAME DESIRED CURRENT READY AGE rs-example 5 5 5 50m 2、查看所有replicaset(子资源)详细信息 $ kubectl describe replicasets $ kubectl describe replicasets/rs-example
1.4、更新ReplicaSet控制器
更改Pod模板:升级应用,ReplicaSet控制器的Pod模板可随时按需修改,但它仅影响这之后由其新建的Pod对象,对已有的副本不会产生作用。但在用户逐个手动关闭其旧版本的Pod资源后就能以新代旧,实现控制器下应用版本的滚动升级。
修改原ReplicaSet.yaml文件镜像
apply文件,查看image信息
kubectl get pod -o custom-columns=pod_name:metadata.name,pod_image:spec.containers[0].image
[root@k8s-master contorlermanager]# kubectl get pod -o custom-columns=pod_name:metadata.name,pod_image:spec.containers[0].image pod_name pod_image rs-example-5nqt5 nginx rs-example-gs8x9 nginx rs-example-lfm4t nginx rs-example-xrmcj nginx rs-example-z5rsv nginx [root@k8s-master contorlermanager]# kubectl delete -f rs-example.yaml replicaset.apps "rs-example" deleted [root@k8s-master contorlermanager]# kubectl apply -f rs-example.yaml replicaset.apps/rs-example created [root@k8s-master contorlermanager]# kubectl get pod -o custom-columns=pod_name:metadata.name,pod_image:spec.containers[0].image pod_name pod_image rs-example-cmpb2 busybox rs-example-k7qhf busybox rs-example-mwv2w busybox rs-example-qvhkx busybox rs-example-w6p4r busybox
扩容与缩容:
改动ReplicaSet控制器对象配置中期望的Pod副本数量(replicas字段)会由控制器实时做出响应,从而实现应用规模的水平伸缩。
kubectl还提供了一个专用的子命令scale用于实现应用规模的伸缩,它支持从资源清单文件中获取新的目标副本数量,也可以直接在命令行通过“–replicas”选项进行读取,将rs-example控制器的Pod副本数量提升至5个:
kubectl scale replicasets rs-example --replicas=5
[root@k8s-master contorlermanager]#kubectl scale replicas rs-example --replicas=5 [root@k8s-master contorlermanager]# kubectl get pod NAME READY STATUS RESTARTS AGE rs-example-2df8f 1/1 Running 0 68s rs-example-9m8m4 1/1 Running 0 68s rs-example-jq2bv 1/1 Running 0 2m17s rs-example-njzd9 1/1 Running 0 2m17s rs-example-rjw79 1/1 Running 0 68s [root@k8s-master contorlermanager]# kubectl get rs rs-example NAME DESIRED CURRENT READY AGE rs-example 5 5 4 104s
1.5、故障转移
目前有3个副本分别运行在node1和node2上。
现在模拟 k8s-node1 故障,关闭该节点。[root@k8s-master liveliness]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-5546c765b7-4466q 1/1 Running 0 46s 10.244.2.46 k8s-node2 <none> <none> nginx-deployment-5546c765b7-fmr8b 1/1 Running 0 46s 10.244.2.47 k8s-node2 <none> <none> nginx-deployment-5546c765b7-h5nvq 1/1 Running 0 46s 10.244.1.143 k8s-node1 <none> <none>
等待一段时间,Kubernetes 会检查到 k8s-node1不可用,将 k8s-node1上的 Pod 标记为 terminating 状态,并在 k8s-node1 上新创建两个 Pod,维持总副本数为 3。
[root@k8s-master contorlermanager]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES rs-example-9m8m4 1/1 Running 0 7m2s 10.244.1.140 k8s-node1 <none> <none> rs-example-jq2bv 1/1 Running 0 8m11s 10.244.2.39 k8s-node2 <none> <none> rs-example-njzd9 1/1 Running 0 8m11s 10.244.1.139 k8s-node1 <none> <none> [root@k8s-master liveliness]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-5546c765b7-4466q 1/1 Running 0 7m34s 10.244.2.46 k8s-node2 <none> <none> nginx-deployment-5546c765b7-fmr8b 1/1 Running 0 7m34s 10.244.2.47 k8s-node2 <none> <none> nginx-deployment-5546c765b7-h5nvq 1/1 Terminating 0 7m34s 10.244.1.143 k8s-node1 <none> <none> nginx-deployment-5546c765b7-hfmjc 1/1 Running 0 61s 10.244.2.48 k8s-node2 <none> <none> [root@k8s-master liveliness]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-5546c765b7-4466q 1/1 Running 0 9m54s 10.244.2.46 k8s-node2 <none> <none> nginx-deployment-5546c765b7-fmr8b 1/1 Running 0 9m54s 10.244.2.47 k8s-node2 <none> <none> nginx-deployment-5546c765b7-hfmjc 1/1 Running 0 3m21s 10.244.2.48 k8s-node2 <none> <none>
当 k8s-node1 恢复后,terminating的 Pod 会被删除,不过已经运行的 Pod不会重新调度回 k8s-node1。