NodeRestriction准入插件必须启用且Kubelet证书CN为system:node:、O为system:nodes,才能限制Kubelet仅操作自身节点;否则默认system:node ClusterRole赋予其对所有nodes的update/patch权限。

默认情况下,Kubelet 使用的客户端证书一旦被签发,就具备对整个 nodes 资源的 update 和 patch 权限(通过 system:node ClusterRole),这会导致一个节点上的 Kubelet 可以意外或恶意修改其他节点的状态(比如篡改 NodeStatus、删除他人节点对象)。必须启用 Node-Restriction 准入插件并配合适当的证书字段,才能让 Kubelet「只认自己」。
NodeRestriction 准入插件是否已启用
这是前提,没开等于白设。它不依赖 RBAC,而是由 API Server 在请求到达鉴权层之前拦截并校验 nodes 操作的合法性。
- 检查
kube-apiserver启动参数中是否包含--enable-admission-plugins=...,NodeRestriction,...(注意顺序无关,但必须显式列出) - 确认未在
--disable-admission-plugins中禁用它 - 重启
kube-apiserver后,可临时用非法操作验证:以某个 Kubelet 的 kubeconfig 尝试 patch 其他节点(如kubectl --kubeconfig=node-kubeconfig.kubeconfig patch node other-node --type=json -p='[{"op":"add","path":"/test","value":"x"}]'),应返回Forbidden: node "other-node" is not owned by the authenticated user
Kubelet 证书的 CN 和 O 字段必须符合约定
NodeRestriction 插件只放行满足特定格式的证书:CN 必须为 system:node:,O(Organization)必须为 system:nodes。它不看用户名或 token,只认证书里的这两个字段。
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
- 生成 Kubelet 证书时,
openssl req或 cfssl 的 CSR 中,CN必须设为system:node:ip-10-0-1-5.ec2.internal这类完整节点名(和hostname或--hostname-override值一致) -
O字段必须且只能是system:nodes;多加一个system:authenticated会直接被拒绝 - 如果用 kubeadm,它默认生成的证书符合要求;但自建 PKI 或用 Ansible 手动生成时极易漏掉
O=system:nodes,导致 Kubelet 启动后不断报错Forbidden: node "xxx" is not owned by the authenticated user
为什么 Kubelet 还是无法更新自己的状态?
即使准入插件开了、证书也对了,仍可能失败——常见于节点名解析不一致或 Node 对象被手动干预过。
- 检查 Kubelet 启动参数:
--hostname-override值是否与证书 CN 中的节点名完全一致(包括大小写、域名后缀);若不一致,NodeRestriction 会认为“你不是这个 node” - 运行
kubectl get node,确认-o yaml metadata.name和证书 CN 完全匹配;如果之前用kubectl delete node清过又重建,而新 Node 对象 name 不同,旧证书就作废了 - 确保没有手动给 Kubelet ServiceAccount 绑定额外的
nodes权限(比如误加了 ClusterRoleBinding 到system:node),NodeRestriction 不会阻止这种绕过,但会与预期行为冲突
真正卡点往往不在准入插件开关本身,而在证书 CN 和实际 Node 名之间的“一字之差”——比如少了个 .local,或者用了 IP 而不是 FQDN。NodeRestriction 的日志不会明确告诉你“CN 不匹配”,只会报“not owned”,得靠比对三处:证书、启动参数、Node 对象名。










