☰
K9s v0.17.6 节点维护实战:在 Node 视图中一键完成 Cordon / Uncordon / Drain 集群运维
2026/9/30 6:51:12 网站建设 项目流程
  • 云原生
  • 容器编排
  • CLI
  • 运维

【免费下载链接】k9s

🐶 Kubernetes CLI To Manage Your Clusters In Style!

项目地址:https://gitcode.com/GitHub_Trending/k9s/k9s
点击查看免费下载

导读

本文聚焦 K9s v0.17.6 版本引入的节点直接维护能力:在 Node 视图中按下快捷键即可对集群节点执行封锁(cordon)、解除封锁(uncordon)与排水(drain),每种操作都配有可配置参数的对话框。读完本文,你将掌握 K9s 节点维护的完整操作流程、各参数含义,以及这套交互能力在internal/view/node.go、internal/view/drain_dialog.go与internal/dao/node.go中的底层实现原理,可用于日常集群容量调整、节点下线、故障隔离与滚动维护场景。

一、版本背景:为什么需要"Get A Rope"特性

K9s 的 release_v0.17.6 以 "Get A Rope!" 为主题,回应了长期积压的需求:当你的集群需要"春季大扫除"——比如替换节点、腾空节点以便维护、或临时将节点从调度池中隔离时,过去需要跳出终端反复执行kubectl cordon、kubectl uncordon、kubectl drain三条命令。而 v0.17.6 将这三项操作直接内置到 K9s 的 Node 视图中,配合对话框完成参数配置与操作确认。

该版本同时解决了 Issue #612、#608、#606、#237,并合并了 PR #607 与 PR #570 等贡献。对熟悉 K9s 快捷键体系的用户而言,这是一次"运维不离开 TUI"的体验升级。

二、核心操作:Node 视图中的三个维护快捷键

进入 Node 视图(在 K9s 中输入:node回车),选中一个或多个节点后即可使用以下快捷键。发行说明(v0.17.6)原始定义如下:

快捷键操作说明
cCordon 封锁节点标记节点为不可调度(SchedulingDisabled),弹出确认对话框
uUncordon 解除封锁恢复节点可调度状态,弹出确认对话框
dDrain 排水驱逐节点上所有 Pod,弹出参数配置对话框

需要注意:在当前版本的 K9s 源码中,Drain 操作已绑定到r键(因为d在多数资源视图中被 "Describe" 占用),Cordon 为c、Uncordon 为u保持不变。这一点可以从 README 快捷键对照表 与 Node 视图按键绑定 中相互印证:

// internal/view/node.go -> bindDangerousKeys aa.Bulk(ui.KeyMap{ ui.KeyC: ui.NewKeyActionWithOpts("Cordon", n.toggleCordonCmd(true), ...), ui.KeyU: ui.NewKeyActionWithOpts("Uncordon", n.toggleCordonCmd(false), ...), ui.KeyR: ui.NewKeyActionWithOpts("Drain", n.drainCmd, ...), })

三个操作均支持多选批量执行:当同时选中多个节点时,确认对话框会显示(N) nodes的批量提示,例如 Drain 对话框标题会变为Drain (3) nodes?,实现一键对多个节点执行相同维护动作。

2.1 只读模式的保护

从 bindKeys 的实现可以看到,这三项维护能力只在非只读模式下绑定:

func (n *Node) bindKeys(aa *ui.KeyActions) { if !n.App().Config.IsReadOnly() { n.bindDangerousKeys(aa) } ... }

当 K9s 以只读模式(--readonly)启动或配置了只读上下文时,c/u/r不会出现在 Node 视图中,从入口层面杜绝误操作。

三、Cordon / Uncordon:确认对话框与底层实现

按下c或u后,toggleCordonCmd(cordon bool)会先弹出确认对话框(标题分别为 "Confirm Cordon" 与 "Confirm Uncordon"),单节点时提示Cordon <nodeName>?,多节点时提示Cordon (N) marked nodes?。用户点击确认后,K9s 通过 DAO 层的NodeMaintainer接口逐个节点执行操作。

该接口定义在 internal/dao/types.go#L91-L98:

