k8s--deployment 控制器、扩缩容、升级策略
介绍
Deployment 表示用户对 K8S 集群的一次更新操作。Deployment 是一个比 RS( Replica Set, RS) 应用模型更广的 API 对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减少到 0 的复合操作。
这样一个复合操作用一个 RS 是不好描述的,所以用一个更通用的 Deployment 来描述。以 K8S 的发展方向,未来对所有长期伺服型的业务的管理,都会通过 Deployment来管理。
Deployment主要功能有下面几个:
- 支持 ReplicaSet 的所有功能
- 支持发布的停止、继续
- 支持滚动升级和回滚版本
Deployment 的资源清单文件:
apiVersion: apps/v1 # 版本号 kind: Deployment # 类型 metadata: # 元数据 name: # rs名称 namespace: # 所属命名空间 labels: #标签 controller: deploy spec: # 详情描述 replicas: 3 # 副本数量 revisionHistoryLimit: 3 # 保留历史版本 paused: false # 暂停部署,默认是false progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600 strategy: # 策略 type: RollingUpdate # 滚动更新策略 rollingUpdate: # 滚动更新 maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 selector: # 选择器,通过它指定该控制器管理哪些pod 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
创建 deployment
创建 pc-deployment.yaml,内容如下:
apiVersion: apps/v1 kind: Deployment # 类型为 deployment metadata: name: pc-deployment # deployment 的名称 namespace: zouzou spec: replicas: 3 # 副本数为 3 selector: # 选择器,和 template 的对应 matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.14
创建 pod
# 创建 deployment,--record=true 表示将命令记录到版本里面 [root@dce-10-6-215-215 tmp]# kubectl create -f pc-deployment.yaml --record=true deployment.apps/pc-deployment created # 查看 deployment,deploy 是 deployment 的简写 # UP-TO-DATE:最新版本的 pod 的数量 # AVAILABLE:当前可用的 pod 的数量,pc-deployment 就是 yaml 里写的 name [root@dce-10-6-215-215 tmp]# kubectl get deploy pc-deployment -n zouzou NAME READY UP-TO-DATE AVAILABLE AGE pc-deployment 3/3 3 3 23s # 查看 rs,发现 rs 的名称是在原来的 deployment 的名字后面添加了一个 10 位数的随机串 [root@dce-10-6-215-215 tmp]# kubectl get rs -n zouzou NAME DESIRED CURRENT READY AGE nginx3-c5d7c9466 1 1 1 62m pc-deployment-5db6b86685 3 3 3 33s # 查看 pod,pod 是在 rs 的名称后面添加了 5 位随机数 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE nginx3-c5d7c9466-vnt9c 1/1 Running 0 59m pc-deployment-5db6b86685-6rhsd 1/1 Running 0 46s pc-deployment-5db6b86685-w9g25 1/1 Running 0 46s pc-deployment-5db6b86685-z2ktw 1/1 Running 0 46s
扩缩容
deployment 的扩缩容和 rs 的扩缩容一样,参考:https://www.cnblogs.com/zouzou-busy/p/16153136.html
1.使用命令的方式
# 变更副本数为 5 个,注意,扩缩的时候写的是控制器的名称,不是 pod
[root@dce-10-6-215-215 tmp]# kubectl scale deploy pc-deployment --replicas=5 -n zouzou
deployment.apps/pc-deployment scaled
# 查看 deployment
[root@dce-10-6-215-215 tmp]# kubectl get deploy pc-deployment -n zouzou
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 10m
# 查看 pod
[root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou
NAME READY STATUS RESTARTS AGE
nginx3-c5d7c9466-vnt9c 1/1 Running 0 69m
pc-deployment-5db6b86685-6rhsd 1/1 Running 0 10m
pc-deployment-5db6b86685-9sbnj 1/1 Running 0 30s
pc-deployment-5db6b86685-cc5kt 1/1 Running 0 30s
pc-deployment-5db6b86685-w9g25 1/1 Running 0 10m
pc-deployment-5db6b86685-z2ktw 1/1 Running 0 10m
2.通过编辑的方式
# 编辑 deployment 的副本数量,改为两个 [root@dce-10-6-215-215 tmp]# kubectl edit deploy pc-deployment -n zouzou deployment.apps/pc-deployment edited # 查看 pod 数量,有些 pod 正在停止 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE nginx3-c5d7c9466-vnt9c 1/1 Running 0 72m pc-deployment-5db6b86685-6rhsd 1/1 Running 0 13m pc-deployment-5db6b86685-9sbnj 0/1 Terminating 0 3m38s pc-deployment-5db6b86685-cc5kt 1/1 Running 0 3m38s pc-deployment-5db6b86685-w9g25 0/1 Terminating 0 13m pc-deployment-5db6b86685-z2ktw 0/1 Terminating 0 13m # 查看 pod,只有两个在运行了 [root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou NAME READY STATUS RESTARTS AGE nginx3-c5d7c9466-vnt9c 1/1 Running 0 72m pc-deployment-5db6b86685-6rhsd 1/1 Running 0 14m pc-deployment-5db6b86685-cc5kt 1/1 Running 0 3m46s
3.通过修改 yaml 文件的方式,在 apply 一下,不做演示
镜像升级
升级: 假设从版本为1.14 升级到 1.15 ,这就叫应用的升级【升级可以保证服务不中断】
deployment 支持两种更新策略,重建更新和滚动更新,可以通过 strategy 指定策略类型,支持两个属性
strategy: # 指定新的 pod 替换旧的 pod 的策略,支持两个属性 type: # 指定策略类型,支持两种策略 Recreate: # 重建更新,在创建出新的 pod 之前会先杀掉所有已经存在的 pod RollingUpdate: # 滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的 pod rollingUpdate: # 用来指定在升级过程中不可用 pod 的最大数量,默认为 25% maxSurge: # 用来指定在升级过程中可以超过期望的 pod 的最大数量,默认为 25%
重建更新
编辑 pc-deployment.yaml,在 spec 节点下添加更新策略
apiVersion: apps/v1 kind: Deployment # 类型为 deployment metadata: name: pc-deployment # deployment 的名称 namespace: zouzou spec: strategy: # 更新策略 type: Recreate # 重建更新 replicas: 3 # 副本数为 3 selector: # 选择器,和 template 的对应 matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.14
在 apply 一下
kubectl apply -f pc-deployment.yaml
修改镜像,将镜像从 1.14 改为 1.15
kubectl set image deployment pc-deployment nginx=nginx:1.15 -n zouzou
为了观察方便,我们可以在开一个窗口,使用 -w 参数动态监听
从下面的结果可以看出,一下子三个 pod 都停止了,然后重新创建了三个 pod,在运行
[root@dce-10-6-215-215 ~]# kubectl get pods -n zouzou -w NAME READY STATUS RESTARTS AGE nginx3-c5d7c9466-vnt9c 1/1 Running 0 96m pc-deployment-5db6b86685-6rhsd 1/1 Running 0 37m pc-deployment-5db6b86685-cc5kt 1/1 Running 0 27m pc-deployment-5db6b86685-cw5l6 1/1 Running 0 2m1s pc-deployment-5db6b86685-cw5l6 1/1 Terminating 0 2m57s pc-deployment-5db6b86685-cc5kt 1/1 Terminating 0 27m pc-deployment-5db6b86685-6rhsd 1/1 Terminating 0 38m pc-deployment-5db6b86685-cw5l6 0/1 Terminating 0 3m pc-deployment-5db6b86685-cc5kt 0/1 Terminating 0 28m pc-deployment-5db6b86685-6rhsd 0/1 Terminating 0 38m pc-deployment-5db6b86685-cw5l6 0/1 Terminating 0 3m1s pc-deployment-5db6b86685-cw5l6 0/1 Terminating 0 3m1s pc-deployment-5db6b86685-6rhsd 0/1 Terminating 0 38m pc-deployment-5db6b86685-6rhsd 0/1 Terminating 0 38m pc-deployment-5db6b86685-cc5kt 0/1 Terminating 0 28m pc-deployment-5db6b86685-cc5kt 0/1 Terminating 0 28m pc-deployment-78d879f8b6-2d5fx 0/1 Pending 0 0s pc-deployment-78d879f8b6-2d5fx 0/1 Pending 0 0s pc-deployment-78d879f8b6-ntvb9 0/1 Pending 0 0s pc-deployment-78d879f8b6-qpscz 0/1 Pending 0 0s pc-deployment-78d879f8b6-ntvb9 0/1 Pending 0 0s pc-deployment-78d879f8b6-qpscz 0/1 Pending 0 0s pc-deployment-78d879f8b6-ntvb9 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-2d5fx 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-qpscz 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-2d5fx 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-qpscz 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-ntvb9 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-2d5fx 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-qpscz 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-ntvb9 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-ntvb9 1/1 Running 0 5s pc-deployment-78d879f8b6-2d5fx 1/1 Running 0 5s pc-deployment-78d879f8b6-qpscz 1/1 Running 0 5s
滚动更新
编辑 pc-deployment.yaml,修改更新策略,改为滚动更新
apiVersion: apps/v1 kind: Deployment # 类型为 deployment metadata: name: pc-deployment # deployment 的名称 namespace: zouzou spec: strategy: # 更新策略 type: RollingUpdate # 滚动更新策略 rollingUpdate: maxSurge: 25% maxUnavailable: 25% replicas: 3 # 副本数为 3 selector: # 选择器,和 template 的对应 matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.14
在 apply 一下,这时候的镜像还是 1.14
kubectl apply -f pc-deployment.yaml
修改镜像,将镜像从 1.14 改为 1.15
kubectl set image deployment pc-deployment nginx=nginx:1.15 -n zouzou
为了观察方便,我们可以在开一个窗口,使用 -w 参数动态监听
从下面的结果可以看出,先创建一个容器,创建成功了在停止一个容器,依次更新
在我们执行完命令后,能看到升级的过程
- 首先是开始的 nginx 1.14 版本的 Pod 在运行,然后 1.15 版本的在创建
- 然后在 1.15 版本创建完成后,就会暂停1.14版本
- 最后把 1.14 版本的 Pod 移除,完成我们的升级
我们在下载 1.15版本,容器就处于 ContainerCreating 状态,然后下载完成后,就用 1.15 版本去替换 1.14 版本了,这么做的好处就是:升级可以保证服务不中断
[root@dce-10-6-215-215 ~]# kubectl get pods -n zouzou -w NAME READY STATUS RESTARTS AGE nginx3-c5d7c9466-vnt9c 1/1 Running 0 106m pc-deployment-5db6b86685-fjz46 1/1 Running 0 2m39s pc-deployment-5db6b86685-hdmvd 1/1 Running 0 2m34s pc-deployment-5db6b86685-j7v8f 1/1 Running 0 2m44s pc-deployment-78d879f8b6-crn8s 0/1 Pending 0 0s pc-deployment-78d879f8b6-crn8s 0/1 Pending 0 0s pc-deployment-78d879f8b6-crn8s 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-crn8s 0/1 ContainerCreating 0 2s pc-deployment-78d879f8b6-crn8s 0/1 ContainerCreating 0 2s pc-deployment-78d879f8b6-crn8s 1/1 Running 0 4s pc-deployment-5db6b86685-hdmvd 1/1 Terminating 0 2m48s pc-deployment-78d879f8b6-r8wbx 0/1 Pending 0 0s pc-deployment-78d879f8b6-r8wbx 0/1 Pending 0 0s pc-deployment-78d879f8b6-r8wbx 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-r8wbx 0/1 ContainerCreating 0 3s pc-deployment-5db6b86685-hdmvd 0/1 Terminating 0 2m51s pc-deployment-78d879f8b6-r8wbx 0/1 ContainerCreating 0 3s pc-deployment-78d879f8b6-r8wbx 1/1 Running 0 5s pc-deployment-5db6b86685-fjz46 1/1 Terminating 0 2m58s pc-deployment-78d879f8b6-djg6c 0/1 Pending 0 0s pc-deployment-78d879f8b6-djg6c 0/1 Pending 0 0s pc-deployment-78d879f8b6-djg6c 0/1 ContainerCreating 0 0s pc-deployment-78d879f8b6-djg6c 0/1 ContainerCreating 0 3s pc-deployment-5db6b86685-fjz46 0/1 Terminating 0 3m1s pc-deployment-78d879f8b6-djg6c 0/1 ContainerCreating 0 3s pc-deployment-5db6b86685-fjz46 0/1 Terminating 0 3m2s pc-deployment-5db6b86685-fjz46 0/1 Terminating 0 3m2s pc-deployment-78d879f8b6-djg6c 1/1 Running 0 5s pc-deployment-5db6b86685-j7v8f 1/1 Terminating 0 3m8s pc-deployment-5db6b86685-hdmvd 0/1 Terminating 0 2m59s pc-deployment-5db6b86685-hdmvd 0/1 Terminating 0 2m59s pc-deployment-5db6b86685-j7v8f 0/1 Terminating 0 3m11s pc-deployment-5db6b86685-j7v8f 0/1 Terminating 0 3m12s pc-deployment-5db6b86685-j7v8f 0/1 Terminating 0 3m12s
滚动更新的过程如下图所示:
查看 RS 的变化
查看 RS 。发现原来的 RS 依旧存在,只是 pod 的数量变为了 0,而后又新产生了一个 RS,pod 的数量为 3 ,为什么会这样呢?想一下,当我们升级了版本之后,如果这个版本有 bug 怎么办?是不是要马上回滚到上一个版本,这就是 deployment 的高明之处,不会删除之前的 RS
# 查看 rs,发现原来的 rs 依旧存在,只是 pod 数量变为了 0,而后又新产生了一个 rs,pod数量为 3 # 其实这就是 deployment 能够进行版本回退的奥妙所在,后面会详细解释 [root@dce-10-6-215-215 ~]# kubectl get rs -n zouzou NAME DESIRED CURRENT READY AGE nginx3-c5d7c9466 1 1 1 111m pc-deployment-5db6b86685 0 0 0 49m pc-deployment-78d879f8b6 3 3 3 11m
查看更新状态
可以通过下面的命令查看更新的状态
# pc-deployment 是 deployment 的名称 kubectl rollout status deployment pc-deployment -n zouzou