怎样用工具滚动更新?

联启 电脑工具 16

《运维必备:零停机实现服务滚动更新的五种工具与实战指南》

目录导读

  1. 为什么需要滚动更新?
  2. Kubernetes原生Deployments滚动更新
  3. Docker Swarm服务滚动升级
  4. Ansible结合负载均衡的零停机更新
  5. Nomad的任务组滚动策略
  6. 自定义脚本+反向代理(Nginx/HAProxy)
  7. 常见问题QA

为什么需要滚动更新?

:滚动更新与传统“全部停止再启动”相比,优势在哪?
:滚动更新能逐个替换服务实例,使应用在更新期间始终对外可用,避免停机导致的业务中断、用户流失和收入损失,根据Google SRE报告,采用滚动更新的系统可用性可达99.99%以上。

怎样用工具滚动更新?-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

关键实现原理:保持最小健康实例数(如 maxSurgemaxUnavailable 参数),逐步用新版本替换旧版本,同时通过健康检查(liveness/readiness probe)确保新实例就绪后才下线旧实例。


Kubernetes原生Deployments滚动更新

Kubernetes(简称K8s)的Deployment资源内置滚动更新策略,是云原生场景下最常用的工具。

核心配置(YAML示例)

apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1          // 允许额外创建1个新Pod
      maxUnavailable: 1     // 允许1个旧Pod不可用
  template:
    spec:
      containers:
      - name: app
        image: myapp:v2
        readinessProbe:
          httpGet:
            path: /healthz
          initialDelaySeconds: 5
          periodSeconds: 10

执行命令

kubectl set image deployment/myapp myapp=myapp:v2 --record
kubectl rollout status deployment/myapp  # 监控状态
kubectl rollout undo deployment/myapp    # 回滚

实战技巧

  • 设置 progressDeadlineSeconds(默认600秒)避免更新卡死
  • 结合HPA(水平自动扩缩容),滚动更平滑

Docker Swarm服务滚动升级

Docker Swarm适合中小团队,配置简单。

更新命令

docker service update --image myapp:v2 --update-parallelism 2 --update-delay 10s my_service
  • --update-parallelism:同时更新的副本数
  • --update-delay:每批更新后的等待时间(用于健康检查)

:Swarm如何确保新服务正常工作?
:通过 --update-failure-action pause(默认),一旦新副本健康检查失败,自动暂停更新并保持旧版本运行。


Ansible结合负载均衡的零停机更新

适用于传统虚拟机或裸机环境,通过编排工具控制更新节奏。

Playbook关键片段

- name: 滚动更新Web服务
  hosts: web_servers
  serial: 1          # 每次只更新1台主机
  tasks:
    - name: 从负载均衡器移除
      haproxy:
        state: disabled
        host: "{{ ansible_host }}"
        backend: myapp_backend
      delegate_to: lb01
    - name: 更新应用
      docker_container:
        image: myapp:v2
        name: myapp
        state: started
        restart: true
    - name: 健康检查
      uri:
        url: "http://{{ ansible_host }}:8080/health"
      register: result
      until: result.status == 200
      retries: 10
    - name: 加入负载均衡器
      haproxy:
        state: enabled
        host: "{{ ansible_host }}"
        backend: myapp_backend
      delegate_to: lb01

优势:支持任意负载均衡器(Nginx/HAProxy/云厂商LB),完全自定义更新逻辑。


Nomad的任务组滚动策略

HashiCorp Nomad适合混合云编排,使用 update 块定义滚动参数。

Job规范示例

job "web" {
  group "app" {
    count = 5
    update {
      max_parallel = 1
      min_healthy_time = "10s"
      healthy_deadline = "5m"
      progress_deadline = "10m"
      auto_revert = true
    }
  }
}

:Nomad的“自动回滚”如何工作?
:如果新版本部署失败(健康检查持续不通过),Nomad会自动将任务组回退到上一个稳定版本,无需人工干预。


自定义脚本+反向代理(Nginx/HAProxy)

适合极端定制化需求的场景,例如老旧系统或特殊网络环境。

Bash脚本核心逻辑

#!/bin/bash
SERVERS=("192.168.1.10" "192.168.1.11" "192.168.1.12")
for server in "${SERVERS[@]}"; do
    # 1. 从Nginx upstream移除
    ssh lb "sed -i 's/server ${server}:8080;/server ${server}:8080 down;/' /etc/nginx/upstream.conf"
    ssh lb "nginx -s reload"
    # 2. 更新目标服务器
    ssh "$server" "docker pull myapp:v2 && docker-compose up -d web"
    # 3. 健康检查
    while ! curl -s "http://${server}:8080/health" | grep "ok"; do
        sleep 2
    done
    # 4. 重新加入负载均衡
    ssh lb "sed -i 's/server ${server}:8080 down;/server ${server}:8080;/' /etc/nginx/upstream.conf"
    ssh lb "nginx -s reload"
done

注意:需配合 nginx -s reload 的热重载特性,避免重启导致连接中断。


常见问题QA

Q1:滚动更新时如何处理数据库Schema变更?
A:遵循“向后兼容”原则,先执行数据库迁移(允许旧版本代码读取新字段),再滚动更新应用代码,推荐使用FlywayLiquibase管理迁移。

Q2:如果新版本有严重Bug,如何快速回滚?
A

  • K8s:kubectl rollout undo
  • Swarm:docker service update --rollback
  • Nomad:设置auto_revert = true自动回滚
  • 自定义:保留旧镜像标签,重新执行更新脚本的反向顺序

Q3:滚动更新过程中,部分旧实例仍在运行,如何保证请求路由到正确版本?
A

  • 使用服务网格(Istio/Linkerd)的流量镜像或金丝雀发布。
  • 或在反向代理层根据Cookie/Header将部分流量导向新版(金丝雀策略)。

Q4:滚动更新性能优化建议?
A

  • 减少maxUnavailable值(如设为0)避免容量骤降
  • 缩短健康检查间隔(但避免频繁检查影响性能)
  • 利用preStop钩子优雅关闭旧实例(等待已接收请求完成)

选择工具需根据团队规模与环境类型——K8s适合大规模容器化,Swarm简单易用,Ansible适合传统架构,Nomad适合多云混合,自定义脚本适合高度定制,核心原则始终是:保障健康检查、控制更新速度、保留回滚能力

标签: 滚动更新

抱歉,评论功能暂时关闭!