元鉴
返回中文阅读流

Kubernetes Blog

Kubernetes v1.35:细粒度补充组控制进入 GA

Kubernetes SIG Node 宣布,细粒度补充组控制在 Kubernetes v1.35 中进入 GA,提升 Linux 容器补充组管理与安全透明度。

中文内容

已翻译official company source英文原文2025-12-23

Kubernetes v1.35:细粒度补充组控制进入 GA

By Shingo Omura (LY Corporation) | Tuesday, December 23, 2025

我们代表 Kubernetes SIG Node,很高兴宣布细粒度补充组控制在 Kubernetes v1.35 中进入 General Availability(GA)!

新的 Pod 字段 supplementalGroupsPolicy 最初作为 Kubernetes v1.31 的可选启用 alpha 特性引入,随后在 v1.33 中升为 beta。现在,该特性已正式普遍可用。此特性允许你对 Linux 容器中的补充组实施更精确的控制,从而增强安全态势,尤其是在访问卷时。此外,它还提高了容器中 UID/GID 详细信息的透明度,提供更好的安全监督。

如果你计划从 v1.32 或更早版本升级集群,请注意自 beta(v1.33)以来引入了一些行为上的破坏性变更。更多详细信息,请参阅上一篇关于升为 beta 的博客中“beta 中引入的行为变更”和“升级注意事项”部分。

动机:容器镜像中 /etc/group 定义的隐式组成员关系

尽管大多数 Kubernetes 集群管理员/用户可能并不了解这一点,但默认情况下,Kubernetes 会将 Pod 中的组信息与容器镜像中 /etc/group 定义的信息合并。

下面是一个示例:一个 Pod 清单在 Pod 的安全上下文中指定了 spec.securityContext.runAsUser: 1000、spec.securityContext.runAsGroup: 3000 和 spec.securityContext.supplementalGroups: 4000。

apiVersion: v1
kind: Pod
metadata:
  name: implicit-groups-example
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    supplementalGroups: [4000]
  containers:
  - name: example-container
    image: registry.k8s.io/e2e-test-images/agnhost:2.45
    command: [ "sh", "-c", "sleep 1h" ]
    securityContext:
      allowPrivilegeEscalation: false

在 example-container 容器中执行 id 命令会得到什么结果?输出应类似如下:

uid=1000 gid=3000 groups=3000,4000,50000

即使 50000 根本没有在 Pod 清单中定义,补充组(groups 字段)中的组 ID 50000 从何而来?答案是容器镜像中的 /etc/group 文件。

检查容器镜像中 /etc/group 的内容,会看到类似以下内容:

user-defined-in-image:x:1000:
group-defined-in-image:x:50000:user-defined-in-image

这表明容器的主用户 1000 在最后一项中属于组 50000。

因此,容器镜像中 /etc/group 为容器主用户定义的组成员关系,会被隐式合并到来自 Pod 的信息中。请注意,这是当前 CRI 实现从 Docker 继承而来的设计决策,社区直到现在才真正重新审视它。

这有什么问题?

从容器镜像的 /etc/group 隐式合并的组信息会带来安全风险。由于 Pod 清单中没有这些隐式 GID 的记录,策略引擎无法检测或验证它们。这可能导致意外的访问控制问题,尤其是在访问卷时(详情见 kubernetes/kubernetes#112879),因为 Linux 中的文件权限由 UID/GID 控制。

Pod 中的细粒度补充组控制:supplementaryGroupsPolicy

为解决这个问题,Pod 的 .spec.securityContext 现在包含 supplementalGroupsPolicy 字段。

该字段允许你控制 Kubernetes 如何为 Pod 内的容器进程计算补充组。可用策略包括:

  • Merge:将合并容器主用户在 /etc/group 中定义的组成员关系。如果未指定,将应用此策略(即为向后兼容而保持原有行为)。
  • Strict:只有在 fsGroup、supplementalGroups 或 runAsGroup 中指定的组 ID 会作为补充组附加到容器进程。容器主用户在 /etc/group 中定义的组成员关系将被忽略。

下面说明 Strict 策略如何工作。以下 Pod 清单指定了 supplementalGroupsPolicy: Strict:

apiVersion: v1
kind: Pod
metadata:
  name: strict-supplementalgroups-policy-example
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    supplementalGroups: [4000]
    supplementalGroupsPolicy: Strict
  containers:
  - name: example-container
    image: registry.k8s.io/e2e-test-images/agnhost:2.45
    command: [ "sh", "-c", "sleep 1h" ]
    securityContext:
      allowPrivilegeEscalation: false

在 example-container 容器中执行 id 命令的结果应类似如下:

uid=1000 gid=3000 groups=3000,4000

可以看到,Strict 策略可以从 groups 中排除组 50000!

因此,确保 supplementalGroupsPolicy: Strict(由某种策略机制强制执行)有助于防止 Pod 中出现隐式补充组。

注意:

具有足够权限的容器可以更改其进程身份。supplementalGroupsPolicy 只影响初始进程身份。

请继续阅读以了解更多详细信息。

Pod 状态中附加的进程身份

此特性还通过 .status.containerStatuses[].user.linux 字段公开附加到容器第一个容器进程的进程身份。这有助于查看是否附加了隐式组 ID。

...
status:
  containerStatuses:
  - name: ctr
    user:
      linux:
        gid: 3000
        supplementalGroups:
        - 3000
        - 4000
        uid: 1000
...

注意:

请注意,status.containerStatuses[].user.linux 字段中的值是首次附加到容器内第一个容器进程的进程身份。如果容器具有足够权限来调用与进程身份相关的系统调用(例如 setuid(2)、setgid(2) 或 setgroups(2) 等),容器进程可以更改其身份。因此,实际进程身份将是动态的。

有几种方法可以限制容器中的这些权限。我们建议以下作为简单解决方案:

  • 在容器的 securityContext 中设置 privilege: false 和 allowPrivilegeEscalation: false,或
  • 使你的 Pod 符合 Pod Security Standard 中的 Restricted 策略。

此外,kubelet 无法观察 NRI 插件或容器运行时的内部工作情况。配置节点的集群管理员,或拥有本地管理员权限的高权限工作负载,可能会更改任何 Pod 的补充组。不过,这超出了 Kubernetes 控制范围,对于经过安全加固的节点而言不应成为担忧。

Strict 策略需要最新的容器运行时

高级容器运行时(例如 containerd、CRI-O)在计算将附加到容器的补充组 ID 时发挥关键作用。因此,supplementalGroupsPolicy: Strict 需要支持此特性的 CRI 运行时。旧行为(supplementalGroupsPolicy: Merge)可以与不支持此特性的 CRI 运行时配合使用,因为该策略完全向后兼容。

以下是一些支持此特性的 CRI 运行时,以及你需要运行的版本:

  • containerd:v2.0 或更高版本
  • CRI-O:v1.31 或更高版本

此外,你可以在 Node 的 .status.features.supplementalGroupsPolicy 字段中查看是否支持该特性。请注意,该字段不同于 KEP-5328: Node Declared Features(原 Node Capabilities)中引入的 status.declaredFeatures。

apiVersion: v1
kind: Node
...
status:
  features:
    supplementalGroupsPolicy: true

随着容器运行时普遍支持此特性,各种安全策略可能会开始强制执行更安全的 Strict 行为。最佳实践是确保你的 Pod 已为这种强制执行做好准备,并且所有补充组都在 Pod spec 中透明声明,而不是在镜像中声明。

参与进来

这一增强由 SIG Node 社区推动。欢迎加入我们,与社区建立联系,并分享你围绕上述特性及其他方面的想法和反馈。我们期待听到你的声音!

如何了解更多?

  • 为 Pod 或容器配置 Security Context,以了解 supplementalGroupsPolicy 的更多详细信息
  • KEP-3619:细粒度 SupplementalGroups 控制
  • ← 上一篇
  • 下一篇 →
Last modified January 03, 2026 at 3:42 PM PST: Reorganize 2025 blog content (0979e97a89)

原文标题

Kubernetes v1.35: Fine-grained Supplemental Groups Control Graduates to GA