某些情况下,您可能想要回滚(rollback)Deployment,例如:Deployment 不稳定(可能是不断地崩溃)。默认情况下,kubernetes 将保存 Deployment 的所有更新(rollout)历史。您可以设定 revision history limit 来确定保存的历史版本数量。

TIP 当且仅当 Deployment 的 .spec.template 字段被修改时(例如,您修改了容器的镜像),kubernetes 将为其创建一个 Deployment revision(版本)。Deployment 的其他更新(例如:修改 .spec.replicas 字段)将不会创建新的 Deployment reviesion(版本)。

本文提供了两种途径对 Deployment 执行回滚操作:

  • 使用 kubectl 回滚 Deployment
  • 使用 Kuboard 回滚 Deployment

使用kubectl回滚Deployment

模拟更新错误

  • 假设您在更新 Deployment 的时候,犯了一个拼写错误,将 nginx:1.9.1 写成了 nginx:1.91 ```bash kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 —record=true
  1. <br /> 输出结果如下所示:
  2. ```bash
  3. deployment.apps/nginx-deployment image updated
  • 该更新将卡住,您可以执行命令 kubectl rollout status deployment.v1.apps/nginx-deployment 检查其状态,输出结果如下所示: ```bash Waiting for rollout to finish: 1 out of 3 new replicas have been updated…
  1. - <br />
  2. - 执行命令 kubectl get rs 您将看到两个旧的 ReplicaSetnginx-deployment-1564180365 and nginx-deployment-2035384211)和一个新的 ReplicaSet (nginx-deployment-3066724191) 。如下所示:
  3. ```bash
  4. NAME DESIRED CURRENT READY AGE
  5. nginx-deployment-1564180365 3 3 3 25s
  6. nginx-deployment-2035384211 0 0 0 36s
  7. nginx-deployment-3066724191 1 1 0 6s

  • 执行命令 kubectl get pods,您将看到 1 个由新 ReplicaSet 创建的 Pod 卡在抓取 image 的死循环里: ```bash NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-70iae 1/1 Running 0 25s nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s nginx-deployment-1564180365-hysrc 1/1 Running 0 25s nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
  1. > <br />**TIP**Deployment Controller 将自动停止有问题的更新(rollout),不会继续 scale up 新的 ReplicaSetmaxUnavailable 参数指定了最多会有几个 Pod 副本卡住,该参数的默认值是 25%。
  2. - 执行命令 kubectl describe deployment 查看 Deployment 的详情,输出结果如下所示:
  3. ```bash
  4. Name: nginx-deployment
  5. Namespace: default
  6. CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
  7. Labels: app=nginx
  8. Selector: app=nginx
  9. Replicas: 3 desired | 1 updated | 4 total | 3 available | 1 unavailable
  10. StrategyType: RollingUpdate
  11. MinReadySeconds: 0
  12. RollingUpdateStrategy: 25% max unavailable, 25% max surge
  13. Pod Template:
  14. Labels: app=nginx
  15. Containers:
  16. nginx:
  17. Image: nginx:1.91
  18. Port: 80/TCP
  19. Host Port: 0/TCP
  20. Environment: <none>
  21. Mounts: <none>
  22. Volumes: <none>
  23. Conditions:
  24. Type Status Reason
  25. ---- ------ ------
  26. Available True MinimumReplicasAvailable
  27. Progressing True ReplicaSetUpdated
  28. OldReplicaSets: nginx-deployment-1564180365 (3/3 replicas created)
  29. NewReplicaSet: nginx-deployment-3066724191 (1/1 replicas created)
  30. Events:
  31. FirstSeen LastSeen Count From SubobjectPath Type Reason Message
  32. --------- -------- ----- ---- ------------- -------- ------ -------
  33. 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
  34. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
  35. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
  36. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
  37. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 1
  38. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
  39. 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
  40. 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1


为了修复这个问题,您需要将其回滚到之前的一个稳定版本。

