Kubernetes 1.31 新功能: 细粒度补充组控制

本文介绍了 Kubernetes 1.31 版本中的一个新特性,它可以帮助我们更细致地控制 Pod 里容器的补充组。之前,Kubernetes 会自动把 Pod 里设置的组信息和容器镜像里的 /etc/group 文件中的组信息合并起来,但这种做法有时候并不是管理员想要的。

举个例子,下面创建一个 Pod,并设置了运行用户是 1000,主组是 3000,还指定了一个补充组 4000。配置如下:

apiVersion: v1
kind: Pod
metadata:
  name: implicit-groups
spec:
  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

按照这个配置创建 Pod 后,如果你在容器里执行 id 命令,会发现输出中除了我们设置的组,还多了一个 50000 的组。这个 50000 组就是从 /etc/group 文件中来的,即使你在 Pod 的配置里没有提到它。

执行命令查看输出:

# 创建 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

如果你想查看 /etc/group 文件里的内容,可以执行:

$ kubectl exec implicit-groups -- cat /etc/group

你会发现容器的主用户 1000 属于组 50000。这就是为什么即使没有在 Pod 配置中明确指定,这个组也会出现的原因。

这个自动合并的行为是从 Docker 继承来的,直到现在社区才开始重新考虑。通过 Kubernetes 1.31 的新特性,我们可以更精细地控制这个行为,以避免潜在的安全问题和权限管理上的混乱。

这有什么问题?

在容器镜像中,/etc/group 文件中的组信息可能会被隐式合并,这在某些情况下可能会引起安全关注,特别是在访问卷时(详见 kubernetes/kubernetes#112879),涉及到文件权限时。这是因为Linux系统的文件权限是由用户ID(uid)和组ID(gid)控制的。更让人担忧的是,这些隐式组(gids)不会被任何策略引擎检测或验证,因为它们在配置清单中没有明确的记录。

为了解决这个问题,Kubernetes 1.31版本引入了一个新字段supplementalGroupsPolicy,它位于Pod的.spec.securityContext中。这个字段允许你控制Pod中容器进程的补充组是如何计算的。有两种策略可用:

  1. 合并:这是默认策略,容器的主用户在/etc/group中定义的组成员身份会被合并。
  2. 严格:只有那些在fsGroupsupplementalGroupsrunAsGroup字段中明确指定的组ID会被作为容器进程的补充组。这意味着,容器镜像中为主用户定义的任何组成员身份都不会被合并。

如果你想看看Strict策略是如何工作的,可以按照以下步骤操作:

  1. 创建一个Pod,使用以下命令:
    kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml
    
  2. 验证Pod的容器是否正在运行:
    kubectl get pod strict-supplementalgroups-policy
    
  3. 检查进程身份:
    kubectl exec -it strict-supplementalgroups-policy -- id
    
    输出应该显示类似于:
    uid=1000 gid=3000 groups=3000,4000
    
    这表明Strict策略成功地排除了组50000

通过确保supplementalGroupsPolicy: Strict被正确设置(可能由某些策略机制强制执行),可以帮助防止Pod中的隐式补充组问题。

Pod 状态中的附加进程身份

在Kubernetes中,Pod状态信息的.status.containerStatuses[].user.linux字段提供了一个查看容器进程身份的窗口,这对于理解容器中运行的进程所具有的用户和组权限非常有用。这个字段显示了附加到容器的第一个进程的用户和组信息,包括UID(用户ID)、GID(主组ID)和补充组。

通过查看这个字段,你可以确认容器进程是否具有预期的用户和组权限,这有助于确保容器的安全性和正确的权限管理。例如,如果你看到以下输出:

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

这意味着名为ctr的容器的第一个进程具有以下身份:

  • UID: 1000
  • GID: 3000
  • 补充组: 3000, 4000

这个信息可以帮助你验证是否正确地应用了安全策略,比如supplementalGroupsPolicy。如果策略设置为Strict,那么只有明确指定的组ID才会被附加为补充组,这有助于防止未授权的访问和潜在的安全风险。

特性可用性

要充分利用Kubernetes的supplementalGroupsPolicy功能,确保你的环境满足以下要求是非常重要的。

必需的组件和版本

  1. Kubernetes: 需要使用v1.31或更高版本,并且需要启用SupplementalGroupsPolicy特性门控。在v1.31版本中,这个特性是标记为alpha的,意味着它可能还在开发中,可能需要额外的配置或注意。

  2. CRI运行时:

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

检查特性支持

你可以通过查看节点的.status.features.supplementalGroupsPolicy字段来确认你的节点是否支持supplementalGroupsPolicy特性。如果该字段显示为true,则表示该特性在你的节点上是受支持的。你可以使用以下命令来查看节点的状态:

kubectl get node -o yaml

在输出中,查找类似于以下的内容:

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

如果supplementalGroupsPolicy字段显示为true,那么你的环境已经准备好使用这个特性。

启用特性

如果你的环境还未启用SupplementalGroupsPolicy特性,你可能需要在Kubernetes的配置文件中启用它。这通常涉及到编辑Kubernetes的启动参数,确保包含--feature-gates=SupplementalGroupsPolicy=true

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值