From b9e7236373c580e0159bd7e3acca8f8ce7d3efe2 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Mon, 13 Apr 2020 09:06:52 +0800 Subject: [PATCH] Revert "zh-translation: update pod-security-policy.md (#17333)" --- .../concepts/policy/pod-security-policy.md | 1173 +++-------------- 1 file changed, 171 insertions(+), 1002 deletions(-) diff --git a/content/zh/docs/concepts/policy/pod-security-policy.md b/content/zh/docs/concepts/policy/pod-security-policy.md index 587e8ad275..1573ff7af2 100644 --- a/content/zh/docs/concepts/policy/pod-security-policy.md +++ b/content/zh/docs/concepts/policy/pod-security-policy.md @@ -2,1055 +2,224 @@ approvers: - pweil- title: Pod 安全策略 -content_template: templates/concept -weight: 20 --- -{{% capture overview %}} -{{< feature-state state="beta" >}} +`PodSecurityPolicy` 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 `SecurityContext`。 +查看 [Pod 安全策略建议](https://git.k8s.io/community/contributors/design-proposals/security-context-constraints.md) 获取更多信息。 + +{{< toc >}} - -Pod 安全策略支持针对 pod 创建和更新进行精细的权限控制。 - -{{% /capture %}} - -{{% capture body %}} - ## 什么是 Pod 安全策略? - -_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 规范中对安全敏感的方面。 -[PodSecurityPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) -对象定义了一组 pod 必须在其上运行才能被系统接受的条件,以及相关字段的默认设置。 +_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 +`PodSecurityPolicy` 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。 它们允许管理员控制如下方面: - -| 所控制的方面 | 字段名称 | -|----------------------------------|----------------------------------------------------------------------------------------------| -| 运行特权容器 | [`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) | -| 容器的用户和组的 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) | + +| 控制面 | 字段名称 | +| ------------------------------------------------------------- | --------------------------------- | +| 已授权容器的运行 | `privileged` | +| 为容器添加默认的一组能力 | `defaultAddCapabilities` | +| 为容器去掉某些能力 | `requiredDropCapabilities` | +| 容器能够请求添加某些能力 | `allowedCapabilities` | +| 控制卷类型的使用 | [`volumes`](#controlling-volumes) | +| 主机网络的使用 | [`hostNetwork`](#host-network) | +| 主机端口的使用 | `hostPorts` | +| 主机 PID namespace 的使用 | `hostPID` | +| 主机 IPC namespace 的使用 | `hostIPC` | +| 主机路径的使用 | [`allowedHostPaths`](#allowed-host-paths) | +| 容器的 SELinux 上下文 | [`seLinux`](#selinux) | +| 用户 ID | [`runAsUser`](#runasuser) | +| 配置允许的补充组 | [`supplementalGroups`](#supplementalgroups) | +| 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#fsgroup) | +| 必须使用一个只读的 root 文件系统 | `readOnlyRootFilesystem` | + + + +_Pod 安全策略_ 由设置和策略组成,它们能够控制 Pod 访问的安全特征。这些设置分为如下三类: + +- *基于布尔值控制* :这种类型的字段默认为最严格限制的值。 +- *基于被允许的值集合控制* :这种类型的字段会与这组值进行对比,以确认值被允许。 +- *基于策略控制* :设置项通过一种策略提供的机制来生成该值,这种机制能够确保指定的值落在被允许的这组值中。 + + + +### RunAsUser + + + +- *MustRunAs* - 必须配置一个 `range`。使用该范围内的第一个值作为默认值。验证是否不在配置的该范围内。 +- *MustRunAsNonRoot* - 要求提交的 Pod 具有非零 `runAsUser` 值,或在镜像中定义了 `USER` 环境变量。不提供默认值。 +- *RunAsAny* - 没有提供默认值。允许指定任何 `runAsUser` 。 + + + +### SELinux + +- *MustRunAs* - 如果没有使用预分配的值,必须配置 `seLinuxOptions`。默认使用 `seLinuxOptions`。验证 `seLinuxOptions`。 +- *RunAsAny* - 没有提供默认值。允许任意指定的 `seLinuxOptions` ID。 + + + +### SupplementalGroups + +- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证所有范围的值。 +- *RunAsAny* - 没有提供默认值。允许任意指定的 `supplementalGroups` ID。 + + + +### FSGroup + +- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证在第一个范围内的第一个 ID。 +- *RunAsAny* - 没有提供默认值。允许任意指定的 `fsGroup` ID。 + + + +### 控制卷 + +通过设置 PSP 卷字段,能够控制具体卷类型的使用。当创建一个卷的时候,与该字段相关的已定义卷可以允许设置如下值: + +1. azureFile +1. azureDisk +1. flocker +1. flexVolume +1. hostPath +1. emptyDir +1. gcePersistentDisk +1. awsElasticBlockStore +1. gitRepo +1. secret +1. nfs +1. iscsi +1. glusterfs +1. persistentVolumeClaim +1. rbd +1. cinder +1. cephFS +1. downwardAPI +1. fc +1. configMap +1. vsphereVolume +1. quobyte +1. projected +1. portworxVolume +1. scaleIO +1. storageos +1. \* (allow all volumes) + + + +对新的 PSP,推荐允许的卷的最小集合包括:configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret 和 projected。 + + + +### 主机网络 + - *HostPorts* , 默认为 `empty`。`HostPortRange` 列表通过 `min`(包含) and `max`(包含) 来定义,指定了被允许的主机端口。 + +### 允许的主机路径 + - *AllowedHostPaths* 是一个被允许的主机路径前缀的白名单。空值表示所有的主机路径都可以使用。 + + + +## 许可 + +包含 `PodSecurityPolicy` 的 _许可控制_,允许控制集群资源的创建和修改,基于这些资源在集群范围内被许可的能力。 + +许可使用如下的方式为 Pod 创建最终的安全上下文: +1. 检索所有可用的 PSP。 +1. 生成在请求中没有指定的安全上下文设置的字段值。 +1. 基于可用的策略,验证最终的设置。 + +如果某个策略能够匹配上,该 Pod 就被接受。如果请求与 PSP 不匹配,则 Pod 被拒绝。 + +Pod 必须基于 PSP 验证每个字段。 + -## 启用 Pod 安全策略 - - - -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 都无法被创建**。 - - -由于 Pod 安全策略 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 -# 授权命名空间下的所有 service accounts: -- 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 的创建和更新之外,pod 安全策略也可以用于为由其控制的许多字段提供默认值。当同时多个策略可用时,pod 安全策略控制器依据以下标准选择策略: - - -1. 允许 pod 维持原状,不改变默认设置或者变更 pod 的 PodSecurityPolicy 是首选。这些非变更的 PodSecurityPolicy 的顺序无关紧要。 -2. 如果 pod 必须默认或者变更,则使用第一个 PodSecurityPolicy(按名称排序)以允许该 pod。 - -{{< note >}} - -在更新操作期间(在 pod 规范不允许变更的期间)只有非变更的 PodSecurityPolicy 会用于校验 pod。 -{{< /note >}} - - -## 示例 - - -_这个示例假定你有一个运行中且已启用 PodSecurityPolicy admission 控制器的集群,并且你拥有集群管理员权限。_ - - -### 设置 - - -以此为例设置一个命名空间和 service account. 我们将使用这个 service account 来模拟一个非管理员用户. - -```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。 PodSecurityPolicy 对象的命名必须是合法的 [DNS 子域名](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names). {{< codenew file="policy/example-psp.yaml" >}} - -然后通过 kubectl 命名创建它: + +### 创建一个策略和一个 Pod + +在一个文件中定义 PodSecurityPolicy 对象实例。这里的策略只是用来禁止创建有特权 +要求的 Pods。 + +{{< codenew file="policy/example-psp.yaml" >}} + +使用 kubectl 执行创建操作: ```shell kubectl-admin create -f example-psp.yaml ``` - -现在作为一个非特权用户, 尝试创建一个简单的 pod: +## 获取 Pod 安全策略列表 + +获取已存在策略列表,使用 `kubectl get`: ```shell -kubectl-user create -f- < -**发生了什么?** 尽管 PodSecurityPolicy 已经创建, pod 的 service account 和 `fake-user` 都没有权限使用这个策略: + + +## 修改 Pod 安全策略 + +通过交互方式修改策略,使用 `kubectl edit`: ```shell -kubectl-user auth can-i use podsecuritypolicy/example -no +$ kubectl edit psp permissive ``` - -创建 rolebinding 来为示例策略中的 `fake-user` 的 `use` 动词授权: -{{< note >}} - -不推荐这种方式! 更推荐的方式请查看 [下一部分](#run-another-pod). -{{< /note >}} + +该命令将打开一个默认文本编辑器,在这里能够修改策略。 + + + +## 删除 Pod 安全策略 + +一旦不再需要一个策略,很容易通过 `kubectl` 删除它: ```shell -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 +$ kubectl delete psp permissive +podsecuritypolicy "permissive" deleted ``` - -现在重新创建这个 pod: -```shell -kubectl-user create -f- < -它如期运行,但是任何创建特权 pod 的尝试都应当被拒绝: +## 启用 Pod 安全策略 -```shell -kubectl-user create -f- < -在继续下一步之前先删掉之前的 pod: -```shell -kubectl-user delete pod pause -``` - -### 运行另一个 pod +1. 已经启用 API 类型 `extensions/v1beta1/podsecuritypolicy`(仅对 1.6 之前的版本) +1. 已经启用许可控制器 `PodSecurityPolicy` +1. 已经定义了自己的策略 - -我们来再试一次, 相比之前略微有些不同: -```shell -kubectl-user run pause --image=k8s.gcr.io/pause -deployment "pause" created -kubectl-user get pods -No resources found. +## 使用 RBAC -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 -``` +在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 来控制,对基于用户角色和组的已授权容器的访问。访问不同的 PodSecurityPolicy 对象,可以基于认证来控制。基于 Deployment、ReplicaSet 等创建的 Pod,限制访问 PodSecurityPolicy 对象,[Controller Manager](/docs/admin/kube-controller-manager/) 必须基于安全 API 端口运行,并且不能够具有超级用户权限。 - -**发生了什么?** 我们已经将 `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 权能字的容器来说非常有用。 - - -### 主机命名空间 - - -**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: - # ... 其他特性字段 - 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`。 - - -### AllowedProcMountTypes - - -`allowedProcMountTypes` 是允许 ProcMountTypes 的白名单。空列表或 nil 表示只允许 `DefaultProcMountType` 指定的默认值。 - - -`DefaultProcMount` 对只读路径使用容器运行时默认值,对/proc 使用掩码路径。大多数容器运行时屏蔽 /proc 中的某些路径, -以避免特殊设备或信息的意外安全性暴露。使用字符串 `Default` 表示。 - - -另一个 ProcMountType 是 `UnmaskedProcMount`,它绕过了容器运行时的默认屏蔽行为,并确保新创建的 /proc 容器保持不变。 -使用字符串 `unmask` 表示。 - -### AppArmor - - -通过 PodSecurityPolicy 上面的注解进行控制。参考 [AppArmor -文档](/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)。 - -### Seccomp - - -可以通过 PodSecurityPolicy 上的注解来控制 pod 中 seccomp 配置文件的使用。 -Seccomp 是 Kubernetes 的一个 alpha 特性。 - - -**seccomp.security.alpha.kubernetes.io/defaultProfileName** - 指定要应用于容器的默认 seccomp 配置文件的注解。 -可选值有: - - -- `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 %}} - - -关于 api 细节参考 [Pod 安全策略指南](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy)。 - -{{% /capture %}} +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 控制基于角色和组的已授权容器的访问 。