本文主要是介绍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 新功能: 细粒度补充组控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!