Kubernetes 节点维护模式:cordon、drain 与 delete 操作差异及业务无感知迁移保障

在 Kubernetes 集群中,节点维护是常见操作,用于处理硬件升级、资源调整或故障修复。核心目标是确保业务服务在迁移过程中无感知(即用户无中断、无延迟影响)。cordon、drain 和 delete 是三种关键操作,它们在节点维护中扮演不同角色。下面我将逐步解释每个操作的含义、差异和最佳实践,帮助您安全执行维护。

1. cordon 操作:标记节点为不可调度
  • 含义cordon 用于将节点标记为“不可调度”(unschedulable),阻止新 Pod 被调度到该节点上,但不会影响节点上已有的 Pod。这相当于设置一个“维护中”的隔离状态。
  • 操作命令
    kubectl cordon <node-name>  # 例如:kubectl cordon node-1
    

  • 作用
    • 防止新工作负载分配到该节点,为后续维护做准备。
    • 节点状态变为 SchedulingDisabled,但现有 Pod 继续运行。
  • 适用场景:计划性维护前隔离节点,避免新任务中断。
2. drain 操作:优雅驱逐节点上的 Pod
  • 含义drain 会驱逐节点上的所有 Pod(包括 DaemonSet 外的 Pod),并安全地将它们重新调度到其他可用节点。此操作自动包含 cordon 步骤,确保迁移过程平滑。
  • 操作命令
    kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --grace-period=300  # 示例命令,参数可调整
    

    • 常用选项:
      • --ignore-daemonsets:忽略 DaemonSet Pod(如日志代理),避免驱逐失败。
      • --delete-emptydir-data:清理临时数据卷(EmptyDir),防止数据残留。
      • --grace-period=<seconds>:设置优雅终止时间(默认为 30 秒),允许 Pod 完成当前任务再终止。
  • 作用
    • 自动重新调度 Pod 到健康节点,确保服务连续性。
    • 在驱逐过程中,Kubernetes 控制器(如 Deployment)会创建新 Pod 替代旧 Pod。
  • 适用场景:节点下线维护、升级或资源回收,核心是实现业务无感知迁移。
3. delete 操作:从集群中移除节点
  • 含义delete 直接从 Kubernetes API 中删除节点对象,通常用于节点永久移除(如硬件报废)。这不是维护首选,因为它不会自动处理 Pod 迁移。
  • 操作命令
    kubectl delete node <node-name>  # 例如:kubectl delete node node-1
    

  • 作用
    • 节点被移除后,其上的 Pod 会被强制终止(可能引发服务中断)。
    • 如果节点仍在线,Kubernetes 可能自动重新发现它,导致状态不一致。
  • 适用场景:节点永久删除,需谨慎使用;通常与 drain 结合,确保先迁移 Pod。
操作差异对比

下表总结了三种操作的关键差异,帮助您根据场景选择:

操作 主要目的 影响现有 Pod 自动重新调度 Pod 是否推荐维护使用 命令复杂度
cordon 隔离节点,防止新 Pod 调度 不驱逐,Pod 继续运行 是(作为预备步骤)
drain 驱逐并迁移所有 Pod 驱逐所有 Pod(除 DaemonSet) 是(核心迁移操作) 中(需选项)
delete 永久移除节点 强制终止 Pod 否(可能丢失服务) 否(除非节点报废)
  • 关键差异点
    • cordon 只做隔离,不迁移 Pod;drain 在隔离基础上执行迁移;delete 是硬删除,风险最高。
    • 在维护中,drain 是实现无感知迁移的核心,因为它处理 Pod 的优雅终止和重新调度。
    • cordondrain 可逆(如 kubectl uncordon 恢复节点),而 delete 不可逆。
保障业务无感知迁移的最佳实践

业务无感知迁移要求服务在维护期间零中断(用户无感知)。以下是关键步骤,结合 cordondrain 操作:

  1. 准备阶段(确保集群健康)

    • 检查集群资源:确保其他节点有足够容量处理迁移 Pod。使用 kubectl describe nodes 查看资源利用率。
    • 设置 Pod Disruption Budget (PDB):定义最小可用 Pod 数量(如 PDB 指定 minAvailable: 90%),防止大规模驱逐导致服务中断。示例 PDB 配置:
      apiVersion: policy/v1
      kind: PodDisruptionBudget
      metadata:
        name: my-app-pdb
      spec:
        minAvailable: 90%  # 保证至少 90% Pod 可用
        selector:
          matchLabels:
            app: my-app
      

  2. 执行迁移(使用 drain 保障无感知)

    • 先执行 cordon:隔离节点,避免新任务干扰。
      kubectl cordon <node-name>
      

    • 再执行 drain:优雅驱逐 Pod。关键选项确保平滑:
      kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --grace-period=300
      

      • --grace-period=300:给 Pod 5 分钟完成处理(如数据库事务)。
      • Kubernetes 自动重新调度:控制器(如 ReplicaSet)在健康节点启动新 Pod,旧 Pod 在终止前继续服务(实现无缝切换)。
    • 监控迁移:使用 kubectl get pods -o wide 观察 Pod 状态,确保所有 Pod 在 Terminating 后快速变为 Running 于新节点。
  3. 维护后恢复

    • 如果节点需重新加入,运行 kubectl uncordon <node-name> 恢复可调度状态。
    • 验证服务:使用工具(如 kubectl top pods 或 Prometheus)监控延迟和错误率,确保无感知。
  4. 避免 delete 在维护中使用

    • 仅在节点报废时使用 delete,且必须提前 drain 节点。否则,Pod 强制终止会导致服务中断。
总结
  • 操作顺序推荐:维护节点时,首选 cordon 隔离,然后 drain 迁移,最后可 delete(仅当永久移除)。drain 是实现无感知迁移的核心,通过优雅驱逐和自动重新调度保障业务连续。
  • 风险控制:结合 PDBs 和足够的 grace-period,能有效减少中断概率。测试在非生产环境验证流程。
  • 如果您有具体集群细节(如 Pod 类型),我可以提供更定制建议。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