ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kubernetes生产运维14:集群升级怎么做到业务无感,从API兼容到逐节点驱逐的完整流程

Kubernetes生产运维14:集群升级怎么做到业务无感,从API兼容到逐节点驱逐的完整流程 Kubernetes生产运维14集群升级怎么做到业务无感从API兼容到逐节点驱逐的完整流程写在前面集群升级是运维里少数做对了没人夸做错了全公司都知道的操作。它最怕两件事废弃API新版本删掉了某些API版本你的工作负载还在用升级后突然失效节点驱逐升级节点时要把上面的Pod赶走如果驱逐不当业务会被打断做到业务无感的核心不是运气而是一套有顺序、有保护、有回退的流程先查兼容、先升控制面、节点逐批升、每批验证、随时能退。这篇给出这套完整流程和一份可直接用的Runbook并结合一段EKS逐节点升级的真实脱敏经验说明实际会踩的坑。本文按照Kubernetes官方机制整理并结合作者管理多云集群、做过EKS逐节点升级的脱敏经验。由于当前没有连接可验证的实验集群命令和输出均为说明性重建不是某次升级的原始记录。不同Kubernetes版本、托管服务EKS/GKE/ACK等和自建方式的升级步骤差异很大务必以对应版本和平台的官方文档为准。升级是高风险操作每步都要有验证和回退。写在前面的真实经验先说一个我在EKS升级中反复确认的经验它定了这篇的基调升级前我会先借助工具审查新版本是否调整了API版本或CRD看当前工作负载要不要改升级时先升控制面托管集群由云厂商升再逐个升级Node Pool一台一台来每升一批观察Pod是否正常。曾经踩过的坑是有些Pod没有指定nodegroup或调度约束节点升级驱逐后飘到了错误的节点所以每次升级都要特别注意Pod的调度约束。这段是A级脱敏经验先查兼容、控制面先升、节点逐台升、注意调度约束。下面把它展开成完整流程。文中的具体命令输出属于说明性重建不是那次升级的原始记录。一、升级前查兼容别让API废弃埋雷2.1 看版本变更和废弃API升级前先读目标版本和中间版本的Release Notes重点是废弃deprecated和移除removed的API版本。Kubernetes会在若干版本前标记废弃到某个版本正式移除。如果你的工作负载还在用被移除的API版本升级后这些资源会无法创建或更新。2.2 扫描现有工作负载用了哪些废弃API不要靠人工翻YAML。用工具扫描集群里实际在用的API版本例如社区的废弃API检测工具或云厂商EKS/GKE提供的升级前检查insights。原则升级前扫描出所有使用废弃或将被移除API的资源提前把它们迁移到新API版本在升级前就改好不只看自己的应用还要看Ingress Controller、监控组件、CRD、Operator等第三方组件是否兼容目标版本2.3 检查组件兼容性除了API还要确认Ingress Controller、CNI、CSI、监控栈是否支持目标版本CRD和Operator是否兼容kubelet与控制面的版本偏差是否在支持范围内二、升级顺序先控制面再节点3.1 为什么控制面先升Kubernetes支持控制面比节点版本高一定范围版本偏差策略。所以顺序是先升控制面再升节点反过来不行。托管集群EKS/GKE/ACK控制面由云厂商升级你点一下或调API云厂商负责。没有master/slave这种自己管的概念。自建集群按kubeadm等工具的流程先升控制面组件多控制面节点逐个升。3.2 节点升级逐批而不是一起节点升级不能一次全升否则大量Pod同时被驱逐会打断业务。做法是逐批甚至逐台对每个节点cordon 该节点标记不可调度新Pod不再进来 → drain 该节点驱逐上面的Pod让它们在别处重建 → 升级/替换该节点 → 节点Ready后uncordon重新可调度 → 验证再进行下一批托管集群常用的是替换式升级创建新版本节点把旧节点上的Pod迁过去再删旧节点。原理一样关键都是逐批、有驱逐、有验证。3.3 cordon和drain的作用kubectl cordonnodekubectl drainnode--ignore-daemonsets --delete-emptydir-datacordon只标记节点不可调度不动现有Pod让新Pod不再进来drain驱逐节点上的Pod触发它们在其他节点重建--ignore-daemonsets因为DaemonSet每节点都有、不需迁移--delete-emptydir-data表示接受emptyDir数据丢失drain是有序驱逐会尊重PDB。三、用PDB保证驱逐期间的可用性4.1 PDB是什么PodDisruptionBudgetPDB声明一个工作负载在自愿驱逐如drain期间最少要保留多少可用副本或最多容忍多少不可用。apiVersion:policy/v1kind:PodDisruptionBudgetmetadata:name:web-pdbnamespace:appspec:minAvailable:2# 驱逐期间至少保留2个可用selector:matchLabels:app:web4.2 PDB如何让升级无感drain驱逐Pod时会遵守PDB如果驱逐某个Pod会导致可用副本低于PDB的要求drain会等待直到有足够副本就绪才继续。这样即使在逐节点升级、不断驱逐Pod的过程中每个工作负载始终保持足够的可用副本业务不中断。设计要点关键服务都应配PDBminAvailable按能容忍的最小可用副本设单副本服务无法在驱逐时保持可用PDB也救不了要先多副本化PDB配得太严如minAvailable等于总副本数会让drain卡住永远驱逐不动4.3 配合readiness和优雅关闭驱逐时Pod会被终止并在别处重建。要做到无感还需要readiness探针正确新Pod就绪后才接流量第11篇优雅关闭旧Pod先摘流量再终止足够副本和合理的滚动避免瞬时容量不足四、C级生产化重建案例升级卡在一个drain不动的节点5.1 先说明哪些是真的哪些是重建的下面结合真实的EKS逐节点升级经验但具体场景和输出是根据机制构造的生产化重建不是某次升级的原始记录。内容证据属性先查兼容、控制面先升、节点逐台升、注意调度约束A级脱敏经验cordon、drain、PDB和驱逐的机制Kubernetes官方机制drain卡住、PDB阻止驱逐的具体场景机制一致的重建场景Namespace、资源名、副本数和终端输出为讲解构造的说明性信息某服务PDB配置过严导致drain卡住模拟根因不是某次升级原始记录所有输出按真实对象关系编排但没有连接实际集群采集读者不能把下面的数值引用为某次升级的真实数据。5.2 现场卡片逐节点升级进行到某个节点时drain一直卡住不动节点上的一个Pod始终驱逐不掉升级停滞。团队最初怀疑节点或Pod卡死。重建的相对时间线相对时间观察或动作当时能够得出的结论T00drain某节点长时间不返回驱逐受阻原因未知T02怀疑Pod卡死待验证假设T04drain输出提示违反PDB转向PDBT06发现该服务PDB的minAvailable等于总副本数得到可验证的主假设T验证调整PDB或先扩副本后观察drain单变量验证相对时间只表示排查顺序不代表真实数值。5.3 看drain为什么卡住kubectl drain worker-5 --ignore-daemonsets --delete-emptydir-data机制一致的说明性输出evicting pod app/web-xxxx error when evicting pods/web-xxxx -n app: Cannot evict pod as it would violate the pods disruption budget.drain明确说驱逐这个Pod会违反它的PDB。不是Pod卡死是PDB在阻止。5.4 查PDB配置kubectl get pdb-napp kubectl describe pdb web-pdb-napp机制一致的说明性输出NAME MIN AVAILABLE ALLOWED DISRUPTIONS web-pdb 3 0 web Deployment副本数为3关键发现PDB的minAvailable是3而该Deployment总共就3个副本。这意味着任何时候都不允许有Pod不可用ALLOWED DISRUPTIONS为0drain永远无法驱逐任何一个Pod。证据链drain提示违反PDB不是Pod卡死 PDB minAvailable3 Deployment副本数也是3 ALLOWED DISRUPTIONS0 强烈支持PDB配置过严导致drain无法驱逐这仍是主假设验证前不写成根因已闭环。5.5 止损与单变量验证有两种单变量修正选影响最小的方案一临时把副本从3扩到4这样允许1个被驱逐drain能继续方案二把PDB的minAvailable从3改成2允许1个不可用方案一不降低可用性更稳妥。只改副本数这一项kubectl scale deployment web-napp--replicas4kubectl rollout status deployment/web-napp--timeout5m然后重试drainkubectl drain worker-5 --ignore-daemonsets --delete-emptydir-data kubectl get pdb web-pdb-napp机制一致的说明性输出node/worker-5 drained NAME MIN AVAILABLE ALLOWED DISRUPTIONS web-pdb 3 1扩到4副本后PDB允许1个被驱逐drain顺利完成升级继续。这些输出分别证明不同范围的事实输出能够支持不能单独证明ALLOWED DISRUPTIONS变1有了可驱逐余量所有节点都能顺利drainnode drained成功该节点已安全腾空业务完全无感副本扩到4驱逐期间仍满足minAvailable长期需要4副本5.6 根因闭环与永久修复临时:扩副本让drain继续,完成本次升级永久:修正PDB设计,minAvailable不应等于总副本数,要留出至少1个可驱逐余量;或按可用性需求同时提高副本数和PDB升级完成后如果临时扩了副本,按需恢复这也印证了那段真实经验:升级前的准备(包括PDB和副本设计)比升级动作本身更重要。PDB配错不是升级时才暴露,而是升级时才被用到。五、完整升级Runbook一、升级前准备 [ ] 阅读目标版本和中间版本的Release Notes列出废弃和移除的API [ ] 用工具扫描集群在用的废弃API提前迁移到新版本 [ ] 确认Ingress Controller、CNI、CSI、监控、CRD、Operator兼容目标版本 [ ] 确认关键服务多副本且配了合理的PDB [ ] 检查Pod的调度约束避免驱逐后飘到错误节点 [ ] 在测试集群先完整升一遍观察一段时间 [ ] 准备回退预案确认能退到什么程度 二、升级控制面 [ ] 选低峰窗口 [ ] 托管集群触发控制面升级自建集群逐个升控制面节点 [ ] 验证控制面组件健康、API正常 三、逐批升级节点 [ ] 一批一台或少量节点cordon → drain遵守PDB→ 升级/替换 → Ready后uncordon [ ] 每批后验证Pod正常调度、无异常重启、关键服务可用 [ ] 观察调度约束确认Pod没飘到错误节点 [ ] 有问题立即暂停不继续下一批 四、升级后验证 [ ] 核心业务功能验证 [ ] 监控指标、错误率、延迟对比升级前 [ ] 组件和CRD工作正常 [ ] 恢复升级期间的临时调整如临时扩的副本 五、回退 [ ] 若控制面升级异常按平台回退能力处理 [ ] 若某批节点异常暂停并排查必要时回退该批 [ ] 记录问题复盘后再继续这份Runbook可以直接改成你集群的检查项。六、监控与治理7.1 升级期间监控什么每批节点升级后Pod的调度和就绪情况关键服务的可用副本数是否始终满足PDB业务错误率、延迟与升级前对比是否有Pod因调度约束飘到错误节点控制面组件健康7.2 治理升级前检查API扫描、兼容性、PDB、调度约束标准化成清单关键服务默认多副本加PDBPDB不设成等于总副本数固定升级节奏如跟随社区版本每隔一到两个小版本升一次不跨大版本跳升每次升级后复盘把踩的坑回补进Runbook测试集群先行生产低峰窗口执行七、常见误区误区1不查废弃API直接升工作负载用了被移除的API升级后失效。误区2节点一次全升大量Pod同时驱逐会打断业务要逐批。误区3不配PDB就drain没有PDB保护驱逐可能瞬间打掉过多副本。误区4PDB设成等于总副本数ALLOWED DISRUPTIONS为0drain永远卡住。误区5单副本服务指望升级无感单副本驱逐必然中断要先多副本化。误区6忽略Pod调度约束驱逐后Pod可能飘到错误节点升级前要检查。误区7先升节点再升控制面违反版本偏差策略顺序必须控制面先。误区8不在测试集群预演生产直接升遇到兼容问题就是事故。八、面试怎么说60秒版本集群升级我按固定流程升级前先查废弃和移除的API用工具扫描集群在用的版本提前迁移还要确认Ingress、CNI、CSI、监控和CRD兼容目标版本。顺序是控制面先升托管集群由云厂商升然后节点逐批升不能一次全升。每个节点cordon加draindrain会遵守PDB保证关键服务始终有足够可用副本。每批升完验证Pod调度和业务有问题就暂停。我踩过的坑是有些Pod没设调度约束驱逐后飘到错误节点所以每次都要检查。最后测试集群先行、低峰执行、有回退预案。3分钟场景版本假设逐节点升级时drain卡在一个节点不动。我先看drain输出提示会违反PDB说明不是Pod卡死是PDB在阻止。查这个服务的PDBminAvailable设成了3而Deployment副本也是3导致ALLOWED DISRUPTIONS为0任何驱逐都不允许drain永远卡住。根因是PDB配置过严。我选影响最小的方案临时把副本扩到4让PDB允许1个被驱逐drain随即完成升级继续。永久修复是改PDB设计minAvailable不能等于总副本数要留可驱逐余量。这件事说明升级的坑往往在准备阶段就埋下了PDB、副本、调度约束这些不是升级时才配而是升级时才被用到。所以我把这些检查都放进升级前的Runbook。九、延伸问答1. 为什么控制面要先升版本偏差策略允许控制面比节点高一定范围反过来不行所以控制面先升。2. 节点为什么要逐批升一次全升会同时驱逐大量Pod打断业务逐批加PDB才能无感。3. cordon和drain区别cordon只标记不可调度不动现有Poddrain会驱逐Pod让它们在别处重建。4. PDB怎么保证升级无感drain遵守PDB驱逐会导致可用副本不足时会等待保证始终有足够副本。5. PDB设成minAvailable等于总副本会怎样ALLOWED DISRUPTIONS为0drain永远无法驱逐升级卡住。6. 废弃API怎么提前发现用社区废弃API检测工具或云厂商升级前检查扫描集群实际在用的版本。7. 托管集群升级和自建有什么不同托管集群控制面由云厂商升你不用管master自建要自己按kubeadm等流程升控制面。8. 升级出问题怎么回退控制面按平台回退能力处理节点批次异常就暂停排查必要时回退该批并复盘。小结升级最怕废弃API和节点驱逐打断业务靠流程而非运气解决。升级前查废弃API并提前迁移确认组件兼容。顺序是控制面先升再节点逐批升。节点cordon加draindrain遵守PDB保证可用副本。关键服务多副本加PDBPDB不能等于总副本数。检查Pod调度约束避免驱逐后飘到错误节点。测试集群先行低峰执行每批验证有回退预案。升级的坑多在准备阶段埋下把检查标准化成Runbook。下一篇预告下一篇是本专栏最后一篇监控、告警与故障复盘。我们会讲清RED和USE方法、SLO、告警降噪、故障时间线和Postmortem把前面所有排障经验收敛成稳定性闭环。参考资料Kubernetes官方文档Version Skew PolicyKubernetes官方文档Upgrade A ClusterKubernetes官方文档Deprecated API Migration GuideKubernetes官方文档Kubernetes Deprecation PolicyKubernetes官方文档Specifying a Disruption Budget for your ApplicationKubernetes官方文档DisruptionsKubernetes官方文档Safely Drain a NodeKubernetes官方文档Upgrading kubeadm clustersKubernetes官方文档kubectl drainKubernetes官方文档PodDisruptionBudget API
返回列表