元鉴
返回中文阅读流

Kubernetes Blog

Kubernetes v1.36:细粒度 Kubelet API 授权升至 GA

Kubernetes v1.36 中,细粒度 kubelet API 授权升至 GA,功能门控锁定启用,可为 kubelet HTTPS API 提供更精准的最小权限控制。

中文内容

已翻译official company source英文原文2026-04-24

Kubernetes v1.36:细粒度 Kubelet API 授权升至 GA

By Vinayak Goyal (Google) | Friday, April 24, 2026

我们谨代表 Kubernetes SIG Auth 和 SIG Node,高兴地宣布:细粒度 kubelet API 授权已在 Kubernetes v1.36 中升至通用可用(GA)!

KubeletFineGrainedAuthz 功能门控最初在 Kubernetes v1.32 中作为可选启用的 alpha 功能引入,随后在 v1.33 中升至 beta(默认启用)。现在,该功能已通用可用,且功能门控已锁定为启用。此功能可对 kubelet 的 HTTPS API 实现更精准的最小权限访问控制,取代在常见监控和可观测性用例中授予过于宽泛的 nodes/proxy 权限的需求。

动机:nodes/proxy 问题

kubelet 暴露了一个 HTTPS 端点,其中包含多个 API,可访问敏感程度不同的数据,包括 pod 列表、节点指标、容器日志,以及尤其关键的在运行中容器内执行命令的能力。

在此功能之前,kubelet 授权使用的是粗粒度模型。启用 webhook 授权时,几乎所有 kubelet API 路径都会映射到单一的 nodes/proxy 子资源。这意味着,任何需要从 kubelet 读取指标或健康状态的工作负载都需要 nodes/proxy 权限,而这一权限同样会授予在该节点上运行的任意容器中执行任意命令的能力。

这有什么问题?

向监控代理、日志收集器或健康检查工具授予 nodes/proxy 违反了最小权限原则。如果这些工作负载中的任何一个遭到入侵,攻击者就会获得在该节点上每个容器中运行命令的能力。nodes/proxy 权限实际上是一种节点级超级用户能力,广泛授予它会显著扩大安全事件的影响范围。