type NodeMaintainer interface { // ToggleCordon toggles cordon/uncordon a node. ToggleCordon(path string, cordon bool) error // Drain drains the given node. Drain(path string, opts DrainOptions, w io.Writer) error }

3.1 ToggleCordon 的实现链

核心实现在 internal/dao/node.go#L41-L81,流程如下:

  1. 获取节点:FetchNode先通过CanI检查当前用户的 RBAC 权限(无权限直接报错 "user is not authorized to list nodes"),再读取节点对象;
  2. 构建 cordon helper:基于k8s.io/kubectl/pkg/drain的NewCordonHelperFromRuntimeObject构造操作助手;
  3. 状态检查:UpdateIfRequired(cordon)判断节点是否已处于目标状态——若节点已封锁再执行 cordon,会返回node is already cordoned;反之执行 uncordon 会返回node is already uncordoned。也就是说,该操作是幂等且有明确反馈的;
  4. 应用补丁:通过PatchOrReplace将spec.unschedulable字段以补丁方式写入集群。

四、Drain 排水:参数对话框与执行流程

Drain 是三类操作中参数最丰富的。按下r(早期版本为d)后,K9s 会弹出<Drain>模态对话框,由 internal/view/drain_dialog.go 的ShowDrain实现,字段与源码中的 DrainOptions 结构体一一对应:

对话框字段对应选项含义默认值
GracePeriodGracePeriodSeconds每个 Pod 的优雅终止宽限期(秒),-1表示不覆盖、沿用 Pod 自身配置-1
TimeoutTimeout驱逐操作的总超时时间(Go duration 格式,如5s、2m)5s
Ignore DaemonSetsIgnoreAllDaemonSets忽略 DaemonSet 管理的 Pod,不驱逐它们false
Delete EmptyDir DataDeleteEmptyDirData允许删除使用 emptyDir 卷的 Pod(数据会丢失,需谨慎)false
ForceForce强制删除无法优雅终止的 Podfalse
Disable EvictionDisableEviction禁用 Eviction API,回退到直接删除 Pod 的策略false

默认参数在 drainCmd 中初始化:

opts := dao.DrainOptions{ GracePeriodSeconds: -1, Timeout: 5 * time.Second, }

点击OK后进入执行阶段drainNode(internal/view/node.go#L109-L135):K9s 会先暂停 Node 视图的刷新、注入一个标题为Drain Progress的实时输出详情页,然后对选中的每个节点依次调用 DAO 层的Drain,把 kubectl drain 的详细输出流式写入该页面;全部完成后刷新视图。

4.1 Drain 的底层执行链

internal/dao/node.go#L98-L131 中的Drain实现了一个重要的安全设计——自动先封锁再排水:

  1. ensureCordoned(path)读取节点spec.unschedulable判断是否已封锁;
  2. 若尚未封锁,自动调用ToggleCordon(path, true)先完成封锁,避免 drain 过程中新的 Pod 被调度上来;
  3. 通过toDrainHelper将DrainOptions映射为k8s.io/kubectl/pkg/drain.Helper(复用 kubectl 官方实现,行为与kubectl drain完全一致);
  4. GetPodsForDeletion收集节点上待驱逐的 Pod 列表,若收集过程出现错误(如存在未镜像的 local PV 等),会逐条打印错误并汇总返回;
  5. DeleteOrEvictPods按 Eviction API 优先、删除兜底的策略驱逐 Pod;
  6. 完成后输出Node <name> drained!到进度页面。

五、封锁状态的可视化反馈

Cordon 之后,节点在 Node 视图中会立即出现明显的视觉状态。渲染层 internal/render/node.go 的diagnose通过检查节点状态数组中的SchedulingDisabled与Ready来判定节点状况,若节点已封锁则返回node is cordoned错误标记;随后 ColorerFunc 会将该行VALID列标记为挂起色(PendingColor),让封锁节点在列表中一眼可辨。

这一诊断逻辑有对应的单元测试验证,见 internal/render/node_int_test.go 的TestNode_diagnose:输入["SchedulingDisabled", "Ready"]状态数组断言返回cordonErr,输入["NotReady"]断言返回notReadyErr,覆盖了"封锁且就绪""未就绪""同时存在"等典型组合。

六、运维实战建议

  1. 先评估再封锁:执行c前建议先用y查看节点 YAML、用 Enter 键进入showPods(K9s 会自动按spec.nodeName=<节点名>过滤该节点上的 Pod),确认负载情况;
  2. Drain 默认值偏保守:默认Timeout=5s对大规模节点可能不足,可在对话框内调整为更长的超时;涉及 emptyDir 或 DaemonSet 的工作负载时按需勾选Delete EmptyDir Data与Ignore DaemonSets;
  3. 利用批量操作:同时选中多个待维护节点(空格多选)后执行 drain,K9s 会逐个执行并把每个节点的进度输出到Drain Progress页,便于在一个界面内观察完整排水过程;
  4. 只读环境自动禁用:在只读模式下这三项快捷键不会出现,天然防止误操作,适合告警大屏、演示等只读场景。

七、总结

K9s v0.17.6 把kubectl cordon / uncordon / drain三条命令完整封装进 Node 视图的 TUI 交互中:确认对话框降低误操作风险,Drain 参数对话框保留 kubectl 的完整语义(底层复用k8s.io/kubectl/pkg/drain),Drain Progress实时输出让长耗时排水过程透明可见,封锁节点的颜色标记则提供了持续的状态反馈。配合多选批量执行与只读模式保护,K9s 在节点维护这条高频运维路径上已经可以做到"全程不离开终端"。

  • 云原生
  • 容器编排
  • CLI
  • 运维

【免费下载链接】k9s

🐶 Kubernetes CLI To Manage Your Clusters In Style!

项目地址:https://gitcode.com/GitHub_Trending/k9s/k9s
点击查看免费下载
上一篇:SysDVR 终极指南:免费实现 Switch 游戏画面无线传输的完整方案
下一篇:MissionControl完整教程:如何在Switch上免费使用各类蓝牙控制器

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询