|
| 1 | +--- |
| 2 | +assignees: |
| 3 | +- pweil- |
| 4 | +title: Pod 安全策略 |
| 5 | +redirect_from: |
| 6 | +- "/docs/user-guide/pod-security-policy/" |
| 7 | +- "/docs/user-guide/pod-security-policy/index.html" |
| 8 | +--- |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +`PodSecurityPolicy` 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 `SecurityContext`。 |
| 13 | +查看 [Pod 安全策略建议](https://git.k8s.io/community/contributors/design-proposals/security-context-constraints.md) 获取更多信息。 |
| 14 | + |
| 15 | +* TOC |
| 16 | +{:toc} |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +## 什么是 Pod 安全策略? |
| 21 | + |
| 22 | +_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 |
| 23 | +`PodSecurityPolicy` 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。 |
| 24 | +它们允许管理员控制如下方面: |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +| 控制面 | 字段名称 | |
| 29 | +| ------------------------------------------------------------- | --------------------------------- | |
| 30 | +| 已授权容器的运行 | `privileged` | |
| 31 | +| 为容器添加默认的一组能力 | `defaultAddCapabilities` | |
| 32 | +| 为容器去掉某些能力 | `requiredDropCapabilities` | |
| 33 | +| 容器能够请求添加某些能力 | `allowedCapabilities` | |
| 34 | +| 控制卷类型的使用 | [`volumes`](#controlling-volumes) | |
| 35 | +| 主机网络的使用 | [`hostNetwork`](#host-network) | |
| 36 | +| 主机端口的使用 | `hostPorts` | |
| 37 | +| 主机 PID namespace 的使用 | `hostPID` | |
| 38 | +| 主机 IPC namespace 的使用 | `hostIPC` | |
| 39 | +| 主机路径的使用 | [`allowedHostPaths`](#allowed-host-paths) | |
| 40 | +| 容器的 SELinux 上下文 | [`seLinux`](#selinux) | |
| 41 | +| 用户 ID | [`runAsUser`](#runasuser) | |
| 42 | +| 配置允许的补充组 | [`supplementalGroups`](#supplementalgroups) | |
| 43 | +| 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#fsgroup) | |
| 44 | +| 必须使用一个只读的 root 文件系统 | `readOnlyRootFilesystem` | |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +_Pod 安全策略_ 由设置和策略组成,它们能够控制 Pod 访问的安全特征。这些设置分为如下三类: |
| 49 | + |
| 50 | +- *基于布尔值控制*:这种类型的字段默认为最严格限制的值。 |
| 51 | +- *基于被允许的值集合控制*:这种类型的字段会与这组值进行对比,以确认值被允许。 |
| 52 | +- *基于策略控制*:设置项通过一种策略提供的机制来生成该值,这种机制能够确保指定的值落在被允许的这组值中。 |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +### RunAsUser |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +- *MustRunAs* - 必须配置一个 `range`。使用该范围内的第一个值作为默认值。验证是否不在配置的该范围内。 |
| 61 | +- *MustRunAsNonRoot* - 要求提交的 Pod 具有非零 `runAsUser` 值,或在镜像中定义了 `USER` 环境变量。不提供默认值。 |
| 62 | +- *RunAsAny* - 没有提供默认值。允许指定任何 `runAsUser` 。 |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | +### SELinux |
| 67 | + |
| 68 | +- *MustRunAs* - 如果没有使用预分配的值,必须配置 `seLinuxOptions`。默认使用 `seLinuxOptions`。验证 `seLinuxOptions`。 |
| 69 | +- *RunAsAny* - 没有提供默认值。允许任意指定的 `seLinuxOptions` ID。 |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +### SupplementalGroups |
| 74 | + |
| 75 | +- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证所有范围的值。 |
| 76 | +- *RunAsAny* - 没有提供默认值。允许任意指定的 `supplementalGroups` ID。 |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +### FSGroup |
| 81 | + |
| 82 | +- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证在第一个范围内的第一个 ID。 |
| 83 | +- *RunAsAny* - 没有提供默认值。允许任意指定的 `fsGroup` ID。 |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +### 控制卷 |
| 88 | + |
| 89 | +通过设置 PSP 卷字段,能够控制具体卷类型的使用。当创建一个卷的时候,与该字段相关的已定义卷可以允许设置如下值: |
| 90 | + |
| 91 | +1. azureFile |
| 92 | +1. azureDisk |
| 93 | +1. flocker |
| 94 | +1. flexVolume |
| 95 | +1. hostPath |
| 96 | +1. emptyDir |
| 97 | +1. gcePersistentDisk |
| 98 | +1. awsElasticBlockStore |
| 99 | +1. gitRepo |
| 100 | +1. secret |
| 101 | +1. nfs |
| 102 | +1. iscsi |
| 103 | +1. glusterfs |
| 104 | +1. persistentVolumeClaim |
| 105 | +1. rbd |
| 106 | +1. cinder |
| 107 | +1. cephFS |
| 108 | +1. downwardAPI |
| 109 | +1. fc |
| 110 | +1. configMap |
| 111 | +1. vsphereVolume |
| 112 | +1. quobyte |
| 113 | +1. photonPersistentDisk |
| 114 | +1. projected |
| 115 | +1. portworxVolume |
| 116 | +1. scaleIO |
| 117 | +1. storageos |
| 118 | +1. \* (allow all volumes) |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | +对新的 PSP,推荐允许的卷的最小集合包括:configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret 和 projected。 |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | +### 主机网络 |
| 127 | + - *HostPorts*, 默认为 `empty`。`HostPortRange` 列表通过 `min`(包含) and `max`(包含) 来定义,指定了被允许的主机端口。 |
| 128 | + |
| 129 | +### 允许的主机路径 |
| 130 | + - *AllowedHostPaths* 是一个被允许的主机路径前缀的白名单。空值表示所有的主机路径都可以使用。 |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | +## 许可 |
| 135 | + |
| 136 | +包含 `PodSecurityPolicy` 的 _许可控制_,允许控制集群资源的创建和修改,基于这些资源在集群范围内被许可的能力。 |
| 137 | + |
| 138 | +许可使用如下的方式为 Pod 创建最终的安全上下文: |
| 139 | +1. 检索所有可用的 PSP。 |
| 140 | +1. 生成在请求中没有指定的安全上下文设置的字段值。 |
| 141 | +1. 基于可用的策略,验证最终的设置。 |
| 142 | + |
| 143 | +如果某个策略能够匹配上,该 Pod 就被接受。如果请求与 PSP 不匹配,则 Pod 被拒绝。 |
| 144 | + |
| 145 | +Pod 必须基于 PSP 验证每个字段。 |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | +## 创建 Pod 安全策略 |
| 150 | + |
| 151 | +下面是一个 Pod 安全策略的例子,所有字段的设置都被允许: |
| 152 | + |
| 153 | +{% include code.html language="yaml" file="psp.yaml" ghlink="/docs/concepts/policy/psp.yaml" %} |
| 154 | + |
| 155 | + |
| 156 | + |
| 157 | +下载示例文件可以创建该策略,然后执行如下命令: |
| 158 | + |
| 159 | +```shell |
| 160 | +$ kubectl create -f ./psp.yaml |
| 161 | +podsecuritypolicy "permissive" created |
| 162 | +``` |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | +## 获取 Pod 安全策略列表 |
| 167 | + |
| 168 | +获取已存在策略列表,使用 `kubectl get`: |
| 169 | + |
| 170 | +```shell |
| 171 | +$ kubectl get psp |
| 172 | +NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES |
| 173 | +permissive false [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] |
| 174 | +privileged true [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] |
| 175 | +restricted false [] RunAsAny MustRunAsNonRoot RunAsAny RunAsAny false [emptyDir secret downwardAPI configMap persistentVolumeClaim projected] |
| 176 | +``` |
| 177 | + |
| 178 | + |
| 179 | + |
| 180 | +## 修改 Pod 安全策略 |
| 181 | + |
| 182 | +通过交互方式修改策略,使用 `kubectl edit`: |
| 183 | + |
| 184 | +```shell |
| 185 | +$ kubectl edit psp permissive |
| 186 | +``` |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | +该命令将打开一个默认文本编辑器,在这里能够修改策略。 |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | +## 删除 Pod 安全策略 |
| 195 | + |
| 196 | +一旦不再需要一个策略,很容易通过 `kubectl` 删除它: |
| 197 | + |
| 198 | +```shell |
| 199 | +$ kubectl delete psp permissive |
| 200 | +podsecuritypolicy "permissive" deleted |
| 201 | +``` |
| 202 | + |
| 203 | + |
| 204 | + |
| 205 | +## 启用 Pod 安全策略 |
| 206 | + |
| 207 | +为了能够在集群中使用 Pod 安全策略,必须确保满足如下条件: |
| 208 | + |
| 209 | + |
| 210 | + |
| 211 | +1. 已经启用 API 类型 `extensions/v1beta1/podsecuritypolicy`(仅对 1.6 之前的版本) |
| 212 | +1. 已经启用许可控制器 `PodSecurityPolicy` |
| 213 | +1. 已经定义了自己的策略 |
| 214 | + |
| 215 | + |
| 216 | + |
| 217 | +## 使用 RBAC |
| 218 | + |
| 219 | +在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 来控制,对基于用户角色和组的已授权容器的访问。访问不同的 PodSecurityPolicy 对象,可以基于认证来控制。基于 Deployment、ReplicaSet 等创建的 Pod,限制访问 PodSecurityPolicy 对象,[Controller Manager](/docs/admin/kube-controller-manager/) 必须基于安全 API 端口运行,并且不能够具有超级用户权限。 |
| 220 | + |
| 221 | +PodSecurityPolicy 认证使用所有可用的策略,包括创建 Pod 的用户,Pod 上指定的服务账户(Service Acount)。当 Pod 基于 Deployment、ReplicaSet 创建时,它是创建 Pod 的 Controller Manager,所以如果基于非安全 API 端口运行,允许所有的 PodSecurityPolicy 对象,并且不能够有效地实现细分权限。用户访问给定的 PSP 策略有效,仅当是直接部署 Pod 的情况。更多详情,查看 [PodSecurityPolicy RBAC 示例](https://git.k8s.io/kubernetes/examples/podsecuritypolicy/rbac/README.md),当直接部署 Pod 时,应用 PodSecurityPolicy 控制基于角色和组的已授权容器的访问 。 |
0 commit comments