You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Ansible更新运行中K8s集群的daemon.json并重启Docker且不中断集群

Kubernetes集群滚动更新Docker配置操作方案

你的思路是对的,要避免集群不可用必须走逐节点滚动操作的流程,配合Ansible的串行执行配置可以完全实现无感知变更,具体实现如下:

前置检查(操作前必须完成)

  • 确认所有核心业务Pod配置了≥2的副本数,禁止单副本业务直接执行变更
  • 提前配置对应业务的PodDisruptionBudget,明确允许同时中断的Pod数量,避免驱逐过程中业务副本数低于最低可用标准
  • 提前验证你要更新的daemon.json配置合法性,本地先执行docker daemon --validate -c 待更新的daemon.json确认无语法错误
  • 确认当前所有节点状态为Ready,集群没有正在进行的升级、备份等其他变更任务

Ansible Playbook 实现

核心配置是加serial: 1,强制Ansible一次只操作一个节点,所有步骤在当前节点执行成功后才会处理下一个节点,参考Playbook如下:

---
- name: 滚动更新集群节点Docker配置并重启服务
  hosts: k8s_nodes # 替换成你的节点inventory分组
  serial: 1 # 核心配置:单次仅操作1个节点
  gather_facts: yes
  tasks:
    # 第一步:标记节点为不可调度,避免新Pod调度上来
    - name: Cordon当前节点
      command: kubectl cordon {{ inventory_hostname }}
      delegate_to: "{{ groups['kube_control_plane'][0] }}" # 委派到第一个控制面节点执行kubectl命令,也可以根据你的权限配置调整

    # 第二步:排空节点上的业务Pod
    - name: Drain当前节点,驱逐非DaemonSet的业务Pod
      command: kubectl drain {{ inventory_hostname }} --ignore-daemonsets --delete-emptydir-data --force --grace-period=30
      delegate_to: "{{ groups['kube_control_plane'][0] }}"
      register: drain_result
      until: drain_result is succeeded
      retries: 5
      delay: 10

    # 第三步:更新daemon.json配置
    - name: 更新/etc/docker/daemon.json配置
      template: # 如果你用静态文件可以换成copy模块
        src: templates/daemon.json.j2 # 替换成你的配置模板路径
        dest: /etc/docker/daemon.json
        owner: root
        group: root
        mode: '0644'

    # 第四步:验证Docker配置合法性,配置错误直接终止流程
    - name: 验证Docker配置合法性
      command: docker daemon --validate -c /etc/docker/daemon.json
      register: docker_validate_result
      failed_when: docker_validate_result.rc != 0

    # 第五步:重启Docker服务
    - name: 重载systemd配置并重启Docker
      systemd:
        name: docker
        state: restarted
        daemon_reload: yes

    # 第六步:验证Docker和Kubelet状态正常
    - name: 验证Docker服务运行正常
      command: systemctl is-active docker
      register: docker_status
      failed_when: docker_status.stdout != 'active'

    - name: 验证Kubelet服务运行正常
      command: systemctl is-active kubelet
      register: kubelet_status
      failed_when: kubelet_status.stdout != 'active'

    # 第七步:等待节点重新注册到集群,状态恢复为Ready
    - name: 等待节点状态恢复为Ready
      command: kubectl get node {{ inventory_hostname }} -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
      delegate_to: "{{ groups['kube_control_plane'][0] }}"
      register: node_ready_status
      until: node_ready_status.stdout == 'True'
      retries: 10
      delay: 10

    # 第八步:取消节点不可调度标记,恢复Pod调度
    - name: Uncordon当前节点,恢复调度
      command: kubectl uncordon {{ inventory_hostname }}
      delegate_to: "{{ groups['kube_control_plane'][0] }}"

    # 第九步:等待节点上Pod恢复正常后再处理下一个节点
    - name: 等待节点上所有Pod状态正常
      shell: kubectl get pods --all-namespaces --field-selector spec.nodeName={{ inventory_hostname }} | grep -v -E 'Running|Completed' | wc -l
      delegate_to: "{{ groups['kube_control_plane'][0] }}"
      register: pod_running_status
      until: pod_running_status.stdout == '0'
      retries: 10
      delay: 10

注意事项

  • 如果是操作控制面节点,需要保证操作前至少2个控制面节点处于健康状态,操作完成后额外验证etcd集群状态正常,避免etcd选主失败
  • 操作过程中任意节点执行失败,Ansible会自动终止整个流程,排查完对应节点问题后再重新执行即可,不要强制跳过错误
  • 如果集群节点跨可用区部署,可以调整serial为每个可用区的节点数,按可用区批量操作,进一步降低故障风险

内容的提问来源于stack exchange,提问作者Josh Schubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:06:01