当前位置: 首页 > news >正文

K8s运维实战:给Node节点“放假”的三种姿势(cordon/drain/delete保姆级对比)

K8s节点管理艺术:从优雅隔离到彻底移除的实战指南

节点管理的核心逻辑与场景

在Kubernetes集群的日常运维中,节点管理就像一支交响乐团的指挥工作——需要精确控制每个乐器的入场与退场时机。当某个节点需要维护、升级或退役时,如何确保服务不中断、数据不丢失,同时又能高效完成操作?这正是cordondraindelete这三个命令存在的意义。它们分别对应着三种不同级别的节点隔离策略:

  • 礼貌暂停:像音乐会中场休息,暂时停止新任务分配但保留现有演出(cordon)
  • 有序撤离:类似乐手轮换,先安全转移工作再停止服务(drain)
  • 彻底离场:相当于乐团成员离职,完全移除所有关联(delete)

实际运维中最常见的三大场景包括:计划内维护(如内核升级或硬件更换)、节点故障紧急处理以及集群资源优化调整。选择哪种"休假方式",取决于你对节点未来去向的规划。

重要提示:任何节点操作前务必先执行kubectl get pods -o wide | grep <节点名>,确认该节点运行的关键工作负载

1. 礼貌暂停:cordon的优雅隔离术

1.1 基础原理与操作

cordon相当于给节点挂上"请勿打扰"的牌子。执行后,Kubernetes调度器会将该节点标记为SchedulingDisabled状态,但不会对现有Pod产生任何影响。这就像让节点进入"调休"模式——虽然不出勤,但手头工作照常进行。

典型操作流程:

# 查看节点状态 kubectl get nodes # 标记节点为不可调度 kubectl cordon <node-name> # 验证节点状态 kubectl describe node <node-name> | grep -i schedulable

1.2 适用场景与注意事项

这种模式特别适合以下情况:

  • 预检维护:在实施可能影响稳定性的操作前,先阻止新Pod调度
  • 问题排查:隔离疑似故障节点,避免问题扩散
  • 灰度发布:配合节点选择器实现分批更新

但需要注意:

  1. 已有Pod会继续运行,可能影响维护操作
  2. DaemonSet管理的Pod仍可能被调度到该节点
  3. 需要后续配合drain才能安全下线

参数对比表

特性cordondraindelete
新Pod调度×××
现有Pod处理保留驱逐驱逐
节点元数据保留保留删除
恢复难度简单简单复杂

2. 有序撤离:drain的安全驱逐方案

2.1 完整驱逐流程解析

drain是运维人员最常用的"标准休假流程"。它实际上是cordon的增强版——先禁止调度,然后按照优雅终止策略逐步驱逐Pod。整个过程就像安排员工交接工作:

  1. 通知Pod准备终止(发送SIGTERM)
  2. 等待优雅终止期(默认30秒)
  3. 强制终止未响应Pod(SIGKILL)
  4. 在其他节点重建Pod

完整命令示例:

# 安全驱逐节点所有Pod(忽略DaemonSet和管理本地存储) kubectl drain <node-name> \ --ignore-daemonsets \ --delete-emptydir-data \ --timeout=300s

2.2 关键参数深度解读

  • --ignore-daemonsets:必须参数,因为DaemonSet Pod需要保持节点级服务
  • --delete-emptydir-data:清理使用emptyDir的Pod数据
  • --timeout:设置整个驱逐过程的超时时间
  • --pod-selector:选择性驱逐特定标签的Pod

经验之谈:生产环境建议配合PodDisruptionBudget使用,通过minAvailable设置确保关键服务始终有足够副本

2.3 常见报错解决方案

问题1:无法驱逐本地存储Pod

cannot delete Pods with local storage (use --delete-emptydir-data to override)

解决:评估数据重要性后添加--delete-emptydir-data参数

问题2:DaemonSet Pod阻止操作

cannot delete DaemonSet-managed Pods

解决:必须添加--ignore-daemonsets参数

问题3:Pod驱逐超时

error: timed out waiting for pod xxx to terminate

