- 云原生
- 容器编排
- CLI
- 运维
【免费下载链接】k9s
🐶 Kubernetes CLI To Manage Your Clusters In Style!
导读
本文聚焦 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)原始定义如下:
| 快捷键 | 操作 | 说明 |
|---|---|---|
c | Cordon 封锁节点 | 标记节点为不可调度(SchedulingDisabled),弹出确认对话框 |
u | Uncordon 解除封锁 | 恢复节点可调度状态,弹出确认对话框 |
d | Drain 排水 | 驱逐节点上所有 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,流程如下:
- 获取节点:
FetchNode先通过CanI检查当前用户的 RBAC 权限(无权限直接报错 "user is not authorized to list nodes"),再读取节点对象; - 构建 cordon helper:基于
k8s.io/kubectl/pkg/drain的NewCordonHelperFromRuntimeObject构造操作助手; - 状态检查:
UpdateIfRequired(cordon)判断节点是否已处于目标状态——若节点已封锁再执行 cordon,会返回node is already cordoned;反之执行 uncordon 会返回node is already uncordoned。也就是说,该操作是幂等且有明确反馈的; - 应用补丁:通过
PatchOrReplace将spec.unschedulable字段以补丁方式写入集群。
四、Drain 排水:参数对话框与执行流程
Drain 是三类操作中参数最丰富的。按下r(早期版本为d)后,K9s 会弹出<Drain>模态对话框,由 internal/view/drain_dialog.go 的ShowDrain实现,字段与源码中的 DrainOptions 结构体一一对应:
| 对话框字段 | 对应选项 | 含义 | 默认值 |
|---|---|---|---|
GracePeriod | GracePeriodSeconds | 每个 Pod 的优雅终止宽限期(秒),-1表示不覆盖、沿用 Pod 自身配置 | -1 |
Timeout | Timeout | 驱逐操作的总超时时间(Go duration 格式,如5s、2m) | 5s |
Ignore DaemonSets | IgnoreAllDaemonSets | 忽略 DaemonSet 管理的 Pod,不驱逐它们 | false |
Delete EmptyDir Data | DeleteEmptyDirData | 允许删除使用 emptyDir 卷的 Pod(数据会丢失,需谨慎) | false |
Force | Force | 强制删除无法优雅终止的 Pod | false |
Disable Eviction | DisableEviction | 禁用 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实现了一个重要的安全设计——自动先封锁再排水:
ensureCordoned(path)读取节点spec.unschedulable判断是否已封锁;- 若尚未封锁,自动调用
ToggleCordon(path, true)先完成封锁,避免 drain 过程中新的 Pod 被调度上来; - 通过
toDrainHelper将DrainOptions映射为k8s.io/kubectl/pkg/drain.Helper(复用 kubectl 官方实现,行为与kubectl drain完全一致); GetPodsForDeletion收集节点上待驱逐的 Pod 列表,若收集过程出现错误(如存在未镜像的 local PV 等),会逐条打印错误并汇总返回;DeleteOrEvictPods按 Eviction API 优先、删除兜底的策略驱逐 Pod;- 完成后输出
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,覆盖了"封锁且就绪""未就绪""同时存在"等典型组合。
六、运维实战建议
- 先评估再封锁:执行
c前建议先用y查看节点 YAML、用 Enter 键进入showPods(K9s 会自动按spec.nodeName=<节点名>过滤该节点上的 Pod),确认负载情况; - Drain 默认值偏保守:默认
Timeout=5s对大规模节点可能不足,可在对话框内调整为更长的超时;涉及 emptyDir 或 DaemonSet 的工作负载时按需勾选Delete EmptyDir Data与Ignore DaemonSets; - 利用批量操作:同时选中多个待维护节点(空格多选)后执行 drain,K9s 会逐个执行并把每个节点的进度输出到
Drain Progress页,便于在一个界面内观察完整排水过程; - 只读环境自动禁用:在只读模式下这三项快捷键不会出现,天然防止误操作,适合告警大屏、演示等只读场景。
七、总结
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!
相关推荐
weibaohui/kom节点维护:Drain与Cordon操作指南
weibaohui/kom节点维护:Drain与Cordon操作指南 引言:节点维护的挑战与解决方案 在Kubernetes集群运维中,节点维护是不可避免的常规
云原生后端MCP 服务Nomad节点排水(Drain)完整指南:实现零停机维护与升级运维
Nomad节点排水(Drain)完整指南:实现零停机维护与升级运维 Nomad 节点排水(Drain)是 HashiCorp Nomad 工作负载编排器的核心运
任务调度云原生运维后端MicroK8s节点维护:kubectl drain安全驱逐Pod
MicroK8s节点维护:kubectl drain安全驱逐Pod 你是否曾因节点维护导致业务中断?在Kubernetes集群管理中,安全驱逐Pod(Pod E
云原生容器编排边缘计算物联网运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考