Kubernetes 原生滚动更新(Rolling Update)完整实践指南

一句话承诺:30 分钟掌握零停机更新,让你的服务升级像呼吸一样自然

👉 关联文章|Containerd 从入门到精通:一篇吃透安装、镜像、排障全流程(涵盖 Containerd的基础使用和镜像加速配置及注意事项)

1 问题背景

在 Kubernetes 集群中,传统的应用更新方式往往需要停止服务,导致用户体验中断。滚动更新(Rolling Update)通过逐步替换旧版本 Pod,实现了真正的零停机升级。本指南将带你从理论到实践,掌握这一核心技能。

根据 Kubernetes 官方文档,滚动更新是 Deployment 控制器的默认更新策略,它通过 maxSurgemaxUnavailable 两个核心参数精确控制更新节奏,确保服务始终可用。1

2 方案总览

创建新 Pod 就绪检查 是 否 继续 完成 旧版本 Pod 新版本 Pod 新 Pod 健康? 替换旧 Pod 回滚/重试 下一个 Pod 更新完成

3 逐步拆解

3.1 环境准备与验证

在开始之前,确保你的 Kubernetes 环境满足以下要求:

bash 复制代码
# 验证集群状态 - 所有节点应显示 Ready
kubectl get nodes -o wide

预期输出:

复制代码
NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
master   Ready    control-plane   60m   v1.28.2   192.168.209.100   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.33
node1    Ready    <none>          59m   v1.28.2   192.168.209.101   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.33
node2    Ready    <none>          59m   v1.28.2   192.168.209.102   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.33


背景补充(点击展开)

环境要求详解
  1. Kubernetes 集群版本:建议使用 v1.20+ 版本,确保滚动更新功能完整
  2. kubectl 工具 :需要与集群版本匹配,可通过 kubectl version --client 验证
  3. 网络连通性:确保能够访问 Docker Hub 或你的私有镜像仓库
  4. 权限配置:需要具备创建和管理 Deployment 的权限
单节点环境方案

如果没有多节点集群,可以使用以下方案:

  • Minikube:本地单节点 Kubernetes 环境
  • Kind:基于 Docker 的 Kubernetes 环境
  • k3s:轻量级 Kubernetes 发行版

3.2 创建基础 Deployment

使用以下命令创建包含 3 个副本的 Nginx Deployment:

bash 复制代码
# 创建名为 nginx-deploy 的 Deployment,副本数 3,镜像用 nginx:1.19
kubectl create deployment nginx-deploy --image=nginx:1.19 --replicas=3

# 验证创建结果
kubectl get deployment nginx-deploy -o wide

创建过程遵循以下 ASCII 流程:

复制代码
[用户输入] →{集群验证}→|通过→[创建 Deployment]→[生成 ReplicaSet]→[启动 Pod]
|不通过
↓
[返回错误信息]

3.3 配置滚动更新策略

Kubernetes 默认的滚动更新策略参数:

  • maxSurge: 25% - 最多可超出期望副本数的 25%
  • maxUnavailable: 25% - 更新过程中最多 25% 的 Pod 不可用

为了演示更保守的更新策略,我们进行自定义配置:

bash 复制代码
# 设置保守的滚动更新策略
kubectl patch deployment nginx-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'

参数说明:

  • maxSurge: 1 - 更新时最多额外启动 1 个新 Pod
  • maxUnavailable: 0 - 更新过程中不允许任何旧 Pod 不可用(保证 100% 可用性)

3.4 执行滚动更新

现在执行实际的版本升级,将 Nginx 从 1.19 升级到 1.21:

bash 复制代码
# 方法1:直接更新镜像(推荐)
kubectl set image deployment/nginx-deploy nginx=nginx:1.21

# 方法2:通过编辑器修改(适合复杂修改)
kubectl edit deployment nginx-deploy
# 在编辑器中找到 spec.template.spec.containers[0].image,修改为 nginx:1.21

实时监控更新过程:

bash 复制代码
# 观察 Pod 状态变化
kubectl get pods -w

典型的滚动更新过程:

  1. 新 Pod 创建(镜像 nginx:1.21)
  2. 新 Pod 通过就绪检查
  3. 旧 Pod 开始优雅终止
  4. 重复直到所有 Pod 更新完成

检查更新状态:

bash 复制代码
# 查看滚动更新状态
kubectl rollout status deployment/nginx-deploy

成功输出:deployment "nginx-deploy" successfully rolled out

3.5 验证更新结果

确认所有 Pod 都使用了新版本镜像:

bash 复制代码
# 查看每个 Pod 的镜像版本
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

预期结果:所有 Pod 都应显示 nginx:1.21

服务可用性验证:

bash 复制代码
# 端口转发到任意 Pod 进行测试
kubectl port-forward $(kubectl get pods -l app=nginx-deploy -o jsonpath='{.items[0].metadata.name}') 8080:80

访问 http://localhost:8080 应该能看到 Nginx 欢迎页面,证明服务在更新过程中没有中断。

4 完整示例

高级配置示例

以下是一个包含健康检查和资源限制的完整 Deployment 配置:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  annotations:
    kubernetes.io/change-cause: "Update to Nginx version 1.21"
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

5 常见坑

现象 原因 一行命令验证 解决方案
Pod 长时间 ContainerCreating 镜像拉取失败 kubectl describe pod <pod-name> 检查镜像名称是否正确,确认网络连通性
更新过程卡住 新 Pod 就绪失败 kubectl get pods -o wide 检查就绪探针配置,确认资源充足
回滚失败 更新历史不足 kubectl rollout history deployment/nginx-deploy 确保至少有一次成功的更新记录
服务中断 maxUnavailable 设置过大 kubectl get deployment nginx-deploy -o yaml 减小 maxUnavailable 值,确保服务可用性

6 回滚操作(安全网)

如果更新后发现问题,可以快速回滚到之前的稳定版本:

bash 复制代码
# 查看更新历史
kubectl rollout history deployment/nginx-deploy

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deploy

# 或者回滚到指定版本
kubectl rollout undo deployment/nginx-deploy --to-revision=1

回滚过程与更新过程类似,同样遵循滚动替换的原则,确保服务不中断。

7 结论与海报

核心结论

  1. 零停机更新:通过滚动更新机制,实现应用版本升级的服务连续性
  2. 灵活控制 :通过 maxSurgemaxUnavailable 参数精确控制更新节奏
  3. 安全可靠:内置回滚机制,确保更新失败时可以快速恢复
  4. 原生支持:Kubernetes 原生功能,无需额外插件或复杂配置

更新策略选择建议

场景 maxSurge maxUnavailable 特点
生产环境 1 0 最保守,100% 可用性
一般业务 25% 25% 平衡更新速度和可用性
测试环境 50% 50% 最快更新速度
镜像优化
  • 使用多阶段构建减小镜像体积
  • 选择 Alpine 等轻量级基础镜像
  • 合理利用镜像分层缓存
资源规划
  • 为更新过程预留足够的集群资源
  • 配置适当的资源请求和限制
  • 监控更新过程中的资源使用情况
网络优化
  • 使用本地镜像缓存加速拉取
  • 配置镜像仓库的并发拉取限制
  • 优化网络策略,确保 Pod 间通信正常

下一步

🎯 动手实践:现在就在你的 Kubernetes 环境中执行一次滚动更新,体验零停机升级的魅力。

💡 进阶学习:探索蓝绿部署、金丝雀发布等高级部署策略,构建更强大的持续交付流水线。

🚀 生产应用:将这些最佳实践应用到你的生产环境,让每一次发布都变得可预测、可控制、可回滚。

记住:最好的文档是实践出来的。打开终端,输入第一个命令,开始你的 Kubernetes 滚动更新之旅吧!

"自动化不是目的,而是手段。真正的价值在于:让技术为你服务,而不是你被技术奴役。"

当你把重复性的工作交给代码,你就能把时间和精力投入到更有创造性的工作中去。

现在就开始你的自动化之旅吧!每一个专家都曾经是初学者,区别在于他们开始了。

代码已经给你了,集群就在你的电脑里,剩下的,就是按下那个 Enter 键。

相关推荐
神秘人X7072 小时前
K8s Pod生命周期完全指南
容器·kubernetes
qq_343247034 小时前
docker 下搭建 nacos
运维·docker·容器
AI小小怪9 小时前
在Linux服务器上安装CVAT (Docker 28.5.1)
运维·docker·容器·数据标注·cvat
小坏讲微服务10 小时前
Docker-compose 搭建Maven私服部署
java·spring boot·后端·docker·微服务·容器·maven
!chen11 小时前
k8s-Pod中的网络通信
网络·docker·kubernetes
奥尔特星云大使13 小时前
《系统规划与管理师教程(第2版)》方法篇 第10章 云原生系统规划 知识点总结
云原生·软考·高级·系规
熙客14 小时前
Kubernetes是如何保证有状态应用数据安全和快速恢复的
mysql·云原生·容器·kubernetes
Wang's Blog15 小时前
Nestjs框架: 微服务项目工程结构优化与构建方案
微服务·云原生·架构·nestjs
似水流年 光阴已逝16 小时前
Kubernetes Pod 基本原理:全面详解
云原生·容器·kubernetes·pod