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

如何在Ansible任务级别覆盖主机,实现K8S Worker节点Cordon、Drain与重启

解决方案:逐个重启Kubernetes Worker节点的Ansible Playbook

你的需求完全可以实现,但任务级别不能直接使用hosts关键字,需要通过delegate_to或local_action指定在localhost执行kubectl命令,同时仍能获取当前Worker节点的主机名变量。以下是修正后的完整Playbook及关键说明:

修正后的Playbook代码

- name: 逐个重启Kubernetes Worker节点
  become: yes
  hosts: workers
  gather_facts: no
  serial: 1  # 强制逐个处理节点,确保一个节点完成全流程再处理下一个
  tasks:
    - name: 将Worker节点标记为不可调度(cordon)
      delegate_to: localhost  # 该任务委托到localhost执行
      shell: kubectl cordon {{ inventory_hostname }}
      async: 300
      poll: 10

    - name: 驱逐Worker节点上的Pod(drain)
      delegate_to: localhost
      shell: >
        kubectl drain {{ inventory_hostname }}
        --ignore-daemonsets
        --delete-emptydir-data
        --force
      async: 300
      poll: 10
      register: drain_result
      failed_when: drain_result.rc not in [0, 1]  # 兼容节点无Pod可驱逐的场景

    - name: 重启Worker节点
      reboot:
        reboot_timeout: 500

关键要点说明

  • 任务级主机切换:用delegate_to: localhost替代示例中的hosts: localhost,既让kubectl命令在本地执行,又保留了Play目标主机(Worker节点)的变量(比如inventory_hostname就是当前Worker的主机名),完美匹配kubectl命令的需求。
  • 逐个节点执行:serial: 1是核心配置,它会让Play按顺序处理workers组中的每个节点,只有当前节点完成cordon、drain、重启全流程后,才会开始处理下一个节点。
  • kubectl drain参数优化:添加了--ignore-daemonsets(忽略守护进程Pod,这类Pod通常无法被驱逐)、--delete-emptydir-data(清理使用emptyDir的Pod数据)、--force(强制驱逐无法优雅终止的Pod),这些是生产环境中常用的必要参数。
  • 容错处理:drain任务的failed_when规则,兼容了节点上已无可驱逐Pod的场景(此时kubectl drain可能返回非0码,但不属于执行失败)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:37:25