在现代DevOps实践中,应用的零停机部署(Zero-Downtime Deployment)是衡量部署流程成熟度的关键指标。Kubernetes(K8s)的Deployment资源提供了强大的内置机制,用于管理应用的滚动更新(Rolling Update)和版本回滚(Rollback)。
本文将聚焦如何利用Kubernetes的这一特性,实现在不中断用户服务的前提下进行版本升级,并在出现问题时快速回退到上一个稳定版本。
1. 准备工作:初始部署(V1版本)
首先,我们创建一个基础的Deployment,运行Nginx应用,并指定其副本策略为滚动更新。默认情况下,K8s Deployment使用的就是滚动更新策略。
我们将应用命名为my-web-app,并使用Nginx的1.20版本作为V1。
# deployment-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
# 允许最多比预期多创建一个Pod
maxSurge: 1
# 允许最多一个Pod不可用
maxUnavailable: 1
template:
metadata:
labels:
app: web
version: v1
spec:
containers:
- name: nginx-container
image: nginx:1.20 # V1 版本
ports:
- containerPort: 80
执行部署:
kubectl apply -f deployment-v1.yaml
kubectl get deployments my-web-app
此时,我们的应用已经稳定运行在V1版本。
2. 执行滚动更新(V2版本)
假设我们现在需要将Nginx升级到1.25版本(即V2版本)。我们只需要修改YAML文件中的image标签,并重新应用配置。
# deployment-v2.yaml (仅修改 image)
# ... snip ...
containers:
- name: nginx-container
image: nginx:1.25 # V2 版本
ports:
# ... snip ...
执行更新:
kubectl apply -f deployment-v2.yaml
Kubernetes会自动触发滚动更新流程。根据我们在strategy中设置的参数(maxSurge: 1和maxUnavailable: 1),K8s会采取以下步骤确保服务不中断:
- 创建一个V2版本的新Pod。
- 一旦新的V2 Pod处于Running且Ready状态,它会停止并终止一个V1版本的旧Pod。
- 重复此过程,直到所有3个Pod都更新为V2版本。
监控更新状态:
要查看部署过程,可以使用kubectl rollout status:
kubectl rollout status deployment/my-web-app
# 输出示例:waiting for rollout to finish: 2 of 3 updated replicas are available...
# deployment "my-web-app" successfully rolled out
3. 查看部署历史
每次成功的kubectl apply都会在Deployment中创建一个新的修订版(Revision),以便进行历史追踪和回滚。
kubectl rollout history deployment/my-web-app
输出可能如下:
REVISION CHANGE-CAUSE
1 <none>
2 <none> # 对应 V2 版本的更新
4. 版本回滚实战
假设在部署V2版本后,我们发现应用出现了严重的内存泄漏,必须立即回滚到稳定的V1版本。
回滚是Kubernetes的Deployment最强大的功能之一。我们不需要手动修改YAML文件或重新部署V1,只需要使用kubectl rollout undo命令。
回滚到上一个版本 (默认操作):
kubectl rollout undo deployment/my-web-app
回滚到指定的历史版本:
如果我们想跳过上一个版本(Revision 2),直接回滚到Revision 1:
# 假设 V1 版本对应 Revision 1
kubectl rollout undo deployment/my-web-app --to-revision=1
执行回滚后,K8s会立即开始一个反向的滚动更新:它会用Revision 1的配置替换所有正在运行的Revision 2的Pod,且这个过程同样是零停机的。
回滚后的验证:
kubectl get pods
# 确认所有Pod已经回到 nginx:1.20 的配置
kubectl rollout status deployment/my-web-app
总结
Kubernetes的Deployment资源通过内置的RollingUpdate策略和强大的kubectl rollout命令集,完美解决了应用部署中的两大核心问题:零停机更新和快速版本回滚。掌握这些命令是任何现代化运维或开发团队的必备技能,它保证了应用的高可用性和部署的安全性。
汤不热吧