解决

  1. 检查Pod是否配置了合理的terminationGracePeriodSeconds
  2. 适当增加--timeout
  3. 确认kubelet工作正常

3. 彻底离场:delete的完全移除

3.1 核心理念与风险控制

delete是节点管理的"终极手段",相当于直接解除劳动合同。它不仅会驱逐所有Pod,还会从API Server中彻底移除节点对象。这种操作具有不可逆性,通常只在以下场景使用:

  • 永久性节点退役
  • 节点异常且无法恢复
  • 云环境节点被直接销毁

基本操作流程:

# 从集群删除节点定义 kubectl delete node <node-name> # 节点侧需要清理kubelet相关数据 ssh <node-ip> "sudo kubeadm reset -f" # 重新加入集群需要重新生成join命令 kubeadm token create --print-join-command

3.2 与drain的本质区别

虽然两者都会驱逐Pod,但delete会额外:

  1. 从etcd删除节点对象
  2. 需要重新加入才能恢复
  3. 可能导致监控数据断裂
  4. 影响节点关联的PV/PVC

操作影响对比

影响维度draindelete
节点对象保留删除
证书信息保留失效
监控连续性保持中断
恢复方式uncordon重新join

4. 实战决策树与进阶技巧

4.1 命令选择决策流程图

开始 │ ├─ 需要临时维护? → cordon → 维护完成 → uncordon │ ├─ 需要长期下线? → drain → 节点保留 → 未来uncordon │ └─ 永久移除? → drain → delete

4.2 大规模集群管理实践

对于超过50个节点的大型集群,建议:

  1. 使用节点亲和性分散关键Pod
  2. 设置合理的PDB(PodDisruptionBudget)
  3. 采用分批次滚动维护策略
  4. 配合Cluster Autoscaler自动补偿容量

示例滚动维护脚本:

#!/bin/bash for node in $(kubectl get nodes -l worker=yes -o name); do kubectl drain ${node#node/} --ignore-daemonsets --grace-period=900 perform_maintenance kubectl uncordon ${node#node/} sleep 300 # 等待集群稳定 done

4.3 监控与验证要点

操作后必须检查:

  1. 所有Pod是否重建成功:
    kubectl get pods -o wide | grep -v Running
  2. 节点资源压力:
    kubectl top nodes
  3. 服务可用性指标:
    • 请求成功率
    • 响应延迟
    • 错误日志量

5. 特殊场景处理手册

5.1 有状态服务处理方案

当节点运行着StatefulSet或带本地存储的Pod时:

  1. 提前确认存储复制状态
  2. 使用--pod-selector避开关键Pod
  3. 手动控制迁移顺序
  4. 验证数据一致性

Cassandra等特殊中间件可能需要自定义驱逐钩子:

lifecycle: preStop: exec: command: ["/bin/sh", "-c", "nodetool drain"]

5.2 云环境特殊考量

主流云平台的特殊处理:

云平台节点终止行为建议操作
AWS实例终止自动触发drain直接终止实例
GCP节点池自动修复使用托管实例组API
Azure虚拟机SSD本地存储提前迁移有状态Pod

5.3 内核升级实战案例

典型内核升级流程:

# 1. 标记节点不可调度 kubectl cordon node-01 # 2. 安全驱逐Pod(给30分钟优雅退出时间) kubectl drain node-01 --ignore-daemonsets --timeout=1800s # 3. SSH登录节点执行升级 ssh node-01 "sudo apt update && sudo apt install linux-image-new" # 4. 重启节点 ssh node-01 "sudo reboot" # 5. 等待节点恢复 watch kubectl get nodes # 6. 重新允许调度 kubectl uncordon node-01

6. 自动化运维集成

6.1 与CI/CD管道结合

在GitOps工作流中添加节点健康检查:

steps: - name: node-drain-check image: kubectl:latest commands: - kubectl get nodes -o json | jq '.items[] | select(.spec.unschedulable == true)' - test $(kubectl get pods --field-selector=status.phase!=Running -A | wc -l) -eq 0

6.2 自定义控制器实现

通过Kubernetes Operator实现智能排水:

func (r *NodeMaintenanceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { node := &corev1.Node{} if err := r.Get(ctx, req.NamespacedName, node); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) } if node.Labels["maintenance"] == "true" { if !node.Spec.Unschedulable { if err := r.cordonNode(ctx, node); err != nil { return ctrl.Result{}, err } } pods, err := r.getPodsOnNode(ctx, node.Name) if err != nil { return ctrl.Result{}, err } if len(pods) > 0 { if err := r.evictPods(ctx, pods); err != nil { return ctrl.Result{}, err } return ctrl.Result{RequeueAfter: 30 * time.Second}, nil } } return ctrl.Result{}, nil }

6.3 Prometheus告警规则示例

节点排水状态监控:

groups: - name: node-maintenance rules: - alert: LongRunningDrain expr: time() - kube_node_spec_unschedulable_change_timestamp_seconds > 3600 for: 15m labels: severity: warning annotations: summary: "Node {{ $labels.node }} has been draining for over 1 hour" description: "Check pod eviction issues on {{ $labels.node }}"
http://www.jsqmd.com/news/656820/

相关文章:

  • 蓝桥杯DP题“更小的数”保姆级解析:从暴力O(n³)到动态规划O(n²)的优化之路
  • 2026年华东、华中、华南集中供热保温管道系统与蒸汽节能输送解决方案 - 企业名录优选推荐
  • 无人机视觉‘看懂’世界:从BEV视图合成到目标跟踪,一份给算法工程师的避坑与实践指南
  • 保姆级教程:用PyTorch从零搭建一个CNN,在CIFAR-10上实现75%+准确率
  • Calibre路径本地化技术解析:告别拼音目录,拥抱原生中文路径
  • 【划重点】HarmonyOS 应用市场审核 3.63.7 驳回“四大场景”全解析
  • R3nzSkin终极指南:如何安全免费实现英雄联盟全皮肤切换
  • 数据仓库核心组件解析:事实表与维度表的设计哲学与应用场景
  • 玄机靶场-实战Live勒索病毒溯源排查 WP
  • 三菱旋切飞剪:Q172DSCPU控制下的程序与文档说明(含凸轮曲线分析计算结果)
  • Ubuntu 22.04 LTS下,5分钟搞定PyCharm社区版安装与Anaconda环境关联(附搜狗输入法冲突解决)
  • 帧级精准同步:video-compare在视频质量分析中的技术架构与应用实践
  • 在线帮助系统:知识库检索与上下文感知帮助
  • CSS Grid高级布局技巧与实战
  • 别再找第三方工具了!Windows 10自带虚拟网卡功能,5分钟搞定Microsoft Loopback Adapter
  • 被飞书和火山引擎账号体系整崩溃了?一个程序员彻底讲清楚背后的设计逻辑
  • 避坑指南:psplash开机动画在ARM开发板上的5大常见部署错误及解决方法
  • 告别轮询:深入理解RDMA Verbs中的CQ事件通知机制(ibv_req_notify_cq与ibv_get_cq_event实战)
  • AI 域名投资价值高吗
  • STM32 HAL库实战:DMA串口通信避坑指南(附CubeMX配置)
  • 2026年React Native热更新主流方案对比解析
  • Windows安全防护-深入剖析QQ巨盗病毒行为与查杀策略
  • 深入DSP28379D Boot ROM:双核启动顺序、IPC通信与安全启动(DCSM/OTP)机制解析
  • 若依框架里MyBatis分页失效?别在Service层循环查数据库了!
  • 告别转圈和报错:手把手教你解决Android 12/13手机连接Appium Inspector的三大疑难杂症
  • 真空干燥箱品牌与生产厂家怎么选?2026高口碑优质厂商实力对比及选购参考 - 品牌推荐大师1
  • Chrome画中画扩展技术实现:高效多任务视频处理架构设计
  • 深入剖析Swap机制:从swap_info_struct到swp_entry_t的全链路解析
  • 清香型白酒代理优选:德厚成+杏花酒,低风险高潜力 - 中媒介
  • 2026年纳米CT供应商技术实力评估:从系统集成到工程化交付——以无锡璟能智能仪器有限公司为例 - 品牌推荐大师1