在这个例子中,我们将把我们的应用程序部署到Kubernetes,并在最近的部署出现问题时回滚到任何特定的版本。
**重要提示:**当回滚到一个特定的版本时,docker镜像会被拉出,所以要确保每个镜像都有一个独特的标签,并在deployment.yaml ,以便每次部署都能引用。每次你部署一个代码,它的图像标签应该是一个新的。如果你使用latest ,你也将不得不先手动恢复代码,推送图像,这不是一个好的做法,也违背了回滚的目的。简而言之,给docker镜像打上唯一的标签(例如:git hash ),推送它并在deployment.yaml 文件中使用相同的标签。
修订历史的限制
一个部署的修订历史存储在其ReplicaSets中。
可选的.spec.revisionHistoryLimit 键控制应保留多少 ReplicaSets 以便回滚。保留的 ReplicaSets 越多,etcd 中消耗的资源就越多,所以不要把数字定得太高。默认情况下,10个旧的ReplicaSets将被保留。
例子
我们把revisionHistoryLimit ,所以我们永远不会有超过5次的修订。让我们看看我们目前在集群中的情况:
$ kubectl get deployments,replicasets,pods
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/address-finder-deployment 1/1 1 1 9m20s
NAME DESIRED CURRENT READY AGE
replicaset.apps/address-finder-deployment-68dd5b79b8 0 0 0 9m
replicaset.apps/address-finder-deployment-56847c949b 0 0 0 3m
replicaset.apps/address-finder-deployment-7f9fdc5f48 1 1 1 17s
NAME READY STATUS RESTARTS AGE
pod/address-finder-deployment-7f9fdc5f48-wr94x 2/2 Running 0 17s
如你所见,我们有3个ReplicaSets。鉴于部署/发布的修订是由ReplicaSets控制的,我们也应该有3个修订历史。让我们检查一下:
$ kubectl rollout history deployment address-finder-deployment
REVISION CHANGE-CAUSE
1
2
3
我们的Pod是一个Web服务器,所以它会打印一个假的字符串,如v1、v2、v3等等。目前它打印的是v3,但我们想回到v2的信息。你可以认为这个修订属于最新的ReplicaSet,也就是3,因为它是底部最新的一个。但是,情况并不总是这样,所以我们先确认一下:
$ kubectl describe replicaset address-finder-deployment-7f9fdc5f48 | grep revision
deployment.kubernetes.io/revision: 3
现在我们确定了我们所处的版本。让我们回到以前的版本,也就是2:
$ kubectl rollout undo deployment address-finder-deployment --to-revision=2
deployment.apps/address-finder-deployment rolled back
让我们再看看我们目前在集群中的情况:
$ kubectl get deployments,replicasets,pods
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/address-finder-deployment 1/1 1 1 22m
NAME DESIRED CURRENT READY AGE
replicaset.apps/address-finder-deployment-68dd5b79b8 0 0 0 22m
replicaset.apps/address-finder-deployment-56847c949b 1 1 1 15m
replicaset.apps/address-finder-deployment-7f9fdc5f48 0 0 0 13m
NAME READY STATUS RESTARTS AGE
pod/address-finder-deployment-56847c949b-vr99p 2/2 Running 0 14s
正如你所看到的,当前的ReplicaSet已经改变,Pod已经重新启动。让我们也来看看修订历史是什么样子的:
$ kubectl rollout history deployment address-finder-deployment
REVISION CHANGE-CAUSE
1
3
4
修订版2现在被提升为4,应该是活动的。让我们确认一下当前的ReplicaSet:
$ kubectl describe replicaset address-finder-deployment-56847c949b | grep revision
deployment.kubernetes.io/revision: 4
deployment.kubernetes.io/revision-history: 2
这就是了,它告诉我们当前的版本是什么以及它的回滚历史。我们的web服务器现在应该打印v2信息,而不是v3。
命令
// Run/restart rollout/deployment
$ kubectl rollout restart deployment address-finder-deployment
// List rollout/deployment history/revisions
$ kubectl rollout history deployment address-finder-deployment
// Rollback to revision
$ kubectl rollout undo deployment address-finder-deployment --to-revision={revision-no}