多年来,社区一直充分认识到这一问题(见 kubernetes/kubernetes#83465),它也是此增强 KEP-2862 背后的主要动因。

nodes/proxy GET WebSocket RCE 风险

情况比乍看之下更严重。安全研究人员在 2026 年初证明,仅 nodes/proxy GET 这一通常授予监控工具的最小只读权限,就可被滥用于在可达节点上的任意 pod 中执行命令。

根本原因在于 WebSocket 连接的工作方式与 kubelet 将 HTTP 方法映射到 RBAC 动词的方式不匹配。WebSocket 协议(RFC 6455)要求初始连接握手使用 HTTP GET 请求。kubelet 将此 GET 映射为 RBAC 的 get 动词,并在未执行二次检查以确认随后写操作也具备 CREATE 权限的情况下授权该请求。使用 websocat 这样的 WebSocket 客户端,攻击者可以直接访问 kubelet 在 10250 端口上的 /exec 端点并执行任意命令:

websocat --insecure \
  --header "Authorization: Bearer $TOKEN" \
  --protocol v4.channel.k8s.io \
  "wss://$NODE_IP:10250/exec/default/nginx/nginx?output=1&error=1&command=id"

uid=0(root) gid=0(root) groups=0(root)

细粒度 kubelet 授权:工作方式

借助 KubeletFineGrainedAuthz,kubelet 现在会在回退到 nodes/proxy 子资源之前,先执行一次额外且更具体的授权检查。若干常用 kubelet API 路径会被映射到各自专用的子资源:

kubelet APIResourceSubresource/stats/*nodesstats/metrics/*nodesmetrics/logs/*nodeslog/podsnodespods, proxy/runningPods/nodespods, proxy/healthznodeshealthz, proxy/configznodesconfigz, proxy/spec/*nodesspec/checkpoint/*nodescheckpointall othersnodesproxy

对于现在拥有细粒度子资源的端点(/pods、/runningPods/、/healthz、/configz),kubelet 会首先针对特定子资源发送 SubjectAccessReview。如果该检查成功,请求即被授权。如果失败,kubelet 会为了向后兼容而使用粗粒度的 nodes/proxy 子资源重试。

这种双重检查方法确保了平滑迁移路径。已有 nodes/proxy 权限的现有工作负载会继续工作,而新的部署可以从第一天起采用最小权限访问。

这在实践中意味着什么

以需要从 kubelet 抓取 /metrics 的 Prometheus node exporter 或监控 DaemonSet 为例。此前,你需要像这样的 RBAC ClusterRole:

# Old approach: overly broad
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/proxy"]
  verbs: ["get"]

这会授予监控代理远超其所需的访问权限。通过细粒度授权,你现在可以精确限定权限范围:

# New approach: least privilege
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/metrics", "nodes/stats"]
  verbs: ["get"]

监控代理现在可以从 kubelet 读取指标和统计信息,而永远无法在容器中执行命令。

更新后的 system:kubelet-api-admin ClusterRole

启用 RBAC 授权时,内置的 system:kubelet-api-admin ClusterRole 会自动更新,以包含所有新的细粒度子资源权限。这确保已经使用该角色的集群管理员,包括 API server 的 kubelet 客户端,无需任何手动配置更改即可继续拥有完整访问权限。

该角色现在包含以下权限:

  • 正文:nodes/proxy
  • 正文:nodes/stats
  • 正文:nodes/metrics
  • 正文:nodes/log
  • 正文:nodes/spec
  • 正文:nodes/checkpoint
  • 正文:nodes/configz
  • 正文:nodes/healthz
  • 正文:nodes/pods

升级注意事项

由于 kubelet 会执行双重授权检查(先细粒度检查,然后回退到 nodes/proxy),对大多数集群而言,升级到 v1.36 应该是无缝的:

  • 已有 nodes/proxy 权限的现有工作负载无需更改即可继续工作。回退到 nodes/proxy 可确保向后兼容。
  • API server 始终通过 system:kubelet-api-admin 拥有 nodes/proxy 权限,因此无论功能门控状态如何,kube-apiserver 到 kubelet 的通信都不受影响。
  • 混合版本集群会被妥善处理。如果某个 kubelet 支持细粒度授权而 API server 不支持(或反之),nodes/proxy 权限会作为回退。

验证该功能已启用

你可以通过检查 kubelet 指标端点,确认某个给定节点上该功能是否处于活动状态。由于 10250 端口上的指标端点需要授权,你首先需要为发起请求的 pod 或 ServiceAccount 创建适当的 RBAC 绑定。

步骤 1:创建 ServiceAccount 和 ClusterRole

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubelet-metrics-checker
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubelet-metrics-reader
rules:
- apiGroups: [""]
  resources: ["nodes/metrics"]
  verbs: ["get"]

步骤 2:将 ClusterRole 绑定到 ServiceAccount

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubelet-metrics-checker
subjects:
- kind: ServiceAccount
  name: kubelet-metrics-checker
  namespace: default
roleRef:
  kind: ClusterRole
  name: kubelet-metrics-reader
  apiGroup: rbac.authorization.k8s.io

应用这两个清单:

kubectl apply -f serviceaccount.yaml
kubectl apply -f clusterrole.yaml
kubectl apply -f clusterrolebinding.yaml

步骤 3:使用该 ServiceAccount 运行一个 pod,并检查功能标志

kubectl run kubelet-check \
  --image=curlimages/curl \
  --serviceaccount=kubelet-metrics-checker \
  --restart=Never \
  --rm -it \
  -- sh

然后在 pod 内部获取节点 IP,并查询指标端点:

# Get the token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

# Query the kubelet metrics and filter for the feature gate
curl -sk \
  --header "Authorization: Bearer $TOKEN" \
  https://$NODE_IP:10250/metrics \
  | grep kubernetes_feature_enabled \
  | grep KubeletFineGrainedAuthz

如果该功能已启用,你应当会看到类似输出:

kubernetes_feature_enabled{name="KubeletFineGrainedAuthz",stage="GA"} 1
注意:将 $NODE_IP 替换为你要检查的节点的 IP 地址。你可以使用 kubectl get nodes -o wide 获取节点 IP。

从 alpha 到 GA 的历程

ReleaseStageDetailsv1.32AlphaFeature gate KubeletFineGrainedAuthz introduced, disabled by defaultv1.33BetaEnabled by default; fine-grained checks for /pods, /runningPods/, /healthz, /configzv1.36GAFeature gate locked to enabled; fine-grained kubelet authorization is always active

下一步是什么?

随着细粒度 kubelet 授权现已 GA,Kubernetes 社区可以开始建议并最终强制要求监控和可观测性工作负载使用特定子资源,而不是 nodes/proxy。研究显示 nodes/proxy GET 可通过 WebSocket 协议被滥用于未记录的远程代码执行,这凸显了迁移的紧迫性。数十个广泛部署的 Helm chart 的默认 RBAC 配置中都存在这一风险。随着时间推移,我们预计:

  • 生态系统采用:Prometheus、Datadog agents 以及其他 DaemonSet 等监控工具可以更新其默认 RBAC 配置,改用 nodes/metrics、nodes/stats 和 nodes/pods,而不是 nodes/proxy。这将直接消除这些工作负载的 WebSocket RCE 攻击面。
  • 策略执行:准入控制器和策略引擎可以标记或拒绝在存在细粒度替代方案时仍授予 nodes/proxy 的 RBAC 绑定,帮助组织大规模采用最小权限访问。
  • 弃用路径:随着采用率提高,nodes/proxy 最终可能会在监控用例中被弃用,从而进一步降低 Kubernetes 集群的攻击面。

参与进来

此增强由 SIG Auth 和 SIG Node 推动。如果你有兴趣为 Kubernetes 的安全和授权功能做出贡献,欢迎加入我们:

  • 正文:SIG Auth
  • 正文:SIG Node
  • Slack:#sig-auth 和 #sig-node
  • KEP-2862:细粒度 Kubelet API 授权

我们期待听到你对这一功能的反馈和使用经验!

  • ← 上一篇
  • 下一篇 →
Last modified April 24, 2026 at 1:50 PM PST: release two feature blogs (dbd16099df)

原文标题

Kubernetes v1.36: Fine-Grained Kubelet API Authorization Graduates to GA