diff --git a/content/zh-cn/docs/tutorials/security/apparmor.md b/content/zh-cn/docs/tutorials/security/apparmor.md index 00048de976..a1669d2a5d 100644 --- a/content/zh-cn/docs/tutorials/security/apparmor.md +++ b/content/zh-cn/docs/tutorials/security/apparmor.md @@ -4,6 +4,8 @@ content_type: tutorial weight: 10 --- AppArmor 是一个 Linux 内核安全模块, 它补充了基于标准 Linux 用户和组的权限,将程序限制在一组有限的资源中。 @@ -31,7 +33,7 @@ AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提 *强制(enforcing)* 模式(阻止访问不允许的资源)或 *投诉(complain)* 模式(仅报告冲突)下运行。 - * 查看如何在节点上加载配置文件示例 * 了解如何在 Pod 上强制执行配置文件 @@ -61,10 +63,12 @@ AppArmor 可以通过限制允许容器执行的操作, ## {{% heading "prerequisites" %}} - + 确保: - 只要 Kubelet 版本包含 AppArmor 支持(>=v1.4), 如果不满足这些先决条件,Kubelet 将拒绝带有 AppArmor 选项的 Pod。 @@ -201,11 +205,13 @@ gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor e - + ## 保护 Pod {#securing-a-pod} {{< note >}} - AppArmor 配置文件是按 *逐个容器* 的形式来设置的。 要指定用来运行 Pod 容器的 AppArmor 配置文件,请向 Pod 的 metadata 添加注解: @@ -226,38 +232,38 @@ AppArmor 配置文件是按 *逐个容器* 的形式来设置的。 container.apparmor.security.beta.kubernetes.io/: ``` - `` 的名称是配置文件所针对的容器的名称,`` 则设置要应用的配置文件。 `` 可以是以下取值之一: - * `runtime/default` 应用运行时的默认配置 * `localhost/` 应用在主机上加载的名为 `` 的配置文件 * `unconfined` 表示不加载配置文件 - -有关注解和配置文件名称格式的详细信息,请参阅[API 参考](#api-reference)。 +有关注解和配置文件名称格式的详细信息,请参阅 [API 参考](#api-reference)。 - Kubernetes AppArmor 强制执行机制首先检查所有先决条件都已满足, 然后将所选的配置文件转发到容器运行时进行强制执行。 如果未满足先决条件,Pod 将被拒绝,并且不会运行。 - 要验证是否应用了配置文件,可以在容器创建事件中查找所列出的 AppArmor 安全选项: @@ -268,8 +274,8 @@ kubectl get events | grep Created 22s 22s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet e2e-test-stclair-node-pool-31nt} Created container with docker id 269a53b202d3; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write] ``` - 你还可以通过检查容器的 proc attr,直接验证容器的根进程是否以正确的配置文件运行: @@ -280,14 +286,18 @@ kubectl exec cat /proc/1/attr/current k8s-apparmor-example-deny-write (enforce) ``` - + ## 举例 {#example} - -*本例假设你已经设置了一个集群使用 AppArmor 支持。* + +**本例假设你已经设置了一个集群使用 AppArmor 支持。** - 首先,我们需要将要使用的配置文件加载到节点上。配置文件拒绝所有文件写入: @@ -304,10 +314,10 @@ profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { } ``` - 由于我们不知道 Pod 将被调度到哪里,我们需要在所有节点上加载配置文件。 在本例中,我们将使用 SSH 来安装概要文件, @@ -334,7 +344,9 @@ EOF' done ``` - + 接下来,我们将运行一个带有拒绝写入配置文件的简单 “Hello AppArmor” Pod: {{< codenew file="pods/security/hello-apparmor.yaml" >}} @@ -343,9 +355,9 @@ done kubectl create -f ./hello-apparmor.yaml ``` - 如果我们查看 Pod 事件,我们可以看到 Pod 容器是用 AppArmor 配置文件 “k8s-apparmor-example-deny-write” 所创建的: @@ -361,7 +373,9 @@ kubectl get events | grep hello-apparmor 13s 13s 1 hello-apparmor Pod spec.containers{hello} Normal Started {kubelet gke-test-default-pool-239f5d02-gyn2} Started container with docker id 06b6cd1c0989 ``` - + 我们可以通过检查该配置文件的 proc attr 来验证容器是否实际使用该配置文件运行: ```shell @@ -371,7 +385,9 @@ kubectl exec hello-apparmor -- cat /proc/1/attr/current k8s-apparmor-example-deny-write (enforce) ``` - + 最后,我们可以看到,如果我们尝试通过写入文件来违反配置文件会发生什么: ```shell @@ -382,7 +398,9 @@ touch: /tmp/test: Permission denied error: error executing remote command: command terminated with non-zero exit code: Error executing in Docker Container: 1 ``` - + 最后,让我们看看如果我们试图指定一个尚未加载的配置文件会发生什么: ```shell @@ -456,35 +474,39 @@ Events: 23s 23s 1 {kubelet e2e-test-stclair-node-pool-t1f5} Warning AppArmor Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded ``` - 注意 Pod 呈现 Pending 状态,并且显示一条有用的错误信息: `Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded`。 还用相同的消息记录了一个事件。 - + ## 管理 {#administration} - + ### 使用配置文件设置节点 {#setting-up-nodes-with-profiles} - Kubernetes 目前不提供任何本地机制来将 AppArmor 配置文件加载到节点上。 有很多方法可以设置配置文件,例如: - * 通过在每个节点上运行 Pod 的 [DaemonSet](/zh-cn/docs/concepts/workloads/controllers/daemonset/)来确保加载了正确的配置文件。 @@ -492,23 +514,25 @@ Kubernetes 目前不提供任何本地机制来将 AppArmor 配置文件加载 * 在节点初始化时,使用节点初始化脚本(例如 Salt、Ansible 等)或镜像。 * 通过将配置文件复制到每个节点并通过 SSH 加载它们,如[示例](#example)。 - 调度程序不知道哪些配置文件加载到哪个节点上,因此必须将全套配置文件加载到每个节点上。 另一种方法是为节点上的每个配置文件(或配置文件类)添加节点标签, -并使用[节点选择器](/zh-cn/docs/concepts/configuration/assign-pod-node/)确保 +并使用[节点选择器](/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/)确保 Pod 在具有所需配置文件的节点上运行。 - + ### 使用 PodSecurityPolicy 限制配置文件 {#restricting-profiles-with-the-podsecuritypolicy} {{< note >}} - @@ -516,9 +540,9 @@ PodSecurityPolicy 在 Kubernetes v1.21 版本中已被废弃,将在 v1.25 版 查看 [PodSecurityPolicy](/zh-cn/docs/concepts/security/pod-security-policy/) 文档获取更多信息。 {{< /note >}} - 如果启用了 PodSecurityPolicy 扩展,则可以应用集群范围的 AppArmor 限制。 要启用 PodSecurityPolicy,必须在 `apiserver` 上设置以下标志: @@ -527,7 +551,9 @@ enable the PodSecurityPolicy, the following flag must be set on the `apiserver`: --enable-admission-plugins=PodSecurityPolicy[,others...] ``` - + AppArmor 选项可以指定为 PodSecurityPolicy 上的注解: ```yaml @@ -535,31 +561,35 @@ apparmor.security.beta.kubernetes.io/defaultProfileName: apparmor.security.beta.kubernetes.io/allowedProfileNames: [,others...] ``` - 默认配置文件名选项指定默认情况下在未指定任何配置文件时应用于容器的配置文件。 所允许的配置文件名称选项指定允许 Pod 容器运行期间所对应的配置文件列表。 如果同时提供了这两个选项,则必须允许默认值。 配置文件的指定格式与容器上的相同。有关完整规范,请参阅 [API 参考](#api-reference)。 - + ### 禁用 AppArmor {#disabling-apparmor} - + 如果你不希望 AppArmor 在集群上可用,可以通过命令行标志禁用它: ``` --feature-gates=AppArmor=false ``` - 禁用时,任何包含 AppArmor 配置文件的 Pod 都将导致验证失败,且返回 “Forbidden” 错误。 @@ -575,21 +605,23 @@ availability (GA). {{}} - + ## 编写配置文件 {#authoring-profiles} - 获得正确指定的 AppArmor 配置文件可能是一件棘手的事情。幸运的是,有一些工具可以帮助你做到这一点: - * `aa-genprof` 和 `aa-logprof` 通过监视应用程序的活动和日志并准许它所执行的操作来生成配置文件规则。 @@ -597,41 +629,49 @@ tools to help with that: * [bane](https://github.com/jfrazelle/bane) 是一个用于 Docker的 AppArmor 配置文件生成器,它使用一种简化的画像语言(profile language) - 想要调试 AppArmor 的问题,你可以检查系统日志,查看具体拒绝了什么。 AppArmor 将详细消息记录到 `dmesg`, 错误通常可以在系统日志中或通过 `journalctl` 找到。 更多详细信息见 [AppArmor 失败](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Failures)。 - + ## API 参考 {#api-reference} - + ### Pod 注解 {#pod-annotation} - + 指定容器将使用的配置文件: - - **键名**: `container.apparmor.security.beta.kubernetes.io/` ,其中 `` 与 Pod 中某容器的名称匹配。 可以为 Pod 中的每个容器指定单独的配置文件。 - **键值**: 对配置文件的引用,如下所述 - + ### 配置文件引用 {#profile-reference} - - `runtime/default`: 指默认运行时配置文件。 - 等同于不指定配置文件(没有 PodSecurityPolicy 默认值),只是它仍然需要启用 AppArmor。 @@ -650,30 +690,38 @@ AppArmor 将详细消息记录到 `dmesg`, - 可能的配置文件名在[核心策略参考](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#profile-names-and-attachment-specifications)。 - `unconfined`: 这相当于为容器禁用 AppArmor。 - + 任何其他配置文件引用格式无效。 - + ### PodSecurityPolicy 注解 {#podsecuritypolicy-annotations} - + 指定在未提供容器时应用于容器的默认配置文件: - * **键名**: `apparmor.security.beta.kubernetes.io/defaultProfileName` * **键值**: 如上述文件参考所述 - + 上面描述的指定配置文件,Pod 容器列表的配置文件引用允许指定: - * **键名**: `apparmor.security.beta.kubernetes.io/allowedProfileNames` * **键值**: 配置文件引用的逗号分隔列表(如上所述) @@ -681,12 +729,14 @@ AppArmor 将详细消息记录到 `dmesg`, ## {{% heading "whatsnext" %}} - + 其他资源: - * [Apparmor 配置文件语言快速指南](https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage) * [Apparmor 核心策略参考](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout)