控制器介绍
pod 是 kubernetes 的最小管理单元,在 kubernetes 中,按照 pod 的创建方式可以将其分为两类
- 自主式 pod:kubernetes 直接创建出来的 pod,这种 pod 删除后就没有了,也不会重新创建
- 控制器创建的 pod:kubernetes 通过控制器创建的 pod,这种 pod 删除了之后还会自动创建
什么是 pod 控制器
pod 控制器是管理 pod 的中间层,使用 pod 控制器之后,只需要告诉 pod 控制器,想要多少个什么样的 pod 就可以了,它会创建出满足条件的 pod 并确保每一个 pod 资源处于用户期望的目标状态。如果 pod 资源在运行中出现故障,它会基于指定策略重新编排 pod
在 kubernetes 中,有很多类型的 pod 控制器,每种都有自己适合的场景,常见的控制器有下面这些
- ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代
- ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级
- Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本
- Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷
- DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务
- Job:它创建出来的pod只要完成任务就立即退出,不需要重启或重建,用于执行一次性任务
- Cronjob:它创建的Pod负责周期性任务控制,不需要持续后台运行
- StatefulSet:管理有状态应用
ReplicaSet(RS) 控制器
ReplicaSet 的主要作用是保证一定数量的 pod 正常运行,它会持续监听这些 pod 的运行状态,一旦 pod 发生故障,就会重启或者新建,同时它还支持对 pod 数量的扩缩容和镜像版本的升降级
- Replication Controller 为 Kubernetes 的一个核心内容,应用托管到 Kubernetes 之后,需要保证应用能够持续的运行,Replication Controller 就是这个保证的 key,主要的功能如下:
- 确保 pod 数量:它会确保 Kubernetes 中有指定数量的 Pod 在运行。如果少于指定数量的 pod,Replication Controller 会创建新的,反之则会删除掉多余的以保证 Pod 数量不变。
- 确保 pod 健康:当 pod 不健康,运行出错或者无法提供服务时,Replication Controller 也会杀死不健康的 pod,重新创建新的。
- 弹性伸缩 :在业务高峰或者低峰期的时候,可以通过 Replication Controller 动态的调整 pod 的数量来提高资源的利用率。同时,配置相应的
- 监控功能(Hroizontal Pod Autoscaler),会定时自动从监控平台获取 Replication Controller 关联 pod 的整体资源使用情况,做到自动伸缩。
- 滚动升级:滚动升级为一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定,在初始化升级的时候就可以及时发现和解决问题,避免问题不断扩大。
ReplicaSet 的资源清单文件:
apiVersion: apps/v1 # 版本号 kind: ReplicaSet # 类型 metadata: # 元数据 name: # rs名称 namespace: # 所属命名空间 labels: #标签 controller: rs spec: # 详情描述 replicas: 3 # 副本数量 selector: # 选择器,通过它指定该控制器管理哪些 pod,和 template 里的标签对应 matchLabels: # Labels匹配规则 app: nginx-pod matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80
在这里面,需要新了解的配置项就是 spec 下面的几个选项
- replicas:指定副本数量,其实就是当前 rs 创建出来的 pod 的数量,默认为 1
- selector:选择器。它的作用是建立 pod 控制器和 pod 之间的关联关系,采用的 Label Selector 机制,在 pod 模板上定义 label,在控制器上定义选择器,就可以表明当前控制器能管理哪些 pod 了
- template:模板,就是当前控制器创建的 pod 所使用的模板,里面其实就是 pod 的定义
创建 ReplicaSet
创建 pc-replicaset.yaml 文件,内容如下:
apiVersion: apps/v1 kind: ReplicaSet # 类型为 RS 控制器 metadata: name: pc-replicaset # 这个就是 rs 的名字,生成的 pod 会在这个后面加上随机字符 namespace: zouzou spec: replicas: 3 # 副本数为 3 个 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.14
创建 RS 控制器
# 创建 RS 控制器 kubectl apply -f pc-replicaset.yaml
查看 RS 控制器和 pod
# 查看 RS 控制器,rs 是 replicaset 的简写 # DESIRED:期望的副本数量 # CURRENT:当前的副本数量 # READY:已经准备好提供服务的副本数量 [root@dce-10-6-215-215 tmp]# kubectl get rs pc-replicaset -n zouzou -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-replicaset 3 3 3 89s nginx nginx:1.14 app=nginx-pod # 查看 pod,这里发现控制器创建出来的 pod 名称是在控制器名称后面拼接了-xxxxx 随机码 [root@dce-10-6-215-215 tmp]# [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-5vbjj 1/1 Running 0 110s pc-replicaset-qddc4 1/1 Running 0 110s pc-replicaset-qr7wc 1/1 Running 0 110s
扩缩容
扩缩容就是 pod 的数量,对应 yaml 里的 spec:replicas
1.可以通过编辑 rs 的副本数量,修改 spec:replicas: 6 即可
# 通过 edit 实现,改完文件保存之后就会自动生效 [root@dce-10-6-215-215 tmp]# kubectl edit rs pc-replicaset -n zouzou replicaset.apps/pc-replicaset edited # 查看 pod 的数量,变成了 6 个 pod [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-5vbjj 1/1 Running 0 24m pc-replicaset-6sb4z 1/1 Running 0 9s pc-replicaset-7z8tv 1/1 Running 0 9s pc-replicaset-qddc4 1/1 Running 0 24m pc-replicaset-qr7wc 1/1 Running 0 24m pc-replicaset-twbzm 1/1 Running 0 9s
2.通过命令来实现,使用 scale 命令实现扩缩容, 后面 --replicas=n 直接指定目标数量即可
# 通过命令修改副本数量,改为两个副本数 [root@dce-10-6-215-215 tmp]# kubectl scale rs pc-replicaset --replicas=2 -n zouzou replicaset.apps/pc-replicaset scaled # 查看pod,发现有四个的状态是 Terminating [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-5vbjj 1/1 Terminating 0 27m pc-replicaset-6sb4z 1/1 Terminating 0 2m47s pc-replicaset-7z8tv 1/1 Terminating 0 2m47s pc-replicaset-qddc4 1/1 Running 0 27m pc-replicaset-qr7wc 1/1 Running 0 27m pc-replicaset-twbzm 1/1 Terminating 0 2m47s # 在等会查看,副本数就只有两个了 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-qddc4 1/1 Running 0 27m pc-replicaset-qr7wc 1/1 Running 0 27m
3.vim 编辑修改 pc-replicaset.yaml 文件,改好副本数保存后,在 apply 一下,我这里把副本数改为了 5
# 修改副本数,改为 5 [root@dce-10-6-215-215 tmp]# vim pc-replicaset.yaml # 修改完文件后重新配置一下 [root@dce-10-6-215-215 tmp]# kubectl apply -f pc-replicaset.yaml replicaset.apps/pc-replicaset configured # 查看发现有三个 pod 正在创建 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-96ngk 0/1 ContainerCreating 0 4s pc-replicaset-b8fhc 0/1 ContainerCreating 0 4s pc-replicaset-bqhvz 0/1 ContainerCreating 0 4s pc-replicaset-qddc4 1/1 Running 0 30m pc-replicaset-qr7wc 1/1 Running 0 30m # 五个pod 都已经运行了 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE pc-replicaset-96ngk 1/1 Running 0 11s pc-replicaset-b8fhc 1/1 Running 0 11s pc-replicaset-bqhvz 1/1 Running 0 11s pc-replicaset-qddc4 1/1 Running 0 30m pc-replicaset-qr7wc 1/1 Running 0 30m
镜像升级
目前我们用的镜像是 nginx:1.14的。现在我们要升级为 1.15
也有三种修改的方式
1.可以通过编辑rs的容器镜像 - image: nginx:1.15
# 通过 edit 实现,改完文件保存之后就会自动生效 [root@dce-10-6-215-215 tmp]# kubectl edit rs pc-replicaset -n zouzou replicaset.apps/pc-replicaset edited # 控制器 pc-replicaset 的 nginx 镜像已经成了 1.15 之前是1.14 [root@dce-10-6-215-215 tmp]# kubectl get rs -n zouzou -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR nginx3-c5d7c9466 1 1 1 21m nginx nginx:1.14 app=nginx3,pod-template-hash=c5d7c9466 pc-replicaset 5 5 5 36m nginx nginx:1.15 app=nginx-pod
2.通过命令来实现,kubectl set image rs rs名称 容器=镜像版本 -n namespace
# 通过命令的方式,将镜像版本改为 1.14 [root@dce-10-6-215-215 tmp]# kubectl set image rs pc-replicaset nginx=nginx:1.14 -n zouzou replicaset.apps/pc-replicaset image updated # 查看 rs,发现镜像版本从原来的 1.15 改为了 1.14 [root@dce-10-6-215-215 tmp]# kubectl get rs -n zouzou -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR nginx3-c5d7c9466 1 1 1 26m nginx nginx:1.14 app=nginx3,pod-template-hash=c5d7c9466 pc-replicaset 5 5 5 41m nginx nginx:1.14 app=nginx-pod
3.vim 编辑修改 pc-replicaset.yaml 文件,把镜像改为 1.15
# 修改文件,改镜像,保存 [root@dce-10-6-215-215 tmp]# vim pc-replicaset.yaml # 重新 apply 一下 pc-replicaset.yaml [root@dce-10-6-215-215 tmp]# kubectl apply -f pc-replicaset.yaml replicaset.apps/pc-replicaset configured # 查看 rs,发现镜像又变成了 1.15 [root@dce-10-6-215-215 tmp]# kubectl get rs -n zouzou -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR nginx3-c5d7c9466 1 1 1 28m nginx nginx:1.14 app=nginx3,pod-template-hash=c5d7c9466 pc-replicaset 5 5 5 43m nginx nginx:1.15 app=nginx-pod
删除 ReplicaSet
删除 RS 控制器也有三种方法
# 使用 kubectl delete 命令会删除此 RS 以及它管理的 Pod # 在 kubernetes 删除 RS 前,会将 RS 的 replicasclear 调整为 0,等待所有的 Pod 被删除后,在执行 RS 对象的删除 [root@dce-10-6-215-215 tmp]# kubectl delete rs pc-replicaset -n zouzou replicaset.apps "pc-replicaset" deleted # 如果希望仅仅删除 RS 对象(保留 Pod ),可以使用 kubectl delete 命令时添加 --cascade=false 选项(不推荐)。 [root@dce-10-6-215-215 tmp]# kubectl delete rs pc-replicaset -n dev --cascade=false replicaset.apps "pc-replicaset" deleted [root@dce-10-6-215-215 tmp]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-cl82j 1/1 Running 0 75s pc-replicaset-dslhb 1/1 Running 0 75s # 也可以使用yaml直接删除(推荐) [root@dce-10-6-215-215 tmp]# kubectl delete -f pc-replicaset.yaml replicaset.apps "pc-replicaset" deleted
RS 的选择器
rs 在标签选择器上,除了可以定义键值对的选择方式。还支持 matchExpressions 字段,可以提供多种选择,目前支持的操作有
- In:label 的值在某个列表中
- NotIn:列表的值不在某个列表中
- Exists:某个 label 存在
- DoesNotExist:某个 label 不存在
如下面的 rs.yaml 加上 matchExpressions 字段
apiVersion: apps/v1 kind: ReplicaSet # 使用 rs 选择器 metadata: name: frontend labels: app: guestbook tier: frontend spec: replicas: 3 selector: matchExpressions: - key: tier # 只要有 key,且 key 的值为 tier 就行,不管 tier 对应的 value 是什么 operator: Exists # 某个 label 存在 template: metadata: labels: tier: frontend # 这里存在 tier 的 key,就可以匹配上 spec: containers: - name: php-redis image: yecc/gcr.io-google_samples-gb-frontend:v3 imagePullPolicy: IfNotPresent
In 的用法
apiVersion: apps/v1 kind: ReplicaSet # 使用 rs 选择器 metadata: name: frontend labels: app: guestbook tier: frontend spec: replicas: 3 selector: matchExpressions: - key: tier # operator: In # 在某个列表里面 ,在 values 里面 values: - spring-k8s - haha template: metadata: labels: tier: sg-k8s # 匹配不上,要么是 spring-k8s 或者 haha spec: containers: - name: php-redis image: yecc/gcr.io-google_samples-gb-frontend:v3 imagePullPolicy: IfNotPresent