From 655a0aaa3ef2303189d104328ced63f3e68d34ac Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 18 Sep 2024 09:32:58 +0800 Subject: [PATCH] [zh] Add a blog: 2024-08-22-Fine-grained-SupplementalGroups-control --- .../implicit-groups.yaml | 15 + .../index.md | 315 ++++++++++++++++++ .../strict-supplementalgroups-policy.yaml | 16 + 3 files changed, 346 insertions(+) create mode 100644 content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml create mode 100644 content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/index.md create mode 100644 content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml diff --git a/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml new file mode 100644 index 0000000000..2e50ed0104 --- /dev/null +++ b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml @@ -0,0 +1,15 @@ +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 diff --git a/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/index.md b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/index.md new file mode 100644 index 0000000000..96e4e9a4af --- /dev/null +++ b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/index.md @@ -0,0 +1,315 @@ +--- +layout: blog +title: 'Kubernetes 1.31:细粒度的 SupplementalGroups 控制' +date: 2024-08-22 +slug: fine-grained-supplementalgroups-control +author: > + Shingo Omura (Woven By Toyota) +translator: > + [Michael Yao](https://github.com/windsonsea) (DaoCloud) +--- + + + +本博客讨论了 Kubernetes 1.31 中的一项新特性,目的是改善处理 Pod 中容器内的附加组。 + + +## 动机:容器镜像中 `/etc/group` 中定义的隐式组成员关系 + +尽管这种行为可能并不受许多 Kubernetes 集群用户/管理员的欢迎, +但 Kubernetes 默认情况下会将 Pod 中的组信息与容器镜像中 `/etc/group` 中定义的信息进行**合并**。 + +让我们看一个例子,以下 Pod 在 Pod 的安全上下文中指定了 +`runAsUser=1000`、`runAsGroup=3000` 和 `supplementalGroups=4000`。 + +{{% code_sample file="implicit-groups.yaml" %}} + + +在 `ctr` 容器中执行 `id` 命令的结果是什么? + +```console +# 创建 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 +``` + + +输出应类似于: + +```none +uid=1000 gid=3000 groups=3000,4000,50000 +``` + + +尽管 `50000` 根本没有在 Pod 的清单中被定义,但附加组中的组 ID `50000`(`groups` 字段)是从哪里来的呢? +答案是容器镜像中的 `/etc/group` 文件。 + +检查容器镜像中 `/etc/group` 的内容应如下所示: + +```console +$ 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](https://issue.k8s.io/112879)), +因为在 Linux 中文件权限是通过 uid/gid 进行控制的。 +更糟糕的是,隐式的 gid 无法被任何策略引擎所检测/验证,因为在清单中没有隐式组信息的线索。 +这对 Kubernetes 的安全性也可能构成隐患。 + + +## Pod 中的细粒度 SupplementalGroups 控制:`SupplementaryGroupsPolicy` + +为了解决上述问题,Kubernetes 1.31 在 Pod 的 `.spec.securityContext` +中引入了新的字段 `supplementalGroupsPolicy`。 + +此字段提供了一种控制 Pod 中容器进程如何计算附加组的方法。可用的策略如下: + + +* **Merge**:将容器的主要用户在 `/etc/group` 中定义的组成员关系进行合并。 + 如果不指定,则应用此策略(即为了向后兼容性而保持的原有行为)。 + +* **Strict**:仅将 `fsGroup`、`supplementalGroups` 或 `runAsGroup` + 字段中指定的组 ID 挂接为容器进程的附加组。这意味着容器的主要用户在 `/etc/group` 中定义的任何组成员关系都不会被合并。 + +让我们看看 `Strict` 策略是如何工作的。 + +{{% code_sample file="strict-supplementalgroups-policy.yaml" %}} + + +```console +# 创建 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 +``` + + +输出应类似于: + +```none +uid=1000 gid=3000 groups=3000,4000 +``` + + +你可以看到 `Strict` 策略可以将组 `50000` 从 `groups` 中排除出去! + +因此,确保(通过某些策略机制强制执行的)`supplementalGroupsPolicy: Strict` 有助于防止 Pod 中的隐式附加组。 + +{{}} + +实际上,这还不够,因为具有足够权限/能力的容器可以更改其进程身份。 +有关细节参见以下章节。 +{{}} + + +## Pod 状态中挂接的进程身份 + +此特性还通过 `.status.containerStatuses[].user.linux` +字段公开挂接到容器的第一个容器进程的进程身份。这将有助于查看隐式组 ID 是否被挂接。 + +```yaml +... +status: + containerStatuses: + - name: ctr + user: + linux: + gid: 3000 + supplementalGroups: + - 3000 + - 4000 + uid: 1000 +... +``` + +{{}} + +请注意,`status.containerStatuses[].user.linux` 字段中的值是**首次挂接**到容器中第一个容器进程的进程身份。 +如果容器具有足够的权限调用与进程身份相关的系统调用(例如 +[`setuid(2)`](https://man7.org/linux/man-pages/man2/setuid.2.html)、 +[`setgid(2)`](https://man7.org/linux/man-pages/man2/setgid.2.html) 或 +[`setgroups(2)`](https://man7.org/linux/man-pages/man2/setgroups.2.html) 等), +则容器进程可以更改其身份。因此,**实际**的进程身份将是动态的。 +{{}} + + +## 特性可用性 + +要启用 `supplementalGroupsPolicy` 字段,必须使用以下组件: + + +- Kubernetes:v1.31 或更高版本,启用 `SupplementalGroupsPolicy` + [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)。 + 截至 v1.31,此门控标记为 Alpha。 +- CRI 运行时: + - containerd:v2.0 或更高版本 + - CRI-O:v1.31 或更高版本 + +你可以在 Node 的 `.status.features.supplementalGroupsPolicy` 字段中查看此特性是否受支持。 + +```yaml +apiVersion: v1 +kind: Node +... +status: + features: + supplementalGroupsPolicy: true +``` + + +## 接下来 + +Kubernetes SIG Node 希望并期待此特性将在 Kubernetes 后续版本中进阶至 Beta, +并最终进阶至正式发布(GA),以便用户不再需要手动启用特性门控。 + +当 `supplementalGroupsPolicy` 未被指定时,将应用 `Merge` 策略,以保持向后兼容性。 + + +## 我如何了解更多? + + + + +- [为 Pod 或容器配置安全上下文](/docs/tasks/configure-pod-container/security-context/)以获取有关 + `supplementalGroupsPolicy` 的更多细节 +- [KEP-3619:细粒度 SupplementalGroups 控制](https://github.com/kubernetes/enhancements/issues/3619) + + +## 如何参与? + +此特性由 SIG Node 社区推动。请加入我们,与社区保持联系, +分享你对上述特性及其他方面的想法和反馈。我们期待听到你的声音! diff --git a/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml new file mode 100644 index 0000000000..8c949ba10f --- /dev/null +++ b/content/zh-cn/blog/_posts/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: strict-supplementalgroups-policy +spec: + 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