检查 Deployment 的更新历史

  1. 执行命令 kubectl rollout history deployment.v1.apps/nginx-deployment 检查 Deployment 的历史版本,输出结果如下所示: ```bash deployments “nginx-deployment” REVISION CHANGE-CAUSE 1 kubectl apply —filename=https://k8s.io/examples/controllers/nginx-deployment.yaml —record=true 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 —record=true 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 —record=true
  1. <br />**CHANGE-CAUSE** 是该 revision(版本)创建时从 Deployment 的 annotation kubernetes.io/change-cause 拷贝而来。
  2. 您可以通过如下方式制定 **CHANGE-CAUSE** 信息:
  3. - 为 Deployment 增加注解,kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"
  4. - 执行 kubectl apply 命令时,增加 --record 选项
  5. - 手动编辑 Deployment 的 .metadata.annotation 信息
  6. 2. 执行命令 kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2,查看 revision(版本)的详细信息,输出结果如下所示:
  7. ```yaml
  8. deployments "nginx-deployment" revision 2
  9. Labels: app=nginx
  10. pod-template-hash=1159050644
  11. Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
  12. Containers:
  13. nginx:
  14. Image: nginx:1.9.1
  15. Port: 80/TCP
  16. QoS Tier:
  17. cpu: BestEffort
  18. memory: BestEffort
  19. Environment Variables: <none>
  20. No volumes.

回滚到前一个 revision(版本)

下面的步骤可将 Deployment 从当前版本回滚到前一个版本(version 2)

  1. 执行命令 kubectl rollout undo deployment.v1.apps/nginx-deployment 将当前版本回滚到前一个版本,输出结果如下所示: ```bash deployment.apps/nginx-deployment
  1. <br /> 或者,您也可以使用 --to-revision 选项回滚到前面的某一个指定版本,执行如下命令:
  2. ```bash
  3. kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2


输出结果如下:

  1. deployment.apps/nginx-deployment


更详细的信息,请参考 kubectl rollout(opens new window)此时,Deployment 已经被回滚到前一个稳定版本。您可以看到 Deployment Controller 为该 Deployment 产生了 DeploymentRollback event。

  1. 执行命令 kubectl get deployment nginx-deployment,检查该回滚是否成功,Deployment 是否按预期的运行,输出结果如下: ```bash NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 30m
  1. 3. 执行命令 kubectl describe deployment nginx-deployment 查看 Deployment 的详情,输出结果如下:
  2. ```bash
  3. Name: nginx-deployment
  4. Namespace: default
  5. CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500
  6. Labels: app=nginx
  7. Annotations: deployment.kubernetes.io/revision=4
  8. kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
  9. Selector: app=nginx
  10. Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
  11. StrategyType: RollingUpdate
  12. MinReadySeconds: 0
  13. RollingUpdateStrategy: 25% max unavailable, 25% max surge
  14. Pod Template:
  15. Labels: app=nginx
  16. Containers:
  17. nginx:
  18. Image: nginx:1.9.1
  19. Port: 80/TCP
  20. Host Port: 0/TCP
  21. Environment: <none>
  22. Mounts: <none>
  23. Volumes: <none>
  24. Conditions:
  25. Type Status Reason
  26. ---- ------ ------
  27. Available True MinimumReplicasAvailable
  28. Progressing True NewReplicaSetAvailable
  29. OldReplicaSets: <none>
  30. NewReplicaSet: nginx-deployment-c4747d96c (3/3 replicas created)
  31. Events:
  32. Type Reason Age From Message
  33. ---- ------ ---- ---- -------
  34. Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set nginx-deployment-75675f5897 to 3
  35. Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 1
  36. Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 2
  37. Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 2
  38. Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 1
  39. Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 3
  40. Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 0
  41. Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-595696685f to 1
  42. Normal DeploymentRollback 15s deployment-controller Rolled back deployment "nginx-deployment" to revision 2
  43. Normal ScalingReplicaSet 15s deployment-controller Scaled down replica set nginx-deployment-595696685f to 0

使用Kuboard回滚Deployment

模拟更新错误

  • 假设您更新 Deployment 的时候,犯了一个拼写错误,将 1.9.1 写成了 1.91,如下图所示:image.png
  • 该更新将卡住,新的副本集中的 Pod 将因为抓取不到镜像而不能启动,并陷入不断抓取镜像的死循环当中,如下图所示:image.png

    检查 Deployment 的更新历史,并回滚

  • 上图中,显示了该 Deployment 有三个副本集,分别对应 Deployment 的版本 1、2、3。点击某一个副本集上的 回滚到 按钮,Kuboard 将为您对比两个版本之间的差异,如下图所示:image.png

  • 点击 确认 按钮,将回滚到选定的版本