From 2d41065ae4629dde8e371b94ab6fec6f703bb81b Mon Sep 17 00:00:00 2001 From: windsonsea Date: Mon, 2 Sep 2024 10:00:43 +0800 Subject: [PATCH] [zh] Add zh text to: security-context.md --- .../supplemental-groups-policy.md | 19 + .../security-context.md | 377 +++++++++++++++++- .../pods/security/security-context-5.yaml | 15 + .../pods/security/security-context-6.yaml | 16 + 4 files changed, 422 insertions(+), 5 deletions(-) create mode 100644 content/zh-cn/docs/reference/command-line-tools-reference/feature-gates/supplemental-groups-policy.md create mode 100644 content/zh-cn/examples/pods/security/security-context-5.yaml create mode 100644 content/zh-cn/examples/pods/security/security-context-6.yaml diff --git a/content/zh-cn/docs/reference/command-line-tools-reference/feature-gates/supplemental-groups-policy.md b/content/zh-cn/docs/reference/command-line-tools-reference/feature-gates/supplemental-groups-policy.md new file mode 100644 index 0000000000..3f9830c5c5 --- /dev/null +++ b/content/zh-cn/docs/reference/command-line-tools-reference/feature-gates/supplemental-groups-policy.md @@ -0,0 +1,19 @@ +--- +title: SupplementalGroupsPolicy +content_type: feature_gate +_build: + list: never + render: false + +stages: + - stage: alpha + defaultValue: false + fromVersion: "1.31" +--- + + +启用对细粒度 SupplementalGroups 控制的支持。 +有关细节请参见[为 Pod 配置细粒度 SupplementalGroups 控制](/zh-cn/docs/tasks/configure-pod-container/security-context/#supplementalgroupspolicy)。 diff --git a/content/zh-cn/docs/tasks/configure-pod-container/security-context.md b/content/zh-cn/docs/tasks/configure-pod-container/security-context.md index 5bac369957..f508f32383 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/security-context.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/security-context.md @@ -117,6 +117,8 @@ all processes within any containers of the Pod. If this field is omitted, the pr will be root(0). Any files created will also be owned by user 1000 and group 3000 when `runAsGroup` is specified. Since `fsGroup` field is specified, all processes of the container are also part of the supplementary group ID 2000. The owner for volume `/data/demo` and any files created in that volume will be Group ID 2000. +Additionally, when the `supplementalGroups` field is specified, all processes of the container are also part of the +specified groups. If this field is omitted, it means empty. Create the Pod: --> @@ -126,6 +128,8 @@ Create the Pod: 当 `runAsGroup` 被设置时,所有创建的文件也会划归用户 1000 和组 3000。 由于 `fsGroup` 被设置,容器中所有进程也会是附组 ID 2000 的一部分。 卷 `/data/demo` 及在该卷中创建的任何文件的属主都会是组 ID 2000。 +此外,当 `supplementalGroups` 字段被指定时,容器的所有进程也会成为所指定的组的一部分。 +如果此字段被省略,则表示为空。 创建该 Pod: @@ -235,20 +239,23 @@ The output is similar to this: 输出类似于: ```none -uid=1000 gid=3000 groups=2000 +uid=1000 gid=3000 groups=2000,3000,4000 ``` 从输出中你会看到 `gid` 值为 3000,也就是 `runAsGroup` 字段的值。 如果 `runAsGroup` 被忽略,则 `gid` 会取值 0(root),而进程就能够与 root 用户组所拥有以及要求 root 用户组访问权限的文件交互。 +你还可以看到,除了 `gid` 之外,`groups` 还包含了由 `fsGroup` 和 `supplementalGroups` 指定的组 ID。 退出你的 Shell: @@ -256,10 +263,291 @@ Exit your shell: exit ``` + +### 容器镜像内 `/etc/group` 中定义的隐式组成员身份 + +默认情况下,Kubernetes 会将 Pod 中的组信息与容器镜像内 `/etc/group` 中定义的信息合并。 + +{{% code_sample file="pods/security/security-context-5.yaml" %}} + + +此 Pod 的安全上下文包含 `runAsUser`、`runAsGroup` 和 `supplementalGroups`。 +然而,你可以看到,挂接到容器进程的实际附加组将包括来自容器镜像中 `/etc/group` 的组 ID。 + +创建 Pod: + +```shell +kubectl apply -f https://k8s.io/examples/pods/security/security-context-5.yaml +``` + + +验证 Pod 的 Container 正在运行: + +```shell +kubectl get pod security-context-demo +``` + + +打开一个 Shell 进入正在运行的 Container: + +```shell +kubectl exec -it security-context-demo -- sh +``` + + +检查进程身份: + +```shell +$ id +``` + + +输出类似于: + +```none +uid=1000 gid=3000 groups=3000,4000,50000 +``` + + +你可以看到 `groups` 包含组 ID `50000`。 +这是因为镜像中定义的用户(`uid=1000`)属于在容器镜像内 `/etc/group` 中定义的组(`gid=50000`)。 + +检查容器镜像中的 `/etc/group`: + +```shell +$ cat /etc/group +``` + + +你可以看到 uid `1000` 属于组 `50000`。 + +```none +... +user-defined-in-image:x:1000: +group-defined-in-image:x:50000:user-defined-in-image +``` + + +退出你的 Shell: + +```shell +exit +``` + +{{}} + +**隐式合并的**附加组可能会导致安全问题, +特别是在访问卷时(有关细节请参见 [kubernetes/kubernetes#112879](https://issue.k8s.io/112879))。 +如果你想避免这种问题,请查阅以下章节。 +{{}} + + +## 配置 Pod 的细粒度 SupplementalGroups 控制 {#supplementalgroupspolicy} + +{{< feature-state feature_gate_name="SupplementalGroupsPolicy" >}} + + +通过为 kubelet 和 kube-apiserver 设置 `SupplementalGroupsPolicy` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), +并为 Pod 设置 `.spec.securityContext.supplementalGroupsPolicy` 字段,此特性可以被启用。 + +`supplementalGroupsPolicy` 字段为 Pod 中的容器进程定义了计算附加组的策略。 +此字段有两个有效值: + + +* `Merge`:为容器的主用户在 `/etc/group` 中定义的组成员身份将被合并。 + 如果不指定,这就是默认策略。 + +* `Strict`:仅将 `fsGroup`、`supplementalGroups` 或 `runAsGroup` + 字段中的组 ID 挂接为容器进程的附加组。这意味着容器主用户在 `/etc/group` 中的组成员身份将不会被合并。 + + +当此特性被启用时,它还会在 `.status.containerStatuses[].user.linux` +字段中暴露挂接到第一个容器进程的进程身份。这对于检测是否挂接了隐式组 ID 非常有用。 + +{{% code_sample file="pods/security/security-context-6.yaml" %}} + + +此 Pod 清单定义了 `supplementalGroupsPolicy=Strict`。 +你可以看到没有将 `/etc/group` 中定义的组成员身份合并到容器进程的附加组中。 + +创建 Pod: + +```shell +kubectl apply -f https://k8s.io/examples/pods/security/security-context-6.yaml +``` + + +验证 Pod 的 Container 正在运行: + +```shell +kubectl get pod security-context-demo +``` + + +检查进程身份: + +```shell +kubectl exec -it security-context-demo -- id +``` + + +输出类似于: + +```none +uid=1000 gid=3000 groups=3000,4000 +``` + + +查看 Pod 的状态: + +```shell +kubectl get pod security-context-demo -o yaml +``` + + +你可以看到 `status.containerStatuses[].user.linux` 字段暴露了挂接到第一个容器进程的进程身份。 + +```none +... +status: + containerStatuses: + - name: sec-ctx-demo + 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) 等), +则容器进程可以更改其身份。因此,**实际**进程身份将是动态的。 +{{}} + + +### 实现 {#implementations-supplementalgroupspolicy} + +{{% thirdparty-content %}} + + +已知以下容器运行时支持细粒度的 SupplementalGroups 控制。 + +CRI 级别: + +- [containerd](https://containerd.io/),自 v2.0 起 +- [CRI-O](https://cri-o.io/),自 v1.31 起 + +你可以在 Node 状态中查看此特性是否受支持。 + +```yaml +apiVersion: v1 +kind: Node +... +status: + features: + supplementalGroupsPolicy: true +``` + -## 为 Pod 配置卷访问权限和属主变更策略 +## 为 Pod 配置卷访问权限和属主变更策略 {#configure-volume-permission-and-ownership-change-policy-for-pods} {{< feature-state for_k8s_version="v1.23" state="stable" >}} @@ -674,6 +962,85 @@ securityContext: localhostProfile: my-profiles/profile-allow.json ``` + +## 为 Container 设置 AppArmor 配置 {#set-the-apparmor-profile-for-a-container} + + +要为 Container 设置 AppArmor 配置,请在 Container 的 `securityContext` 节中包含 `appArmorProfile` 字段。 +`appArmorProfile` 字段是一个 +[AppArmorProfile](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#apparmorprofile-v1-core) +对象,由 `type` 和 `localhostProfile` 组成。 +`type` 的有效选项包括 `RuntimeDefault`(默认)、`Unconfined` 和 `Localhost`。 +只有当 `type` 为 `Localhost` 时,才能设置 `localhostProfile`。 +它表示节点上预配的配置文件的名称。 +此配置需要被加载到所有适合 Pod 的节点上,因为你不知道 Pod 将被调度到哪里。 +关于设置自定义配置的方法,参见[使用配置文件设置节点](/zh-cn/docs/tutorials/security/apparmor/#setting-up-nodes-with-profiles)。 + + +注意:如果 `containers[*].securityContext.appArmorProfile.type` 被显式设置为 +`RuntimeDefault`,那么如果 AppArmor 未在 Node 上被启用,Pod 将不会被准入。 +然而,如果 `containers[*].securityContext.appArmorProfile.type` 未被指定, +则只有在节点已启用 AppArmor 时才会应用默认值(也是 `RuntimeDefault`)。 +如果节点已禁用 AppArmor,Pod 将被准入,但 Container 将不受 `RuntimeDefault` 配置的限制。 + +以下是将 AppArmor 配置设置为节点的容器运行时默认配置的例子: + +```yaml +... +containers: +- name: container-1 + securityContext: + appArmorProfile: + type: RuntimeDefault +``` + + +以下是将 AppArmor 配置设置为名为 `k8s-apparmor-example-deny-write` 的预配配置的例子: + +```yaml +... +containers: +- name: container-1 + securityContext: + appArmorProfile: + type: Localhost + localhostProfile: k8s-apparmor-example-deny-write +``` + + +有关更多细节参见[使用 AppArmor 限制容器对资源的访问](/zh-cn/docs/tutorials/security/apparmor/)。 + -## 为 Container 赋予 SELinux 标签 +## 为 Container 赋予 SELinux 标签 {#assign-selinux-labels-to-a-container} 若要给 Container 设置 SELinux 标签,可以在 Pod 或 Container 清单的 `securityContext` 节包含 `seLinuxOptions` 字段。 @@ -698,10 +1065,10 @@ securityContext: level: "s0:c123,c456" ``` +{{< note >}} -{{< note >}} 要指定 SELinux,需要在宿主操作系统中装载 SELinux 安全性模块。 {{< /note >}} diff --git a/content/zh-cn/examples/pods/security/security-context-5.yaml b/content/zh-cn/examples/pods/security/security-context-5.yaml new file mode 100644 index 0000000000..26e057150d --- /dev/null +++ b/content/zh-cn/examples/pods/security/security-context-5.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + supplementalGroups: [4000] + containers: + - name: sec-ctx-demo + image: registry.k8s.io/e2e-test-images/agnhost:2.45 + command: [ "sh", "-c", "sleep 1h" ] + securityContext: + allowPrivilegeEscalation: false diff --git a/content/zh-cn/examples/pods/security/security-context-6.yaml b/content/zh-cn/examples/pods/security/security-context-6.yaml new file mode 100644 index 0000000000..6bbd1288ec --- /dev/null +++ b/content/zh-cn/examples/pods/security/security-context-6.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + supplementalGroups: [4000] + supplementalGroupsPolicy: Strict + containers: + - name: sec-ctx-demo + image: registry.k8s.io/e2e-test-images/agnhost:2.45 + command: [ "sh", "-c", "sleep 1h" ] + securityContext: + allowPrivilegeEscalation: false