Deployment 表示用户对 K8S 集群的一次更新操作。Deployment 是一个比 RS( Replica Set, RS) 应用模型更广的 API 对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减少到 0 的复合操作。
这样一个复合操作用一个 RS 是不好描述的,所以用一个更通用的 Deployment 来描述。以 K8S 的发展方向,未来对所有长期伺服型的业务的管理,都会通过 Deployment来管理。
Deployment主要功能有下面几个:
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
创建 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 参数动态监听
从下面的结果可以看出,先创建一个容器,创建成功了在停止一个容器,依次更新
在我们执行完命令后,能看到升级的过程
我们在下载 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 依旧存在,只是 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