Pod 滚动升级(Deployment)
使用kubernetes 进行升级的时候并不需要停止业务,kubectl 支持滚动升级的方式,每次更新一个pod,而不是同时删除整个服务。
目前的kubernetes 版本只支持Replication Controllers的方式实现滚动升级。然而,官方推荐的方式是使用Deployments. Deployments是一个更高级别的控制器,它以声明方式自动执行应用程序的滚动更新,因此推荐使用。
这里将重点介绍使用Deployment的方式。
- 创建一个nginx应用的deployment:
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:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
可以看到,创建了3个Pod副本:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-75675f5897-jhr26 1/1 Running 0 36m
nginx-deployment-75675f5897-n77ds 1/1 Running 0 36m
nginx-deployment-75675f5897-ns6pn 1/1 Running 0 36m
更新镜像为nginx 1.10.3:
# kubectl set image deployment nginx-deployment nginx=nginx:1.10.3
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-75675f5897-n77ds 0/1 Terminating 0 47m
nginx-deployment-75d56bb955-54686 1/1 Running 0 7s
nginx-deployment-75d56bb955-5zxqz 1/1 Running 0 10s
nginx-deployment-75d56bb955-bxqd9 1/1 Running 0 8s
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-75d56bb955-54686 1/1 Running 0 2m 10.2.74.9 10.0.0.3
nginx-deployment-75d56bb955-5zxqz 1/1 Running 0 2m 10.2.74.8 10.0.0.3
nginx-deployment-75d56bb955-bxqd9 1/1 Running 0 2m 10.2.62.16 10.0.0.2
# curl --head 10.2.62.16
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Wed, 20 Jun 2018 10:52:10 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
Connection: keep-alive
ETag: "5890a6b7-264"
Accept-Ranges: bytes
我们也可以直接使用编辑配置文件的方式,直接修改nginx镜像版本为1.12.2:
# kubectl edit deployment nginx-deployment
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-7498dc98f8-756tq 1/1 Running 0 11s 10.2.62.17 10.0.0.2
nginx-deployment-7498dc98f8-g265v 1/1 Running 0 13s 10.2.74.10 10.0.0.3
nginx-deployment-7498dc98f8-hh6wv 1/1 Running 0 10s 10.2.74.11 10.0.0.3
curl --head 10.2.62.17
HTTP/1.1 200 OK
Server: nginx/1.12.2
...
在进行滚动升级的过程中,Deployment 进行初始化时,创建了一个新的ReplicaSet,新的ReplicaSet 逐渐创建新的Pod 副本,旧的ReplicaSet 逐渐销毁旧的副本,并始终保持副本数量恒定,逐步滚动替换。
可以查看ReplicaSet的状态:
# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
nginx-deployment-7498dc98f8 3 3 3 44m nginx nginx:1.12.2 app=nginx,pod-template-hash=3054875494
nginx-deployment-75675f5897 0 0 0 1h nginx nginx:1.7.9 app=nginx,pod-template-hash=3123191453
nginx-deployment-75d56bb955 0 0 0 59m nginx nginx:1.10.3 app=nginx,pod-template-hash=3181266511
查看更新的状态:
kubectl rollout status deployment/nginx-deployment
在Deployment的定义中,可以通过spec.strategy指定的Pod更新策略,支持两种策略:
- Recreate(重建):设置
spec.strategy.type=Recreate
, 表示Deployment在更新Pod的时候,会先杀掉所有正在运行的Pod,然后创建新的Pod。 - RollingUpdate(滚动更新): 设置
spec.strategy.type=RollingUpdate
,表示Deployment会以滚动更新的方式来逐个更新Pod。可以指定
RollingUpdate(滚动更新)有两个主要参数,来控制更新的Pod副本数量:
- .spec.strategy.rollingUpdate.maxUnavailable : 用于指定Deployment在更新过程中不可用状态的Pod数量上限。该maxUnavailable的数值可以是绝对值正整数,也可以是Pod期望的副本数的百分比(例如10%)。如果设置为百分比,那么系统会先以向下取整的方式计算出绝对值整数,但是当.spec.strategy.rollingUpdate.maxSurge值为0时,其值不能为0。 默认情况下为25%。
- .spec.strategy.rollingUpdate.maxSurge: 用于指定Deployment更新Pod过程中Pod总数超过Pod期望副本部分的最大值。该maxSurge的数值可以是绝对值(例如5)或Pod期望副本数的百分比(例如10%)。如果设置为百分比,那么系统会先按照向上取整的方式计算出绝对数值。如果MaxUnavailable的值为0,则这个值不能为0,默认值是25%。
需要注意更新Deployment的标签选择器(Label selector)的情况。通常不鼓励更新Deployment 的标签选择器,这样会导致Deployment选择的Pod列表发生变化,也可能与其它控制器产生的冲突。
如果要更新Deployment标签选择器,有以下注意事项:
- 添加标签选择器时,必须同步修改Deployment配置的Pod标签,为Pod添加新的标签,否则Deployment的更新会报验证错误而失败。更改标签之后,旧的rs将会依旧存在,deployment将无法管理旧的RS。直接执行
kubectl delete rs <rs-name>
即可删除。 - 更新标签选择器,即更新选择器中标签的键或值,也会产生与添加选择器标签类似的效果。
- 删除标签选择器,即从Deployment的标签选择器中删除一个或者多个标签,该Deployment的ReplicaSet 和Pod不会受到任何影响,但需要注意的是,被删除的标签仍然会存在于现有的Pod和ReplicaSet上。
Deployment的回滚
1、查看Deployment部署的历史记录:
kubectl rollout history deployment/nginx-deployment
如果查看到的结果为None,则需要在创建和更新deployment时加上 --record参数.
2、查看特定的版本信息:
# kubectl rollout history deployment/nginx-deployment --revision=3
3、撤销本次发布,回滚到上一个版本:
# kubectl rollout undo deployment/nginx-deployment
4、可以指定版本回滚:
# kubectl rollout undo deployment/nginx-deployment --to-revision=2
5、查看回滚状态:
# kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
暂停和恢复Deployment的部署操作
对于一次复杂的Deplyment配置修改,为了避免频繁触发Deployment的更新操作,可以先暂停Deployment的更新操作,然后进行配置修改,等所有的修改完成后,再恢复Deployment,一次性触发完整的更新操作。这样就可以避免不必要的Deployment的更新操作。
1、 暂停Deployment的操作
# kubectl rollout pause deployment/nginx-deployment
2、修改deployment的镜像信息:
# kubectl set image deploy/nginx-deployment nginx=nginx:1.12.2
# 查看更新记录,没有变化
# kubectl rollout history deploy/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 <none>
4 <none>
5 <none>
3、再次更新容器资源限制:
# kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
4、恢复Deployment的部署操作
kubectl rollout resume deploy/nginx-deployment
5、历史记录以及更新:
# kubectl rollout history deploy/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 <none>
4 <none>
5 <none>
6 <none>
k8s还提供了针对RC进行滚动升级的方式,使用 kubectl rolling-update 命令来执行。由于RC升级过程无法查看记录,无法进行版本数量的精细化控制,将逐渐被RS取代,所以建议优先使用Deployment的方式完成Pod的部署升级,这里不做讨论。
其他对象的更新策略
DaemonSet的更新策略
- OnDelete:这是用于向后兼容的默认更新策略。 使用OnDelete更新策略,在更新DaemonSet模板之后,只有在手动删除旧的DaemonSet窗格时才会创建新的DaemonSet Pod。 这与Kubernetes版本1.5或更早版本中的DaemonSet是一致的。
- RollingUpdate:通过RollingUpdate更新策略,在更新DaemonSet模板后,旧的DaemonSet窗格将被终止,并且将以受控的方式自动创建新的DaemonSet。不过不支持DaemonSet的更新历史记录,并且回滚并不能如Deployment直接通过kubectl rollback 命令来实现。
转载于:https://blog.51cto.com/tryingstuff/2131407