包阅导读总结
1.
关键词:Kubernetes 1.31、SupplementalGroups、控制、策略、容器
2.
总结:本文讨论了 Kubernetes 1.31 中对容器内补充组处理的改进,包括默认的隐式组合并问题及新引入的控制策略,还介绍了相关特征的可用性和未来期望。
3.
主要内容:
– Kubernetes 1.31 之前
– 默认会将 Pod 与容器镜像中 `/etc/group` 定义的组信息合并。
– 问题
– 隐式合并的组信息在访问卷等方面可能引起问题。
– 无法被策略引擎检测和验证,影响安全性。
– Kubernetes 1.31 新特性
– 引入 `supplementalGroupsPolicy` 字段,有 `Merge`(默认,合并组信息)和 `Strict`(仅附加指定组 ID)两种策略。
– 暴露容器状态中附加的进程标识。
– 特征可用性
– 相关组件需满足特定版本要求。
– 未来期望
– 该功能有望晋升为 beta 版和通用版。
思维导图:
文章地址:https://kubernetes.io/blog/2024/08/22/fine-grained-supplementalgroups-control/
文章来源:kubernetes.io
作者:Kubernetes Blog
发布时间:2024/8/22 0:00
语言:英文
总字数:907字
预计阅读时间:4分钟
评分:86分
标签:Kubernetes,安全,容器管理,组策略,Pod 安全
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
Kubernetes 1.31: Fine-grained SupplementalGroups control
By Shingo Omura (Woven By Toyota) |
This blog discusses a new feature in Kubernetes 1.31 to improve the handling of supplementary groups in containers within Pods.
Motivation: Implicit group memberships defined in /etc/group
in the container image
Although this behavior may not be popular with many Kubernetes cluster users/admins, kubernetes, by default, merges group information from the Pod with information defined in /etc/group
in the container image.
Let’s see an example, below Pod specifies runAsUser=1000
, runAsGroup=3000
and supplementalGroups=4000
in the Pod’s security context.
apiVersion: v1kind: Podmetadata: name: implicit-groupsspec: securityContext: runAsUser: 1000 runAsGroup: 3000 supplementalGroups: [4000] containers: - name: ctr image: registry.k8s.io/e2e-test-images/agnhost:2.45 command: [ "sh", "-c", "sleep 1h" ] securityContext: allowPrivilegeEscalation: false
What is the result of id
command in the ctr
container?
# Create the Pod:$ kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml# Verify that the Pod's Container is running:$ kubectl get pod implicit-groups# Check the id command$ kubectl exec implicit-groups -- id
Then, output should be similar to this:
uid=1000 gid=3000 groups=3000,4000,50000
Where does group ID 50000
in supplementary groups (groups
field) come from, even though 50000
is not defined in the Pod’s manifest at all? The answer is /etc/group
file in the container image.
Checking the contents of /etc/group
in the container image should show below:
$ kubectl exec implicit-groups -- cat /etc/group...user-defined-in-image:x:1000:group-defined-in-image:x:50000:user-defined-in-image
Aha! The container’s primary user 1000
belongs to the group 50000
in the last entry.
Thus, the group membership defined in /etc/group
in the container image for the container’s primary user is implicitly merged to the information from the Pod. Please note that this was a design decision the current CRI implementations inherited from Docker, and the community never really reconsidered it until now.
What’s wrong with it?
The implicitly merged group information from /etc/group
in the container image may cause some concerns particularly in accessing volumes (see kubernetes/kubernetes#112879 for details) because file permission is controlled by uid/gid in Linux. Even worse, the implicit gids from /etc/group
can not be detected/validated by any policy engines because there is no clue for the implicit group information in the manifest. This can also be a concern for Kubernetes security.
Fine-grained SupplementalGroups control in a Pod: SupplementaryGroupsPolicy
To tackle the above problem, Kubernetes 1.31 introduces new field supplementalGroupsPolicy
in Pod’s .spec.securityContext
.
This field provies a way to control how to calculate supplementary groups for the container processes in a Pod. The available policy is below:
-
Merge: The group membership defined in
/etc/group
for the container’s primary user will be merged. If not specified, this policy will be applied (i.e. as-is behavior for backword compatibility). -
Strict: it only attaches specified group IDs in
fsGroup
,supplementalGroups
, orrunAsGroup
fields as the supplementary groups of the container processes. This means no group membership defined in/etc/group
for the container’s primary user will be merged.
Let’s see how Strict
policy works.
apiVersion: v1kind: Podmetadata: name: strict-supplementalgroups-policyspec: securityContext: runAsUser: 1000 runAsGroup: 3000 supplementalGroups: [4000] supplementalGroupsPolicy: Strict containers: - name: ctr image: registry.k8s.io/e2e-test-images/agnhost:2.45 command: [ "sh", "-c", "sleep 1h" ] securityContext: allowPrivilegeEscalation: false
# Create the Pod:$ kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml# Verify that the Pod's Container is running:$ kubectl get pod strict-supplementalgroups-policy# Check the process identity:kubectl exec -it strict-supplementalgroups-policy -- id
The output should be similar to this:
uid=1000 gid=3000 groups=3000,4000
You can see Strict
policy can exclude group 50000
from groups
!
Thus, ensuring supplementalGroupsPolicy: Strict
(enforced by some policy mechanism) helps prevent the implicit supplementary groups in a Pod.
Note:
Actually, this is not enough because container with sufficient privileges / capability can change its process identity. Please see the following section for details.
Attached process identity in Pod status
This feature also exposes the process identity attached to the first container process of the containervia .status.containerStatuses[].user.linux
field. It would be helpful to see if implicit group IDs are attached.
...status: containerStatuses: - name: ctr user: linux: gid: 3000 supplementalGroups: - 3000 - 4000 uid: 1000...
Note:
Please note that the values in
status.containerStatuses[].user.linux
field is
the firstly attached
process identity to the first container process in the container. If the container has sufficient privilegeto call system calls related to process identity (e.g.
setuid(2)
,
setgid(2)
or
setgroups(2)
, etc.), the container process can change its identity. Thus, the
actual
process identity will be dynamic.
Feature availability
To enable supplementalGroupsPolicy
field, the following components have to be used:
- Kubernetes: v1.31 or later, with the
SupplementalGroupsPolicy
feature gate enabled. As of v1.31, the gate is marked as alpha. - CRI runtime:
- containerd: v2.0 or later
- CRI-O: v1.31 or later
You can see if the feature is supported in the Node’s .status.features.supplementalGroupsPolicy
field.
apiVersion: v1kind: Node...status: features: supplementalGroupsPolicy: true
What’s next?
Kubernetes SIG Node hope – and expect – that the feature will be promoted to beta and eventuallygeneral availability (GA) in future releases of Kubernetes, so that users no longer need to enablethe feature gate manually.
Merge
policy is applied when supplementalGroupsPolicy
is not specified, for backwards compatibility.
How can I learn more?
How to get involved?
This feature is driven by the SIG Node community. Please join us to connect withthe community and share your ideas and feedback around the above feature andbeyond. We look forward to hearing from you!