直接调用clientset.corev1().nodes().list(ctx, opts)获取node列表,需设limit防oom,必须传带超时的context,items中每个node的status.conditions需遍历判断ready状态,capacity和allocatable需用resource.mustparse解析。

如何用 client-go 获取 Node 列表
直接调用 CoreV1().Nodes().List() 即可拿到集群所有 Node 的结构化数据,但要注意 ListOptions 中不填参数会默认返回全部,生产环境建议加 Limit 或分页处理,避免一次性拉取过多节点导致内存暴涨或 API Server 压力升高。
常见错误是忽略 context 超时控制,导致网络卡顿时协程永久阻塞。务必传入带超时的 context.Context,例如 context.WithTimeout(context.Background(), 10*time.Second)。
-
Items字段是[]Node类型,每个Node包含Spec(配置)、Status(运行状态)、Labels和Taints - 若只关心 Ready 状态,可过滤
node.Status.Conditions中Type=="Ready"且Status=="True"的项 - 字段如
node.Status.Capacity和node.Status.Allocatable是字符串 map(如"cpu":"2"),需用resource.MustParse()解析为resource.Quantity才能做数值比较
删除 Node 必须先驱逐 Pod 吗
不是必须,但强烈建议。调用 CoreV1().Nodes().Delete(name, &metav1.DeleteOptions{}) 仅从 etcd 中移除 Node 对象,不会自动驱逐其上的 Pod;Kubelet 断连后,Pod 会逐步进入 Unknown 或 Terminating 状态,但可能长期滞留(尤其设置了 finalizers 或有 PDB 限制)。
正确做法是:先用 CoreV1().Pods("").DeleteCollection() 驱逐所有 Pod(注意命名空间设为 "" 表示全部),或更稳妥地调用 CoreV1().Nodes().Evict()(需启用 NodeRestriction 插件并配置 RBAC),再执行 Delete。
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
- 直接删 Node 后,DaemonSet 控制的 Pod 不会自动重建——因为 DaemonSet controller 只 watch Node 的
Ready条件变化,不 watch Node 删除事件 - 如果 Node 实际已宕机,删前跳过驱逐也无妨;但若只是临时下线,应优先用
taint隔离而非删除 -
DeleteOptions中设置GracePeriodSeconds: 0可绕过优雅终止,但对 Node 对象本身无实际意义(Node 无终止逻辑)
给 Node 打标签和加污点要用不同 client
标签(Labels)和污点(Taints)虽都作用于 Node,但更新方式完全不同:标签走标准的 Patch 或 Update,而污点必须用专门的 Patch 操作,不能用 Update 全量覆盖,否则会清空原有污点。
打标签示例:CoreV1().Nodes().Patch(context.TODO(), name, types.StrategicMergePatchType, []byte(`{"metadata":{"labels":{"env":"prod"}}}`), metav1.PatchOptions{});加污点则必须用 JSON Merge Patch 或 types.JSONPatchType,例如:CoreV1().Nodes().Patch(context.TODO(), name, types.JSONPatchType, []byte(`[{"op":"add","path":"/spec/taints","value":[{"key":"dedicated","value":"gpu","effect":"NoSchedule"}]}]`), metav1.PatchOptions{})。
- 标签支持
StrategicMergePatchType,可增量更新;污点字段spec.taints是 slice,用 Strategic Merge 会导致冲突,必须用 JSON Patch 显式操作数组 - 删除污点不能只发空数组,必须用
op:"remove"指定路径,例如"/spec/taints/0" - 修改标签后,调度器不会立刻重新调度已有 Pod,需配合
Pod.Spec.Tolerations或NodeSelector生效
为什么无法用 client-go “添加” Node
client-go 没有 Create Node 的合法路径——Kubernetes 设计上不允许通过 API 直接创建 Node 对象。Node 是由 kubelet 启动后向 API Server 自注册产生的,你看到的 Nodes().Create() 方法在 client-go 中存在,但调用会返回 405 Method Not Allowed 错误。
真实场景中“添加 Node”是指让一台新机器加入集群,这需要:在目标机器上安装 kubelet + kubeadm,然后执行 kubeadm join 命令。Go 程序能做的只是远程触发该命令(比如通过 SSH 调用 master 上的 kubeadm token create --print-join-command,再把结果下发到目标节点执行)。
- 试图用
Nodes().Create()伪造 Node 对象,会导致 kubelet 启动失败或与 API Server 状态不一致 - Node 对象的
UID、ResourceVersion、SelfLink等字段由 server 生成,客户端不可写 - 哪怕 patch 成功,kubelet 也会在下次心跳时覆盖
Status字段,导致信息失真
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










