From ef68ee5c3f4d830db5a41875fc6f779c3434e12e Mon Sep 17 00:00:00 2001 From: Dominic Yin Date: Wed, 1 Apr 2020 12:06:36 +0800 Subject: [PATCH 1/6] zh-translation: update pod-security-policy.md (#17333) --- .../concepts/policy/pod-security-policy.md | 1174 ++++++++++++++--- 1 file changed, 1002 insertions(+), 172 deletions(-) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index 1573ff7af2..f50fa2409f 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -2,224 +2,1054 @@ approvers: - pweil- title: Pod 安全策略 +content_template: templates/concept +weight: 20 --- +{{% capture overview %}} -`PodSecurityPolicy` 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 `SecurityContext`。 -查看 [Pod 安全策略建议](https://git.k8s.io/community/contributors/design-proposals/security-context-constraints.md) 获取更多信息。 +{{< feature-state state="beta" >}} -{{< toc >}} + +PodSecurityPolicy支持针对 pod 创建和更新的精细的权限控制。 + +{{% /capture %}} + +{{% capture body %}} + +## 什么是 PodSecurityPolicy? -## 什么是 Pod 安全策略? - -_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 -`PodSecurityPolicy` 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。 + +_PodSecurityPolicy_ 是集群级别的资源,它能够控制 Pod 规范中对安全敏感的方面。 +[PodSecurityPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) +对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行,以及相关字段的默认值。 它们允许管理员控制如下方面: + +| 控制面 | 字段名称 | +|--------------------------------|----------------------------------------------------------------------------------------------| +| 已授权容器的运行 | [`privileged`](#privileged) | +| 主机 PID namespace 的使用 | [`hostPID`, `hostIPC`](#host-namespaces) | +| 主机网络的使用 | [`hostNetwork`,`hostPorts`](#host-namespaces) | +| 控制卷类型的使用 | [`volumes`](#volumes-and-file-systems) | +| 主机路径的使用 | [`allowedHostPaths`](#volumes-and-file-systems) | +| FlexVolume 卷驱动的白名单 | [`allowedFlexVolumes`](#flexvolume-drivers) | +| 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#volumes-and-file-systems) | +| 必须使用一个只读的 root 文件系统 | [`readOnlyRootFilesystem`(#volumes-and-file-systems) | +| 容器的用户和组的 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#users-and-groups) | +| 提升为 root 权限的限制 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | +| 为容器添加默认的一组能力 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | +| 容器的 SELinux 上下文 | [`seLinux`](#selinux) | +| 容器允许的 Proc 挂载类型 | [`allowedProcMountTypes`](#allowedprocmounttypes) | +| 容器使用的 AppArmor 配置文件 | [annotations](#apparmor) | +| 容器使用的 seccomp 配置文件 | [annotations](#seccomp) | +| 容器使用的 sysctl 配置文件 | [`forbiddenSysctls`,`allowedUnsafeSysctls`](#sysctl) | +## 启用 PodSecurityPolicy -Define the example PodSecurityPolicy object in a file. This is a policy that -simply prevents the creation of privileged pods. - -{{< codenew file="policy/example-psp.yaml" >}} - -And create it with kubectl: - -```shell -kubectl-admin create -f example-psp.yaml -``` + -### 创建一个策略和一个 Pod +PodSecurityPolicy 控制是 [admission 控制器](/docs/reference/access-authn-authz/admission-controllers/#podsecuritypolicy) +的一个可选实现。PodSecurityPolicy通过 [启用 admission 控制器](/docs/reference/access-authn-authz/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in) 被强制启用, +但是如果集群内没有授权任何策略时这样做 **将导致任何 pod 都无法被创建**。 + +由于 PodSecurityPolicy API (`policy/v1beta1/podsecuritypolicy`) 时独立于 admission 控制器启用的, +所以对于现有集群推荐在启用 admission 控制器之前就添加并授权安全策略。 + + +## 授权策略 + + +当一个 PodSecurityPolicy 资源被创建后,不会执行任何动作。想要应用这个策略,请求用户或者目标 pod 的 +[服务账户](/docs/tasks/configure-pod-container/configure-service-account/) 必须在策略中使用 `use` 动词,从而被授权使用这个策略。 + + +多数 Kubernetes pod 并非由用户直接创建。相反,通常他们作为 [Deployment](/docs/concepts/workloads/controllers/deployment/)、 +[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 或者其他的模板控制器的组成部分由控制器管理器被间接地创建。 +授权策略给控制器即授权给 **所有** 由该控制器创建的 pod,因此授权策略的授权方式应该时授权给 pod 的服务账户 (参见 [示例](#run-another-pod))。 + + +### 使用 RBAC + + +[RBAC](/docs/reference/access-authn-authz/rbac/) 是一个标准的 Kubernetes 授权模式,同时也能够方便地用于授权策 +略的使用。 + + +首先,需要有一个 `Role` 或者 `ClusterRole` 被授予访问权限来 `use` 预期策略。授予访问权限的策略如下所示: + + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: <角色名称> +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - <需要授权的策略列表> +``` + + +随后该 `(Cluster)Role` 即绑定给了授权的用户: + + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: <绑定名称> +roleRef: + kind: ClusterRole + name: <角色名称> + apiGroup: rbac.authorization.k8s.io +subjects: +# 授权给特定的服务账户: +- kind: ServiceAccount + name: <授权的服务账户名称> + namespace: <授权的 pod 命名空间> +# 授权给指定用户 (不推荐): +- kind: User + apiGroup: rbac.authorization.k8s.io + name: <授权的用户名> +``` + + +如果一个 `RoleBinding` (非 `ClusterRoleBinding`) 被使用,它只会授权给那些运行在与绑定相同命名空间下的 pod。 +这可以与系统组一起授权给所有运行在该命名空间下的所有 pod。 + + +```yaml +# 授权命名空间下的所有服务账户: +- kind: Group + apiGroup: rbac.authorization.k8s.io + name: system:serviceaccounts +# 或者同样的,授权给命名空间下的所有已验证的用户: +- kind: Group + apiGroup: rbac.authorization.k8s.io + name: system:authenticated +``` + + +更多关于 RBAC 绑定的示例,查看 [角色绑定示例](/docs/reference/access-authn-authz/rbac#role-binding-examples)。 +关于授权 PodSecurityPolicy 的完整示例,查看 [下面](#example)。 + + +### 故障诊断 + + +- [控制器管理器](/docs/admin/kube-controller-manager/) 必须运行于 [安全的 API 端口](/docs/reference/access-authn-authz/controlling-access/), +并且必须不能具备超级用户权限。否则请求将可绕过身份验证和授权模块,所有的 PodSecurityPolicy 对象将被允许,并且所有的用户将能够创建特权容器。 +关于配置控制器管理器授权的更多细节,查看 [控制器角色](/docs/reference/access-authn-authz/rbac/#controller-roles)。 + + +## 策略顺序 + + +除了限制 pod 的创建和更新之外,PodSecurityPolicy 也可以用于为由其控制的许多字段提供默认值。当同时多个策略可用时,PodSecurityPolicy 控制器依据以下标准选择策略: + + +1. 允许 pod 维持原状,不改变默认设置或者变更 pod 的 PodSecurityPolicy 是首选。这些非变更的 PodSecurityPolicy 的顺序无关紧要。 +2. 如果 pod 必须默认或者变更,则使用第一个 PodSecurityPolicy(按名称排序)以允许该 pod。 + +{{< note >}} + +在更新操作期间(在 pod 规范不允许变更的期间)只有非变更的 PodSecurityPolicy 会用于校验 pod。 +{{< /note >}} + + +## 示例 + + +_这个示例假定你有一个运行中且已启用 PodSecurityPolicy admission 控制器的集群,并且你拥有集群管理员权限。_ + + +### 设置 + + +以此为例设置一个命名空间和服务账户. 我们将使用这个服务账户来模拟一个非管理员用户. + +```shell +kubectl create namespace psp-example +kubectl create serviceaccount -n psp-example fake-user +kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user +``` + + +为了清晰展示我们所演示的具体用户以及省去一些键入操作,首先创建两个别名: + +```shell +alias kubectl-admin='kubectl -n psp-example' +alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example' +``` + + +### 创建一个策略和一个 pod + + 在一个文件中定义 PodSecurityPolicy 对象实例。这里的策略只是用来禁止创建有特权 -要求的 Pods。 +要求的 Pods。 PodSecurityPolicy 对象的命名必须是合法的 [DNS 子域名](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names). {{< codenew file="policy/example-psp.yaml" >}} -使用 kubectl 执行创建操作: + +然后通过 kubectl 命名创建它: ```shell kubectl-admin create -f example-psp.yaml ``` -## 获取 Pod 安全策略列表 - -获取已存在策略列表,使用 `kubectl get`: + +现在作为一个非特权用户, 尝试创建一个简单的 pod: ```shell -$ kubectl get psp -NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES -permissive false [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] -privileged true [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] -restricted false [] RunAsAny MustRunAsNonRoot RunAsAny RunAsAny false [emptyDir secret downwardAPI configMap persistentVolumeClaim projected] +kubectl-user create -f- < +***发生了什么?* 尽管 PodSecurityPolicy 已经创建, pod 的 service account 和 `fake-user` 都没有权限使用这个策略: ```shell -$ kubectl edit psp permissive +kubectl-user auth can-i use podsecuritypolicy/example +no ``` + +创建 rolebinding 来为示例策略中的 `fake-user` 的 `use` 动词授权: - -该命令将打开一个默认文本编辑器,在这里能够修改策略。 - - - -## 删除 Pod 安全策略 - -一旦不再需要一个策略,很容易通过 `kubectl` 删除它: +{{< note >}} + +不推荐这种方式! 更推荐的方式请查看 [下一部分](#run-another-pod). +{{< /note >}} ```shell -$ kubectl delete psp permissive -podsecuritypolicy "permissive" deleted +kubectl-admin create role psp:unprivileged \ + --verb=use \ + --resource=podsecuritypolicy \ + --resource-name=example +role "psp:unprivileged" created + +kubectl-admin create rolebinding fake-user:psp:unprivileged \ + --role=psp:unprivileged \ + --serviceaccount=psp-example:fake-user +rolebinding "fake-user:psp:unprivileged" created + +kubectl-user auth can-i use podsecuritypolicy/example +yes ``` + +接下来尝试创建这个 pod: + +```shell +kubectl-user create -f- < +它按预期运行,但是任何创建特权 pod 的尝试应当都被拒绝: + +```shell +kubectl-user create -f- < +在继续下一步之前先删掉之前的 pod: + +```shell +kubectl-user delete pod pause +``` + + +### 运行另一个 pod + + +我们来再试一次, 相比之前略微有些不同: + +```shell +kubectl-user run pause --image=k8s.gcr.io/pause +deployment "pause" created + +kubectl-user get pods +No resources found. + +kubectl-user get events | head -n 2 +LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE +1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request +``` + + +**发生了什么?**我们已经将 `psp:unprivileged` 角色绑定给了 `fake-user`, 为何仍然报错 +`Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request`? +答案在 `replicaset-controller` 源码中. Fake-user 成功创建了 deployment (并且该 deployment 成功创建了一个 replicaset), +然而当该 replicaset 想要创建 pod 时却没有权限使用我们的示例 pod 安全策略. + + +为了修复这个问题,将 `psp:unprivileged` 角色绑定给 pod 的 service account. 在这种情况下(由于我们没有显式指定) 该 service account 为 `default`: + +```shell +kubectl-admin create rolebinding default:psp:unprivileged \ + --role=psp:unprivileged \ + --serviceaccount=psp-example:default +rolebinding "default:psp:unprivileged" created +``` + + +现在如果你给它一分钟让它重试, replicaset-controller 应该最终能够成功创建出 pod: + +```shell +kubectl-user get pods --watch +NAME READY STATUS RESTARTS AGE +pause-7774d79b5-qrgcb 0/1 Pending 0 1s +pause-7774d79b5-qrgcb 0/1 Pending 0 1s +pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s +pause-7774d79b5-qrgcb 1/1 Running 0 2s +``` + + +### 清理 + + +删除命名空间来清理大部分示例资源: + +```shell +kubectl-admin delete ns psp-example +namespace "psp-example" deleted +``` + + +注意 `PodSecurityPolicy` 并非命名空间限定的资源类型, 必须单独清理: + +```shell +kubectl-admin delete psp example +podsecuritypolicy "example" deleted +``` + + +### 示例策略 + + +这是一个你能够创建的最小化的限制性策略, 相当于不使用 pod 安全策略准入控制器: + +{{< codenew file="policy/privileged-psp.yaml" >}} + + +这是一个限制性策略示例,要求用户以非特权用户运行, 屏蔽了权限提升至 root 的可能性, 同时需要使用几个安全机制. + +{{< codenew file="policy/restricted-psp.yaml" >}} + + +## 策略参考 + + +### 特权 + + +**特权** - 决定 pod 中的任意容器能否启用特权模式。默认情况下一个容器不允许访问主机上的任意设备, 但是一个 "特权" 容器是允许访问主机上的所有设备的。 +这样容器具备的权限几乎等同于主机上运行的进程。 这对于像比如操作网络堆栈和访问设备等需要使用 linux capabilities 的容器来说非常有用。 + + +### 主机命名空间 + + +**HostPID** - 控制 pod 容器能否共享主机进程 ID 命名空间。 注意当它与 ptrace 搭配使用时可被利用于在容器外部提升权限(ptrace 默认被禁用)。 + + +**HostIPC** - 控制 pod 容器能够共享主机 IPC + + +**HostNetwork** - 控制 pod 能否使用节点网络命名空间。 这样做可允许 pod 访问回环设备、监听 localhost 的服务以及能够用于探测同意节点上其他 pod 的网络活动。 + + +**HostPorts** - 提供主机网络名称空间中允许端口范围的白名单。定义为 `HostPortRange` 列表,其中包含 `min(包含)` 和 `max(包含)`。默认不允许任何主机端口。 + + +### 存储卷和文件系统 + + +**Volumes** - 提供允许的存储卷类型的白名单。允许值对应于在创建卷时定义的源卷。完整的卷类型列表,请查阅 [卷类型](/docs/concepts/storage/volumes/#types-of-volumes)。 +此外 `*` 可用于允许所有卷类型。 + + +对于新 PSP 允许的卷**推荐的最小化组合** 是: + +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- secret +- projected + +{{< warning >}} + +PodSecurityPolicy 并不会对可能被 `PersistentVolumeClaim` 引用的 `PersistentVolume` 资源对象的类型做限制, +并且 hostPath 类型的 `PersistentVolumes` 并不支持只读访问模式。只有可信用户才应当给予创建 `PersistentVolume` 资源对象的权限。 +{{< /warning >}} + + +**FSGroup** - 控制应用于某些卷的补充组。 + + +- *MustRunAs* - 要求至少指定一个 `range`。使用第一个范围的最小值作为默认值。针对所有范围进行验证。 +- *MayRunAs* - 要求至少指定一个 `range`。允许 `FSGroups` 不提供默认设置。如果设置了 `FSGroups`, +则针对所有范围进行验证。 +- *RunAsAny* - 不提供默认值。允许指定任意 `fsGroup` ID。 + + +**AllowedHostPaths** - 它指定主机路径的白名单,允许 hostPath 卷使用这些白名单。空列表意味着对使用的主机路径没有限制。 +这被定义为一个对象列表,其中有一个 `pathPrefix` 字段,它允许 hostPath 卷挂载一个以允许的前缀开头的路径,以及一个 `readOnly` 字段, +表示它必须以只读方式挂载。例如: + +```yaml +allowedHostPaths: + # This allows "/foo", "/foo/", "/foo/bar" etc., but + # disallows "/fool", "/etc/foo" etc. + # "/foo/../" is never valid. + - pathPrefix: "/foo" + readOnly: true # only allow read-only mounts +``` + +{{< warning >}} + +对于能够无限制访问主机文件系统的容器来说,有许多方式可以进行特权提升,包括从其他容器读取数据,以及滥用系统服务(如 Kubelet)的凭据。 + +可写的 hostPath 目录卷允许容器以允许它们在 `pathPrefix` 之外遍历主机文件系统的方式写入文件系统。`readOnly: true` 在 Kubernetes 1.11+ 可用, +必须应用于 **所有** `allowedHostPaths` 以有效限制对指定 `pathPrefix` 的访问。 +{{< /warning >}} + + +**ReadOnlyRootFilesystem** - 要求容器必须运行于一个只读的根文件系统(即不可写的层)。 + + +### FlexVolume 驱动 + + +这指定了 FlexVolume 驱动程序的白名单,允许 FlexVolume 使用这些驱动程序。空列表或 nil 表示对驱动程序没有限制。 +请确保 [`volumes`](#volumes-and-file-systems) 字段包含 `flexVolume` 卷类型;否则任何 FlexVolume 驱动都不允许。 + + +例如: + +```yaml +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: allow-flex-volumes +spec: + # ... other spec fields + volumes: + - flexVolume + allowedFlexVolumes: + - driver: example/lvm + - driver: example/cifs +``` + + +### 用户和组 + + +**RunAsUser** - 控制容器以哪个用户 ID 运行。 + + +- *MustRunAs* - 要求至少指定一个 `range`。使用第一个范围的最小值作为默认值。针对所有范围进行验证。 +- *MustRunAsNonRoot* - 要求 pod 使用非零的 `runAsUser` 提交,或者在镜像中定义 `USER` 命令 (使用数字 UID)。 +没有指定 `runAsNonRoot` 或 `runAsUser` 设置的 pod 将被修改为设置 `runAsNonRoot=true`, +因此需要在容器中定义一个非零的数字 `USER` 命令。不提供默认值。这个策略强烈建议设置 `allowPrivilegeEscalation=false`。 +- *RunAsAny* - 不提供默认值。允许指定任意 `runAsUser`。 + + +**RunAsGroup** - 控制容器以哪个首要组 ID 运行。 + + +- *MustRunAs* - 要求至少指定一个 `range`。使用第一个范围的最小值作为默认值。针对所有范围进行验证。 +- *MayRunAs* - 不要求指定 RunAsGroup。但是,当指定 RunAsGroup 时,它们必须落在定义的范围内。 +- *RunAsAny* - 不提供默认值。允许指定任意 `runAsGroup`。 + + +**SupplementalGroups** - 控制容器添加那些组 ID。 + + +- *MustRunAs* - 要求至少指定一个 `range`。使用第一个范围的最小值作为默认值。针对所有范围进行验证。 +- *MayRunAs* - 要求至少指定一个 `range`。允许在不提供默认值的情况下不设置 `supplementalGroups`。 +如果设置了 `supplementalGroups`,则对所有范围进行验证。 +- *RunAsAny* - 不提供默认值。允许指定任意 `supplementalGroups`。 + + +### 特权提升 + + +这个选项控制容器的 `allowPrivilegeEscalation` 选项。这个布尔值直接控制 [`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt) +标志是否设置到容器进程上。这个标志将防止 `setuid` 二进制文件改变有效的用户 ID,并防止文件启用额外的功能 (例如,它将防止使用 `ping` 工具)。 +这种行为前提是需要有效地强制指定 `MustRunAsNonRoot`。 + + +**AllowPrivilegeEscalation** - 是否允许用户将容器的安全上下文设置为 `allowPrivilegeEscalation=true`。 +这是默认设置,以便不破坏 setuid 二进制文件。将其设置为 `false` 可以确保容器的子进程不能获得比其父进程更多的特权。 + + +**DefaultAllowPrivilegeEscalation** - 设置 `allowPrivilegeEscalation` 选项的默认值。没有这个设置的默认行为是允许 +特权升级,以避免破坏 setuid 二进制文件。如果这种行为并非有意,可以使此字段默认为不允许,但仍然允许 +显式请求 `allowPrivilegeEscalation` 的 pods。 + + +### 能力 + + +Linux 能力提供了对传统上与超级用户相关的特权的细粒度分解。其中一些能力可用于特权提升或容器断接,并且可能受到 PodSecurityPolicy 的限制。 +有关Linux功能的更多信息,查看 [capabilities(7)](http://man7.org/linux/man-pages/man7/capabilities.7.html)。 + + +以下字段列出了能力列表,在 ALL_CAPS 中指定为不带 `CAP_` 前缀的能力名称。 + + +**AllowedCapabilities** - 提供可添加到容器中的能力白名单。默认的能力集是隐式允许的。 +空集意味着在默认集之外不能添加任何附加能力。`*` 可用于允许所有能力。 + + +**RequiredDropCapabilities** - 必须从容器中删除的能力。这些能力将从默认设置中删除,并且不能被添加。 +在 `requireddropcapability` 中列出的能力不能包含在 `allowedcapability` 或 `defaultaddcapability` 中。 + + +**DefaultAddCapabilities** - 除了运行时默认设置外,默认添加到容器中的能力。查看 [Docker 文档](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) 中关于使用 Docker 运行时时默认的能力列表。 + +### SELinux + +- *MustRunAs* - 要求设置 `seLinuxOptions`。使用 `seLinuxOptions` 作为默认值。针对所有范围进行验证。 +- *RunAsAny* - 不提供默认值。允许指定任意 `seLinuxOptions`。 -## 启用 Pod 安全策略 +### AllowedProcMountTypes -为了能够在集群中使用 Pod 安全策略,必须确保满足如下条件: + +`allowedProcMountTypes` 是允许 ProcMountTypes 的白名单。空列表或 nil 表示只允许 `DefaultProcMountType` 指定的默认值。 + +`DefaultProcMount` 对只读路径使用容器运行时默认值,对/proc 使用掩码路径。大多数容器运行时屏蔽 /proc 中的某些路径, +以避免特殊设备或信息的意外安全性暴露。使用字符串 `Default` 表示。 + +另一个 ProcMountType 是 `UnmaskedProcMount`,它绕过了容器运行时的默认屏蔽行为,并确保新创建的 /proc 容器保持不变。 +使用字符串 `unmask` 表示。 -1. 已经启用 API 类型 `extensions/v1beta1/podsecuritypolicy`(仅对 1.6 之前的版本) -1. 已经启用许可控制器 `PodSecurityPolicy` -1. 已经定义了自己的策略 +### AppArmor + +通过 PodSecurityPolicy 上面的注解进行控制。参考 [AppArmor +文档](/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)。 +### Seccomp -## 使用 RBAC + +可以通过 PodSecurityPolicy 上的注解来控制 pod 中 seccomp 配置文件的使用。 +Seccomp 是 Kubernetes 的一个 alpha 特性。 -在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 来控制,对基于用户角色和组的已授权容器的访问。访问不同的 PodSecurityPolicy 对象,可以基于认证来控制。基于 Deployment、ReplicaSet 等创建的 Pod,限制访问 PodSecurityPolicy 对象,[Controller Manager](/docs/admin/kube-controller-manager/) 必须基于安全 API 端口运行,并且不能够具有超级用户权限。 + +**seccomp.security.alpha.kubernetes.io/defaultProfileName** - 指定要应用于容器的默认 seccomp 配置文件的注解。 +可选值有: -PodSecurityPolicy 认证使用所有可用的策略,包括创建 Pod 的用户,Pod 上指定的服务账户(Service Account)。当 Pod 基于 Deployment、ReplicaSet 创建时,它是创建 Pod 的 Controller Manager,所以如果基于非安全 API 端口运行,允许所有的 PodSecurityPolicy 对象,并且不能够有效地实现细分权限。用户访问给定的 PSP 策略有效,仅当是直接部署 Pod 的情况。更多详情,查看 [PodSecurityPolicy RBAC 示例](https://git.k8s.io/kubernetes/examples/podsecuritypolicy/rbac/README.md),当直接部署 Pod 时,应用 PodSecurityPolicy 控制基于角色和组的已授权容器的访问 。 + +- `unconfined` - 如果没有提供替代方案,则 Seccomp 不会应用于容器进程 (这是 Kubernetes 中的默认设置)。 +- `runtime/default` - 使用默认的容器运行时配置。 +- `docker/default` - 使用 Docker 默认的 seccomp 配置。于 Kubernetes 1.11 弃用。使用 `runtime/default` 代替。 +- `localhost/` - 将配置文件指定为位于节点上 `/` 目录下的文件, +其中通过 Kubelet 上的 `--seccomp-profile-root` 标志来定义 ``。 + + +**seccomp.security.alpha.kubernetes.io/allowedProfileNames** - 用于指定 pod seccomp 注解允许哪些取值的注解。 +指定为允许值的逗号分隔列表。可选值是上面列出的值,加上 `*` 以允许所有配置文件。缺少此注解意味着无法更改默认值。 + +### Sysctl + + +默认情况下允许所有安全的 sysctl。 + + +- `forbiddenSysctls` - 排除特定的 sysctl。您可以在列表中禁止安全的和不安全的 sysctl 的组合。要禁止设置任意 sysctl,请单独使用 `*`。 +- `allowedUnsafeSysctls` - 允许在默认列表中被禁用的特定 sysctl,只要这些 sysctl 没有在 `forbiddenSysctls` 中列出。 + + +参考 [Sysctl 文档]( +/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy)。 +{{% /capture %}} + +{{% capture whatsnext %}} + + + +{{% /capture %}} \ No newline at end of file From de8898ba55ed97aab67ad97be524282807ec6a0c Mon Sep 17 00:00:00 2001 From: Dominic Yin Date: Wed, 1 Apr 2020 12:18:17 +0800 Subject: [PATCH 2/6] addendum for pod-security-policy.md --- content/zh/docs/concepts/policy/pod-security-policy.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index f50fa2409f..118367b247 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -1051,5 +1051,6 @@ Refer to the [Sysctl documentation]( +关于 api 细节参考 [Pod 安全策略指南](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy)。 {{% /capture %}} \ No newline at end of file From 7881e33c91b786b28e4287d12e2dd44a34ac31ac Mon Sep 17 00:00:00 2001 From: Dominic Yin Date: Thu, 2 Apr 2020 09:28:03 +0800 Subject: [PATCH 3/6] Update content/zh/docs/concepts/policy/pod-security-policy.md Co-Authored-By: Qiming Teng --- content/zh/docs/concepts/policy/pod-security-policy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index 118367b247..136ad490b7 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -14,7 +14,7 @@ weight: 20 Pod Security Policies enable fine-grained authorization of pod creation and updates. --> -PodSecurityPolicy支持针对 pod 创建和更新的精细的权限控制。 +PodSecurityPolicy支持针对 pod 创建和更新进行精细的权限控制。 {{% /capture %}} @@ -1053,4 +1053,4 @@ Refer to [Pod Security Policy Reference](/docs/reference/generated/kubernetes-ap --> 关于 api 细节参考 [Pod 安全策略指南](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy)。 -{{% /capture %}} \ No newline at end of file +{{% /capture %}} From 43773ac2da0f2ab24e0ac5c363ae181f3a555e2d Mon Sep 17 00:00:00 2001 From: Dominic Yin Date: Thu, 2 Apr 2020 09:56:36 +0800 Subject: [PATCH 4/6] update zh-trans of pod-security-policy.md --- .../concepts/policy/pod-security-policy.md | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index 136ad490b7..18ad2039d3 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -14,7 +14,7 @@ weight: 20 Pod Security Policies enable fine-grained authorization of pod creation and updates. --> -PodSecurityPolicy支持针对 pod 创建和更新进行精细的权限控制。 +Pod 安全策略支持针对 pod 创建和更新进行精细的权限控制。 {{% /capture %}} @@ -24,7 +24,7 @@ PodSecurityPolicy支持针对 pod 创建和更新进行精细的权限控制。 -## 什么是 PodSecurityPolicy? +## 什么是 Pod 安全策略? -_PodSecurityPolicy_ 是集群级别的资源,它能够控制 Pod 规范中对安全敏感的方面。 +_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 规范中对安全敏感的方面。 [PodSecurityPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) -对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行,以及相关字段的默认值。 +对象定义了一组 pod 必须在其上运行才能被系统接受的条件,以及相关字段的默认设置。 它们允许管理员控制如下方面: -| 控制面 | 字段名称 | -|--------------------------------|----------------------------------------------------------------------------------------------| -| 已授权容器的运行 | [`privileged`](#privileged) | -| 主机 PID namespace 的使用 | [`hostPID`, `hostIPC`](#host-namespaces) | +| 所控制的方面 | 字段名称 | +|----------------------------------|----------------------------------------------------------------------------------------------| +| 运行特权容器 | [`privileged`](#privileged) | +| 使用主机 PID 的命名空间 | [`hostPID`, `hostIPC`](#host-namespaces) | | 主机网络的使用 | [`hostNetwork`,`hostPorts`](#host-namespaces) | | 控制卷类型的使用 | [`volumes`](#volumes-and-file-systems) | | 主机路径的使用 | [`allowedHostPaths`](#volumes-and-file-systems) | | FlexVolume 卷驱动的白名单 | [`allowedFlexVolumes`](#flexvolume-drivers) | | 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#volumes-and-file-systems) | -| 必须使用一个只读的 root 文件系统 | [`readOnlyRootFilesystem`(#volumes-and-file-systems) | +| 必须使用一个只读的 root 文件系统 | [`readOnlyRootFilesystem`(#volumes-and-file-systems) | | 容器的用户和组的 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#users-and-groups) | -| 提升为 root 权限的限制 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | -| 为容器添加默认的一组能力 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | +| 限制提升为 root 特权 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | +| 为容器添加默认的一组能力 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | | 容器的 SELinux 上下文 | [`seLinux`](#selinux) | -| 容器允许的 Proc 挂载类型 | [`allowedProcMountTypes`](#allowedprocmounttypes) | -| 容器使用的 AppArmor 配置文件 | [annotations](#apparmor) | -| 容器使用的 seccomp 配置文件 | [annotations](#seccomp) | -| 容器使用的 sysctl 配置文件 | [`forbiddenSysctls`,`allowedUnsafeSysctls`](#sysctl) | +| 容器允许的 Proc 挂载类型 | [`allowedProcMountTypes`](#allowedprocmounttypes) | +| 容器使用的 AppArmor 配置 | [annotations](#apparmor) | +| 容器使用的 seccomp 配置 | [annotations](#seccomp) | +| 容器使用的 sysctl 配置 | [`forbiddenSysctls`,`allowedUnsafeSysctls`](#sysctl) | -## 启用 PodSecurityPolicy +## 启用 Pod 安全策略 -PodSecurityPolicy 控制是 [admission 控制器](/docs/reference/access-authn-authz/admission-controllers/#podsecuritypolicy) +Pod 安全策略控制是 [admission 控制器](/docs/reference/access-authn-authz/admission-controllers/#podsecuritypolicy) 的一个可选实现。PodSecurityPolicy通过 [启用 admission 控制器](/docs/reference/access-authn-authz/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in) 被强制启用, 但是如果集群内没有授权任何策略时这样做 **将导致任何 pod 都无法被创建**。 @@ -103,7 +103,7 @@ enabled independently of the admission controller, for existing clusters it is recommended that policies are added and authorized before enabling the admission controller. --> -由于 PodSecurityPolicy API (`policy/v1beta1/podsecuritypolicy`) 时独立于 admission 控制器启用的, +由于 Pod 安全策略 API (`policy/v1beta1/podsecuritypolicy`) 时独立于 admission 控制器启用的, 所以对于现有集群推荐在启用 admission 控制器之前就添加并授权安全策略。 多数 Kubernetes pod 并非由用户直接创建。相反,通常他们作为 [Deployment](/docs/concepts/workloads/controllers/deployment/)、 [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 或者其他的模板控制器的组成部分由控制器管理器被间接地创建。 -授权策略给控制器即授权给 **所有** 由该控制器创建的 pod,因此授权策略的授权方式应该时授权给 pod 的服务账户 (参见 [示例](#run-another-pod))。 +授权策略给控制器即授权给 **所有** 由该控制器创建的 pod,因此授权策略的授权方式应该时授权给 pod 的 service account (参见 [示例](#run-another-pod))。 ```yaml -# 授权命名空间下的所有服务账户: +# 授权命名空间下的所有 service accounts: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:serviceaccounts @@ -294,7 +294,7 @@ also be used to provide default values for many of the fields that it controls. When multiple policies are available, the pod security policy controller selects policies according to the following criteria: --> -除了限制 pod 的创建和更新之外,PodSecurityPolicy 也可以用于为由其控制的许多字段提供默认值。当同时多个策略可用时,PodSecurityPolicy 控制器依据以下标准选择策略: +除了限制 pod 的创建和更新之外,pod 安全策略也可以用于为由其控制的许多字段提供默认值。当同时多个策略可用时,pod 安全策略控制器依据以下标准选择策略: -以此为例设置一个命名空间和服务账户. 我们将使用这个服务账户来模拟一个非管理员用户. +以此为例设置一个命名空间和 service account. 我们将使用这个 service account 来模拟一个非管理员用户. ```shell kubectl create namespace psp-example @@ -401,7 +401,7 @@ Error from server (Forbidden): error when creating "STDIN": pods "pause" is forb **What happened?** Although the PodSecurityPolicy was created, neither the pod's service account nor `fake-user` have permission to use the new policy: --> -***发生了什么?* 尽管 PodSecurityPolicy 已经创建, pod 的 service account 和 `fake-user` 都没有权限使用这个策略: +**发生了什么?** 尽管 PodSecurityPolicy 已经创建, pod 的 service account 和 `fake-user` 都没有权限使用这个策略: ```shell kubectl-user auth can-i use podsecuritypolicy/example @@ -441,7 +441,7 @@ yes -接下来尝试创建这个 pod: +现在重新创建这个 pod: ```shell kubectl-user create -f- < -它按预期运行,但是任何创建特权 pod 的尝试应当都被拒绝: +它如期运行,但是任何创建特权 pod 的尝试都应当被拒绝: ```shell kubectl-user create -f- < -**发生了什么?**我们已经将 `psp:unprivileged` 角色绑定给了 `fake-user`, 为何仍然报错 +**发生了什么?** 我们已经将 `psp:unprivileged` 角色绑定给了 `fake-user`, 为何仍然报错 `Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request`? 答案在 `replicaset-controller` 源码中. Fake-user 成功创建了 deployment (并且该 deployment 成功创建了一个 replicaset), 然而当该 replicaset 想要创建 pod 时却没有权限使用我们的示例 pod 安全策略. @@ -529,7 +529,7 @@ In order to fix this, bind the `psp:unprivileged` role to the pod's service account instead. In this case (since we didn't specify it) the service account is `default`: --> -为了修复这个问题,将 `psp:unprivileged` 角色绑定给 pod 的 service account. 在这种情况下(由于我们没有显式指定) 该 service account 为 `default`: +为了修复这个问题,将 `psp:unprivileged` 角色绑定给 pod 的 service account. 在这种情况下(由于我们没有显式指定) 该 service account 为 `default`: ```shell kubectl-admin create rolebinding default:psp:unprivileged \ @@ -780,7 +780,7 @@ kind: PodSecurityPolicy metadata: name: allow-flex-volumes spec: - # ... other spec fields + # ... 其他特性字段 volumes: - flexVolume allowedFlexVolumes: From 9f1f586ffe5f213e47be2224e86e930b5a1967d8 Mon Sep 17 00:00:00 2001 From: Dominic Yin Date: Fri, 3 Apr 2020 16:50:28 +0800 Subject: [PATCH 5/6] Update content/zh/docs/concepts/policy/pod-security-policy.md Co-Authored-By: Qiming Teng --- content/zh/docs/concepts/policy/pod-security-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index 18ad2039d3..6b385d3330 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -132,7 +132,7 @@ pod's service account (see [example](#run-another-pod)). --> 多数 Kubernetes pod 并非由用户直接创建。相反,通常他们作为 [Deployment](/docs/concepts/workloads/controllers/deployment/)、 [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 或者其他的模板控制器的组成部分由控制器管理器被间接地创建。 -授权策略给控制器即授权给 **所有** 由该控制器创建的 pod,因此授权策略的授权方式应该时授权给 pod 的 service account (参见 [示例](#run-another-pod))。 +将访问权限授予控制器即相当于授权给 **所有** 由该控制器创建的 Pod,因此推荐的鉴权策略的方式是为 Pod 的服务账号授权(参见 [示例](#run-another-pod))。 **特权** - 决定 pod 中的任意容器能否启用特权模式。默认情况下一个容器不允许访问主机上的任意设备, 但是一个 "特权" 容器是允许访问主机上的所有设备的。 -这样容器具备的权限几乎等同于主机上运行的进程。 这对于像比如操作网络堆栈和访问设备等需要使用 linux capabilities 的容器来说非常有用。 +这样容器具备的权限几乎等同于主机上运行的进程。 这对于像比如操作网络堆栈和访问设备等需要使用 linux 权能字的容器来说非常有用。 这个选项控制容器的 `allowPrivilegeEscalation` 选项。这个布尔值直接控制 [`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt) -标志是否设置到容器进程上。这个标志将防止 `setuid` 二进制文件改变有效的用户 ID,并防止文件启用额外的功能 (例如,它将防止使用 `ping` 工具)。 +标志是否设置到容器进程上。这个标志将防止 `setuid` 二进制文件改变有效的用户 ID,并防止文件启用额外的权能字 (例如,它将防止使用 `ping` 工具)。 这种行为前提是需要有效地强制指定 `MustRunAsNonRoot`。 -### 能力 +### 权能字 -Linux 能力提供了对传统上与超级用户相关的特权的细粒度分解。其中一些能力可用于特权提升或容器断接,并且可能受到 PodSecurityPolicy 的限制。 +Linux 权能字提供了对传统上与超级用户相关的特权的细粒度分解。其中一些权能字可用于特权提升或容器断接,并且可能受到 PodSecurityPolicy 的限制。 有关Linux功能的更多信息,查看 [capabilities(7)](http://man7.org/linux/man-pages/man7/capabilities.7.html)。 -以下字段列出了能力列表,在 ALL_CAPS 中指定为不带 `CAP_` 前缀的能力名称。 +以下字段列出了权能字列表,在 ALL_CAPS 中指定为不带 `CAP_` 前缀的权能字名称。 -**AllowedCapabilities** - 提供可添加到容器中的能力白名单。默认的能力集是隐式允许的。 -空集意味着在默认集之外不能添加任何附加能力。`*` 可用于允许所有能力。 +**AllowedCapabilities** - 提供可添加到容器中的权能字白名单。默认的权能字集是隐式允许的。 +空集意味着在默认集之外不能添加任何附加权能字。`*` 可用于允许所有权能字。 -**RequiredDropCapabilities** - 必须从容器中删除的能力。这些能力将从默认设置中删除,并且不能被添加。 -在 `requireddropcapability` 中列出的能力不能包含在 `allowedcapability` 或 `defaultaddcapability` 中。 +**RequiredDropCapabilities** - 必须从容器中删除的权能字。这些权能字将从默认设置中删除,并且不能被添加。 +在 `requireddropcapability` 中列出的权能字不能包含在 `allowedcapability` 或 `defaultaddcapability` 中。 -**DefaultAddCapabilities** - 除了运行时默认设置外,默认添加到容器中的能力。查看 [Docker 文档](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) 中关于使用 Docker 运行时时默认的能力列表。 +**DefaultAddCapabilities** - 除了运行时默认设置外,默认添加到容器中的权能字。查看 [Docker 文档](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) 中关于使用 Docker 运行时时默认的权能字列表。 ### SELinux