[zh-cn] Resync apparmor.md

pull/35285/head
Sean Wei 2022-07-23 22:10:00 +08:00
parent a6072b62a5
commit 35285abc00
1 changed files with 138 additions and 88 deletions

View File

@ -4,6 +4,8 @@ content_type: tutorial
weight: 10
---
<!--
reviewers:
- stclair
title: Restrict a Container's Access to Resources with AppArmor
content_type: tutorial
weight: 10
@ -13,14 +15,14 @@ weight: 10
{{< feature-state for_k8s_version="v1.4" state="beta" >}}
<!--
<!--
AppArmor is a Linux kernel security module that supplements the standard Linux user and group based
permissions to confine programs to a limited set of resources. AppArmor can be configured for any
application to reduce its potential attack surface and provide greater in-depth defense. It is
configured through profiles tuned to allow the access needed by a specific program or container,
such as Linux capabilities, network access, file permissions, etc. Each profile can be run in either
*enforcing* mode, which blocks access to disallowed resources, or *complain* mode, which only reports
violations.
violations.
-->
AppArmor 是一个 Linux 内核安全模块,
它补充了基于标准 Linux 用户和组的权限,将程序限制在一组有限的资源中。
@ -31,7 +33,7 @@ AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提
*强制enforcing* 模式(阻止访问不允许的资源)或
*投诉complain* 模式(仅报告冲突)下运行。
<!--
<!--
AppArmor can help you to run a more secure deployment by restricting what containers are allowed to
do, and/or provide better auditing through system logs. However, it is important to keep in mind
that AppArmor is not a silver bullet and can only do so much to protect against exploits in your
@ -46,12 +48,12 @@ AppArmor 可以通过限制允许容器执行的操作,
## {{% heading "objectives" %}}
<!--
<!--
* See an example of how to load a profile on a node
* Learn how to enforce the profile on a Pod
* Learn how to check that the profile is loaded
* See what happens when a profile is violated
* See what happens when a profile cannot be loaded
* See what happens when a profile cannot be loaded
-->
* 查看如何在节点上加载配置文件示例
* 了解如何在 Pod 上强制执行配置文件
@ -61,10 +63,12 @@ AppArmor 可以通过限制允许容器执行的操作,
## {{% heading "prerequisites" %}}
<!-- Make sure: -->
<!--
Make sure:
-->
确保:
<!--
<!--
1. Kubernetes version is at least v1.4 -- Kubernetes support for AppArmor was added in
v1.4. Kubernetes components older than v1.4 are not aware of the new AppArmor annotations, and
will **silently ignore** any AppArmor settings that are provided. To ensure that your Pods are
@ -93,7 +97,7 @@ AppArmor 可以通过限制允许容器执行的操作,
gke-test-default-pool-239f5d02-xwux: v1.4.0
```
<!--
<!--
2. AppArmor kernel module is enabled -- For the Linux kernel to enforce an AppArmor profile, the
AppArmor kernel module must be installed and enabled. Several distributions enable the module by
default, such as Ubuntu and SUSE, and many others provide optional support. To check whether the
@ -143,7 +147,7 @@ AppArmor 可以通过限制允许容器执行的操作,
或 {{< glossary_tooltip term_id="containerd" >}}。
请参考相应的运行时文档并验证集群是否满足使用 AppArmor 的要求。
<!--
<!--
4. Profile is loaded -- AppArmor is applied to a Pod by specifying an AppArmor profile that each
container should be run with. If any of the specified profiles is not already loaded in the
kernel, the Kubelet (>= v1.4) will reject the Pod. You can view which profiles are loaded on a
@ -180,11 +184,11 @@ AppArmor 可以通过限制允许容器执行的操作,
有关在节点上加载配置文件的详细信息,请参见[使用配置文件设置节点](#setting-up-nodes-with-profiles)。
<!--
<!--
As long as the Kubelet version includes AppArmor support (>= v1.4), the Kubelet will reject a Pod
with AppArmor options if any of the prerequisites are not met. You can also verify AppArmor support
on nodes by checking the node ready condition message (though this is likely to be removed in a
later release):
later release):
-->
只要 Kubelet 版本包含 AppArmor 支持(>=v1.4)
如果不满足这些先决条件Kubelet 将拒绝带有 AppArmor 选项的 Pod。
@ -201,11 +205,13 @@ gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor e
<!-- lessoncontent -->
<!-- ## Securing a Pod -->
<!--
## Securing a Pod
-->
## 保护 Pod {#securing-a-pod}
{{< note >}}
<!--
<!--
AppArmor is currently in beta, so options are specified as annotations. Once support graduates to
general availability, the annotations will be replaced with first-class fields (more details in
[Upgrade path to GA](#upgrade-path-to-general-availability)).
@ -217,7 +223,7 @@ AppArmor 目前处于 Beta 阶段,因此选项以注解形式设定。
<!--
AppArmor profiles are specified *per-container*. To specify the AppArmor profile to run a Pod
container with, add an annotation to the Pod's metadata:
container with, add an annotation to the Pod's metadata:
-->
AppArmor 配置文件是按 *逐个容器* 的形式来设置的。
要指定用来运行 Pod 容器的 AppArmor 配置文件,请向 Pod 的 metadata 添加注解:
@ -226,38 +232,38 @@ AppArmor 配置文件是按 *逐个容器* 的形式来设置的。
container.apparmor.security.beta.kubernetes.io/<container_name>: <profile_ref>
```
<!--
<!--
Where `<container_name>` is the name of the container to apply the profile to, and `<profile_ref>`
specifies the profile to apply. The `profile_ref` can be one of:
specifies the profile to apply. The `profile_ref` can be one of:
-->
`<container_name>` 的名称是配置文件所针对的容器的名称,`<profile_def>` 则设置要应用的配置文件。
`<profile_ref>` 可以是以下取值之一:
<!--
<!--
* `runtime/default` to apply the runtime's default profile
* `localhost/<profile_name>` to apply the profile loaded on the host with the name `<profile_name>`
* `unconfined` to indicate that no profiles will be loaded
* `unconfined` to indicate that no profiles will be loaded
-->
* `runtime/default` 应用运行时的默认配置
* `localhost/<profile_name>` 应用在主机上加载的名为 `<profile_name>` 的配置文件
* `unconfined` 表示不加载配置文件
<!--
<!--
See the [API Reference](#api-reference) for the full details on the annotation and profile name formats.
-->
有关注解和配置文件名称格式的详细信息,请参阅[API 参考](#api-reference)。
有关注解和配置文件名称格式的详细信息,请参阅 [API 参考](#api-reference)。
<!--
<!--
Kubernetes AppArmor enforcement works by first checking that all the prerequisites have been
met, and then forwarding the profile selection to the container runtime for enforcement. If the
prerequisites have not been met, the Pod will be rejected, and will not run.
prerequisites have not been met, the Pod will be rejected, and will not run.
-->
Kubernetes AppArmor 强制执行机制首先检查所有先决条件都已满足,
然后将所选的配置文件转发到容器运行时进行强制执行。
如果未满足先决条件Pod 将被拒绝,并且不会运行。
<!--
To verify that the profile was applied, you can look for the AppArmor security option listed in the container created event:
<!--
To verify that the profile was applied, you can look for the AppArmor security option listed in the container created event:
-->
要验证是否应用了配置文件,可以在容器创建事件中查找所列出的 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]
```
<!--
You can also verify directly that the container's root process is running with the correct profile by checking its proc attr:
<!--
You can also verify directly that the container's root process is running with the correct profile by checking its proc attr:
-->
你还可以通过检查容器的 proc attr直接验证容器的根进程是否以正确的配置文件运行
@ -280,14 +286,18 @@ kubectl exec <pod_name> cat /proc/1/attr/current
k8s-apparmor-example-deny-write (enforce)
```
<!-- ## Example -->
<!--
## Example
-->
## 举例 {#example}
<!-- *This example assumes you have already set up a cluster with AppArmor support.* -->
*本例假设你已经设置了一个集群使用 AppArmor 支持。*
<!--
*This example assumes you have already set up a cluster with AppArmor support.*
-->
**本例假设你已经设置了一个集群使用 AppArmor 支持。**
<!--
First, we need to load the profile we want to use onto our nodes. This profile denies all file writes:
<!--
First, we need to load the profile we want to use onto our nodes. This profile denies all file writes:
-->
首先,我们需要将要使用的配置文件加载到节点上。配置文件拒绝所有文件写入:
@ -304,10 +314,10 @@ profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
}
```
<!--
<!--
Since we don't know where the Pod will be scheduled, we'll need to load the profile on all our
nodes. For this example we'll use SSH to install the profiles, but other approaches are
discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles).
discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles).
-->
由于我们不知道 Pod 将被调度到哪里,我们需要在所有节点上加载配置文件。
在本例中,我们将使用 SSH 来安装概要文件,
@ -334,7 +344,9 @@ EOF'
done
```
<!-- Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile: -->
<!--
Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile:
-->
接下来,我们将运行一个带有拒绝写入配置文件的简单 “Hello AppArmor” Pod
{{< codenew file="pods/security/hello-apparmor.yaml" >}}
@ -343,9 +355,9 @@ done
kubectl create -f ./hello-apparmor.yaml
```
<!--
<!--
If we look at the pod events, we can see that the Pod container was created with the AppArmor
profile "k8s-apparmor-example-deny-write":
profile "k8s-apparmor-example-deny-write":
-->
如果我们查看 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
```
<!-- We can verify that the container is actually running with that profile by checking its proc attr: -->
<!--
We can verify that the container is actually running with that profile by checking its proc attr:
-->
我们可以通过检查该配置文件的 proc attr 来验证容器是否实际使用该配置文件运行:
```shell
@ -371,7 +385,9 @@ kubectl exec hello-apparmor -- cat /proc/1/attr/current
k8s-apparmor-example-deny-write (enforce)
```
<!-- Finally, we can see what happens if we try to violate the profile by writing to a file: -->
<!--
Finally, we can see what happens if we try to violate the profile by writing to a file:
-->
最后,我们可以看到,如果我们尝试通过写入文件来违反配置文件会发生什么:
```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
```
<!-- To wrap up, let's look at what happens if we try to specify a profile that hasn't been loaded: -->
<!--
To wrap up, let's look at what happens if we try to specify a profile that hasn't been loaded:
-->
最后,让我们看看如果我们试图指定一个尚未加载的配置文件会发生什么:
```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
```
<!--
<!--
Note the pod status is Pending, with a helpful error message: `Pod Cannot enforce AppArmor: profile
"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message.
"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message.
-->
注意 Pod 呈现 Pending 状态,并且显示一条有用的错误信息:
`Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded`
还用相同的消息记录了一个事件。
<!-- ## Administration -->
<!--
## Administration
-->
## 管理 {#administration}
<!-- ### Setting up nodes with profiles -->
<!--
### Setting up nodes with profiles
-->
### 使用配置文件设置节点 {#setting-up-nodes-with-profiles}
<!--
<!--
Kubernetes does not currently provide any native mechanisms for loading AppArmor profiles onto
nodes. There are lots of ways to setup the profiles though, such as:
nodes. There are lots of ways to setup the profiles though, such as:
-->
Kubernetes 目前不提供任何本地机制来将 AppArmor 配置文件加载到节点上。
有很多方法可以设置配置文件,例如:
<!--
<!--
* Through a [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) that runs a Pod on each node to
ensure the correct profiles are loaded. An example implementation can be found
[here](https://git.k8s.io/kubernetes/test/images/apparmor-loader).
* At node initialization time, using your node initialization scripts (e.g. Salt, Ansible, etc.) or
image.
* By copying the profiles to each node and loading them through SSH, as demonstrated in the
[Example](#example).
[Example](#example).
-->
* 通过在每个节点上运行 Pod 的
[DaemonSet](/zh-cn/docs/concepts/workloads/controllers/daemonset/)来确保加载了正确的配置文件。
@ -492,23 +514,25 @@ Kubernetes 目前不提供任何本地机制来将 AppArmor 配置文件加载
* 在节点初始化时,使用节点初始化脚本(例如 Salt、Ansible 等)或镜像。
* 通过将配置文件复制到每个节点并通过 SSH 加载它们,如[示例](#example)。
<!--
<!--
The scheduler is not aware of which profiles are loaded onto which node, so the full set of profiles
must be loaded onto every node. An alternative approach is to add a node label for each profile (or
class of profiles) on the node, and use a
[node selector](/docs/concepts/configuration/assign-pod-node/) to ensure the Pod is run on a
node with the required profile.
[node selector](/docs/concepts/scheduling-eviction/assign-pod-node/) to ensure the Pod is run on a
node with the required profile.
-->
调度程序不知道哪些配置文件加载到哪个节点上,因此必须将全套配置文件加载到每个节点上。
另一种方法是为节点上的每个配置文件(或配置文件类)添加节点标签,
并使用[节点选择器](/zh-cn/docs/concepts/configuration/assign-pod-node/)确保
并使用[节点选择器](/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/)确保
Pod 在具有所需配置文件的节点上运行。
<!-- ### Restricting profiles with the PodSecurityPolicy -->
<!--
### Restricting profiles with the PodSecurityPolicy
-->
### 使用 PodSecurityPolicy 限制配置文件 {#restricting-profiles-with-the-podsecuritypolicy}
{{< note >}}
<!--
<!--
PodSecurityPolicy is deprecated in Kubernetes v1.21, and will be removed in v1.25.
See [PodSecurityPolicy](/docs/concepts/security/pod-security-policy/) documentation for more information.
-->
@ -516,9 +540,9 @@ PodSecurityPolicy 在 Kubernetes v1.21 版本中已被废弃,将在 v1.25 版
查看 [PodSecurityPolicy](/zh-cn/docs/concepts/security/pod-security-policy/) 文档获取更多信息。
{{< /note >}}
<!--
<!--
If the PodSecurityPolicy extension is enabled, cluster-wide AppArmor restrictions can be applied. To
enable the PodSecurityPolicy, the following flag must be set on the `apiserver`:
enable the PodSecurityPolicy, the following flag must be set on the `apiserver`:
-->
如果启用了 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...]
```
<!-- The AppArmor options can be specified as annotations on the PodSecurityPolicy: -->
<!--
The AppArmor options can be specified as annotations on the PodSecurityPolicy:
-->
AppArmor 选项可以指定为 PodSecurityPolicy 上的注解:
```yaml
@ -535,31 +561,35 @@ apparmor.security.beta.kubernetes.io/defaultProfileName: <profile_ref>
apparmor.security.beta.kubernetes.io/allowedProfileNames: <profile_ref>[,others...]
```
<!--
<!--
The default profile name option specifies the profile to apply to containers by default when none is
specified. The allowed profile names option specifies a list of profiles that Pod containers are
allowed to be run with. If both options are provided, the default must be allowed. The profiles are
specified in the same format as on containers. See the [API Reference](#api-reference) for the full
specification.
specification.
-->
默认配置文件名选项指定默认情况下在未指定任何配置文件时应用于容器的配置文件。
所允许的配置文件名称选项指定允许 Pod 容器运行期间所对应的配置文件列表。
如果同时提供了这两个选项,则必须允许默认值。
配置文件的指定格式与容器上的相同。有关完整规范,请参阅 [API 参考](#api-reference)。
<!-- ### Disabling AppArmor -->
<!--
### Disabling AppArmor
-->
### 禁用 AppArmor {#disabling-apparmor}
<!-- If you do not want AppArmor to be available on your cluster, it can be disabled by a command-line flag: -->
<!--
If you do not want AppArmor to be available on your cluster, it can be disabled by a command-line flag:
-->
如果你不希望 AppArmor 在集群上可用,可以通过命令行标志禁用它:
```
--feature-gates=AppArmor=false
```
<!--
<!--
When disabled, any Pod that includes an AppArmor profile will fail validation with a "Forbidden"
error.
error.
-->
禁用时,任何包含 AppArmor 配置文件的 Pod 都将导致验证失败,且返回 “Forbidden” 错误。
@ -575,21 +605,23 @@ availability (GA).
{{</note>}}
<!-- ## Authoring Profiles -->
<!--
## Authoring Profiles
-->
## 编写配置文件 {#authoring-profiles}
<!--
<!--
Getting AppArmor profiles specified correctly can be a tricky business. Fortunately there are some
tools to help with that:
tools to help with that:
-->
获得正确指定的 AppArmor 配置文件可能是一件棘手的事情。幸运的是,有一些工具可以帮助你做到这一点:
<!--
<!--
* `aa-genprof` and `aa-logprof` generate profile rules by monitoring an application's activity and
logs, and admitting the actions it takes. Further instructions are provided by the
[AppArmor documentation](https://gitlab.com/apparmor/apparmor/wikis/Profiling_with_tools).
* [bane](https://github.com/jfrazelle/bane) is an AppArmor profile generator for Docker that uses a
simplified profile language.
simplified profile language.
-->
* `aa-genprof``aa-logprof`
通过监视应用程序的活动和日志并准许它所执行的操作来生成配置文件规则。
@ -597,41 +629,49 @@ tools to help with that:
* [bane](https://github.com/jfrazelle/bane)
是一个用于 Docker的 AppArmor 配置文件生成器它使用一种简化的画像语言profile language
<!--
<!--
To debug problems with AppArmor, you can check the system logs to see what, specifically, was
denied. AppArmor logs verbose messages to `dmesg`, and errors can usually be found in the system
logs or through `journalctl`. More information is provided in
[AppArmor failures](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Failures).
[AppArmor failures](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Failures).
-->
想要调试 AppArmor 的问题,你可以检查系统日志,查看具体拒绝了什么。
AppArmor 将详细消息记录到 `dmesg`
错误通常可以在系统日志中或通过 `journalctl` 找到。
更多详细信息见 [AppArmor 失败](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Failures)。
<!-- ## API Reference -->
<!--
## API Reference
-->
## API 参考 {#api-reference}
<!-- ### Pod Annotation -->
<!--
### Pod Annotation
-->
### Pod 注解 {#pod-annotation}
<!-- Specifying the profile a container will run with: -->
<!--
Specifying the profile a container will run with:
-->
指定容器将使用的配置文件:
<!--
<!--
- **key**: `container.apparmor.security.beta.kubernetes.io/<container_name>`
Where `<container_name>` matches the name of a container in the Pod.
A separate profile can be specified for each container in the Pod.
- **value**: a profile reference, described below
- **value**: a profile reference, described below
-->
- **键名**: `container.apparmor.security.beta.kubernetes.io/<container_name>`
,其中 `<container_name>` 与 Pod 中某容器的名称匹配。
可以为 Pod 中的每个容器指定单独的配置文件。
- **键值**: 对配置文件的引用,如下所述
<!-- ### Profile Reference -->
<!--
### Profile Reference
-->
### 配置文件引用 {#profile-reference}
<!--
<!--
- `runtime/default`: Refers to the default runtime profile.
- Equivalent to not specifying a profile (without a PodSecurityPolicy default), except it still
requires AppArmor to be enabled.
@ -640,7 +680,7 @@ AppArmor 将详细消息记录到 `dmesg`
- `localhost/<profile_name>`: Refers to a profile loaded on the node (localhost) by name.
- The possible profile names are detailed in the
[core policy reference](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#profile-names-and-attachment-specifications).
- `unconfined`: This effectively disables AppArmor on the container.
- `unconfined`: This effectively disables AppArmor on the container.
-->
- `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。
<!-- Any other profile reference format is invalid. -->
<!--
Any other profile reference format is invalid.
-->
任何其他配置文件引用格式无效。
<!-- ### PodSecurityPolicy Annotations -->
<!--
### PodSecurityPolicy Annotations
-->
### PodSecurityPolicy 注解 {#podsecuritypolicy-annotations}
<!-- Specifying the default profile to apply to containers when none is provided: -->
<!--
Specifying the default profile to apply to containers when none is provided:
-->
指定在未提供容器时应用于容器的默认配置文件:
<!--
<!--
* **key**: `apparmor.security.beta.kubernetes.io/defaultProfileName`
* **value**: a profile reference, described above
* **value**: a profile reference, described above
-->
* **键名**: `apparmor.security.beta.kubernetes.io/defaultProfileName`
* **键值**: 如上述文件参考所述
<!-- Specifying the list of profiles Pod containers is allowed to specify: -->
<!--
Specifying the list of profiles Pod containers is allowed to specify:
-->
上面描述的指定配置文件Pod 容器列表的配置文件引用允许指定:
<!--
<!--
* **key**: `apparmor.security.beta.kubernetes.io/allowedProfileNames`
* **value**: a comma-separated list of profile references (described above)
- Although an escaped comma is a legal character in a profile name, it cannot be explicitly
allowed here.
allowed here.
-->
* **键名**: `apparmor.security.beta.kubernetes.io/allowedProfileNames`
* **键值**: 配置文件引用的逗号分隔列表(如上所述)
@ -681,12 +729,14 @@ AppArmor 将详细消息记录到 `dmesg`
## {{% heading "whatsnext" %}}
<!-- Additional resources: -->
<!--
Additional resources:
-->
其他资源:
<!--
<!--
* [Quick guide to the AppArmor profile language](https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage)
* [AppArmor core policy reference](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout)
* [AppArmor core policy reference](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout)
-->
* [Apparmor 配置文件语言快速指南](https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage)
* [Apparmor 核心策略参考](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout)