本文主要是介绍Kubernetes 1.31 新功能: 细粒度补充组控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这篇文章讨论了 Kubernetes 1.31 中的一个新特性,用于改善 Pod 中容器的补充组(Fine-grained SupplementalGroups control)处理。
动机:在容器镜像中的 /etc/group 定义的隐式组成员身份
尽管这种行为可能并不受许多 Kubernetes 集群用户/管理员的欢迎,但 Kubernetes 默认情况下会将 Pod 中的组信息与容器镜像中 /etc/group 定义的信息进行合并。
让我们来看一个例子,下面的 Pod 在其安全上下文中指定了 runAsUser=1000、runAsGroup=3000 和 supplementalGroups=4000。
apiVersion: v1
kind: Pod
metadata:name: implicit-groups
spec:securityContext:runAsUser: 1000runAsGroup: 3000supplementalGroups: [4000]containers:- name: ctrimage: registry.k8s.io/e2e-test-images/agnhost:2.45command: [ "sh", "-c", "sleep 1h" ]securityContext:allowPrivilegeEscalation: false
在 ctr 容器中执行 id 命令的结果是什么?
# 创建 Pod:
$ kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml# 验证 Pod 的容器正在运行:
$ kubectl get pod implicit-groups# 检查 id 命令
$ kubectl exec implicit-groups -- id
然后,输出应该类似于这样:
uid=1000 gid=3000 groups=3000,4000,50000
即使在 Pod 的清单中根本没有定义 50000,补充组中的组 ID 50000 来自哪里?答案是容器镜像中的 /etc/group 文件。
检查容器镜像中的 /etc/group 的内容应该显示如下:
$ kubectl exec implicit-groups -- cat /etc/group
...
user-defined-in-image:x:1000:
group-defined-in-image:x:50000:user-defined-in-image
啊哈!容器的主用户 1000 在最后一个条目中属于组 50000。
因此,容器镜像中为容器的主用户定义的组成员身份被隐式地合并到来自 Pod 的信息中。请注意,这是当前 CRI 实现从 Docker 继承的设计决策,社区直到现在才真正重新考虑它。
这有什么问题?
容器镜像中的 /etc/group 隐式合并的组信息可能会引起一些关注,特别是在访问卷时(详见 kubernetes/kubernetes#112879),因为文件权限由 Linux 中的 uid/gid 控制。更糟糕的是,来自 /etc/group 的隐式 gids 无法被任何策略引擎检测/验证,因为在清单中没有隐式组信息的线索。这也可能是 Kubernetes 安全方面的一个关注点。
为了解决上述问题,Kubernetes 1.31 引入了 Pod 的 .spec.securityContext 中的新字段 supplementalGroupsPolicy。
此字段提供了一种控制如何计算 Pod 中容器进程的补充组的方法。可用的策略如下:
-
合并:容器的主用户在
/etc/group中定义的组成员身份将被合并。如果没有指定,将应用此策略(即向后兼容的当前行为)。 -
严格:它只附加在
fsGroup、supplementalGroups或runAsGroup字段中指定的组 ID 作为容器进程的补充组。这意味着容器镜像中为主用户定义的任何组成员身份都不会被合并。
让我们看看 Strict 策略是如何工作的。
# 创建 Pod:
$ kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml# 验证 Pod 的容器正在运行:
$ kubectl get pod strict-supplementalgroups-policy# 检查进程身份:
kubectl exec -it strict-supplementalgroups-policy -- id
输出应该类似于这样:
uid=1000 gid=3000 groups=3000,4000
你可以看到 Strict 策略可以排除 groups 中的组 50000!
因此,确保 supplementalGroupsPolicy: Strict(由某些策略机制强制执行)有助于防止 Pod 中的隐式补充组。
Pod 状态中的附加进程身份
此功能还通过 .status.containerStatuses[].user.linux 字段公开了附加到容器的第一个进程的进程身份。这将有助于查看是否附加了隐式组 ID。
...
status:containerStatuses:- name: ctruser:linux:gid: 3000supplementalGroups:- 3000- 4000uid: 1000
...
特性可用性
要启用 supplementalGroupsPolicy 字段,必须使用以下组件:
- Kubernetes:v1.31 或更高版本,启用了
SupplementalGroupsPolicy特性门控。截至 v1.31,该门控标记为 alpha。 - CRI 运行时:
- containerd:v2.0 或更高版本
- CRI-O:v1.31 或更高版本
你可以在节点的 .status.features.supplementalGroupsPolicy 字段中查看特性是否受支持。
apiVersion: v1
kind: Node
...
status:features:supplementalGroupsPolicy: true

这篇关于Kubernetes 1.31 新功能: 细粒度补充组控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!