基本
Deployment控制器用来管理无状态应用,通过Deployment控制器创建ReplicaSet,ReplicaSet控制Pod副本集。
任何时候,都不应该直接去创建ReplicaSet控制器,应始终使用Deployment控制器。
例子
API语法:https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: apps-ro-token
containers:
- name: nginx
image: nginx:v1.20.1
command:
- nginx
args:
- -g
- "daemon off;"
ports:
- containerPort: 80
spec.selector
:Deployment通过它控制Pod,与Podspec.template.metadata.labels
一致。
metadata
: 这里会定义name,labels,namespace,annotations。
⚠️Deployment的spec.selector
选择的标签应该是全局唯一,这样可以避免多个Deployment出现冲突出现不可预知的问题。
ℹ️ 其中 annotations (注解)很特殊,k8s通过注解中的key
来确认要关联的额外服务信息。
例如在阿里云的k8s服务中,你可以添加镜像快照注解信息,从而让 pod 无需从镜像仓库下载启动,而是直接通过快照加速启动。
更新
👙Deployment的每次更新都会创建一个新的ReplicaSet对象。Deployment通过保留新旧的ReplicaSet,来实现回滚功能。
Deployment的默认策略大致如下
更新规则:
- 先扩展一部分新版本
- 删除一部分老版本
- 重复上述行为,直至所有老版本被替换
回滚规则:
- 回滚到任何一个之前的版本
Deployment只会针对
spec.template
更新Pod
初始版本
创建一个nginx的deployment
kubectl apply -f nginx-deployment-1.14.2.yaml
===
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
minReadySeconds: 3
revisionHistoryLimit: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 30%
maxSurge: 30%
template:
metadata:
labels:
app: nginx
version: v1.14.2
annotations:
kubernetes.io/change-cause: "version: v1.14.2"
spec:
containers:
- name: nginx
image: nginx:1.14.2
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo This is v1.14.2 > /usr/share/nginx/html/index.html"]
command:
- nginx
args:
- -g
- "daemon off;"
ports:
- containerPort: 80
spec.template.metadata.annotations.kubernetes.io/change-cause 通过注解添加变更说明
更新策略
deployment 的 .spec 中可以添加一些策略.
spec:
replicas: 3
minReadySeconds: 3 # pod 就绪时间,在此时间之前,deployment 认为 pod 还没有准备好. 默认0
revisionHistoryLimit: 10 # 最大版本保留次数. 默认10
strategy:
type: RollingUpdate # 定义变更策略. 除了 RollingUpdate,还可以是Recreate.Recreate指的是先删除所有pod,再创建.
rollingUpdate:
maxUnavailable: 30% # 变更期间,不可用的副本数。可以是具体数字
maxSurge: 30% # 变更期间,可以超出replicas定义的副本数。可以是具体数字
maxUnavailable 和 maxSurge 设置相等即可. 即开多少个新的同时,就关多少个老的
通过命令添加/删除变更说明
- 添加
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="first"
- 删除(命令最后一个减号)
kubectl annotate deployment/nginx-deployment <注解key>-
- 执行kubectl命令的同时将命令写入
CHANGE-CAUSE
kubectl xxx --record
版本历史
➜ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 version: v1.14.2
暂停发布
此操作不会影响pod的运行,仅仅是阻断deployment实施更新。
如果更新之前就暂停,则你可以多次更新,这些更新在【恢复发布】之前不会被应用,也不会记录在【历史版本】中。
如果更新期间执行暂停,则更新会处于等待状态,已更新的不会回滚。
kubectl rollout pause deployment/nginx-deployment
更新版本
发布版本1.20.1
sed '[email protected]@1.20.1@g' nginx-deployment-1.14.2.yaml > nginx-deployment-1.20.1.yaml
kubectl apply -f nginx-deployment-1.20.1.yaml
恢复发布
kubectl rollout resume deployment/nginx-deployment
启用恢复后,则暂停期间启用的所有更新将开始发挥作用,并且只会将更新的最终版本写入【历史版本】
➜ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 version: v1.14.2
2 version: v1.20.1
更新过程和结果查看,可运行:
kubectl rollout status deployment/nginx-deployment
更深层的rs状态查看,可运行:
kubectl get rs -l app=nginx -l version=v1.20.1
kubectl get pod -l app=nginx -l version=v1.20.1
-l 是调用标签过滤
你可以通过追加版本号来看具体的版本内容
kubectl rollout history deployment/nginx-deployment --revision=<num>
回滚版本
我们选择将nginx版本回滚到第一个版本。被回滚的版本会从版本库里移动到最新位置。
kubectl rollout undo deployment/nginx-deployment --to-revision=1
➜ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 version: v1.20.1
3 version: v1.14.2
如果不指定版本,则回滚到上一个版本。
小结
kubectl rollout history deployment/<> # 查看对象历史
kubectl rollout undo deployment/<> --to-revision=<> # 对象版本回退
kubectl rollout status deployment/<># 展示执行状态
kubectl rollout pause deployment/<> # 暂停此次版本操作行为
kubectl rollout resume deployment/<> # 恢复此次版本操作行为
kubectl set image # 修改镜像配置
kubectl annotate # 添加一个注释
更新过程:
- 创建新的replicaset
- 将新的replicaset扩展
- 将旧的replicaset缩容
- 新的replicaset对应的pod已就绪或可用
另外,可以通过判断kubectl rollout status deployment/<>
命令执行结果,$? 状态为 0,则说明 deployment 处于 complete。
金丝雀发布
金丝雀发布的逻辑:
- 开新Pod,不关老Pod,即确保可用的Pod数不低于预期数。
- 待新 Pod 创建后,立即暂停发布。
- 新 Pod Ready 后,部分流量经过新 Pod。
- 若新 Pod 通过验证,则恢复发布。
- 若新 Pod 没有通过验证,则恢复发布并立即执行回滚操作。
操作步骤:
- 调整新版本Deployment更新策略
-
minReadySeconds
设置为3,添加执行【暂停发布命令】的缓冲时间,避免新Pod被Deployment认为可用的同时删除旧Pod。 -
maxUnavailable
设置为0,避免更新中,可用Pod低于预期值。 -
maxSurge
的值就是验证新版本的Pod(”金丝雀“)数量。
- 启动更新,并立即暂停发布
kubectl apply -f new-nginx-deployment.yaml && kubectl rollout pause deployment/nginx-deployment
- 若新 Pod 没有通过验证,则恢复发布并立即回滚上一个版本。
kubectl rollout resume deployment/nginx-deployment && kubectl rollout undo deployment/nginx-deployment
这个过程不会重建老版本Pod,只会通过新版本rs删除新版本Pod
- 若新 Pod 通过验证,则恢复发布
kubectl rollout resume deployment/nginx-deployment
整个更新过程,若顺利,效果如下所示:
注意点
- deployment只会保留不一致的历史版本。即,假设按照默认参数,deployment会保留10个历史版本,则如果你第三次的配置清单和第一次一致,则第一次的就会被删除,此时,只会有2和3版本。