PodSecurityStandards / PodSecurityAdmission

This commit is contained in:
shaohq
2022-04-07 21:50:23 +08:00
parent 4e25e0c033
commit 12189713f0
3 changed files with 754 additions and 3 deletions

2
.gitignore vendored
View File

@ -2,6 +2,8 @@ HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
.DS_Store
### STS ###
.apt_generated
.classpath

View File

@ -1,6 +1,6 @@
---
layout: LearningLayout
description: Kubernetes教程_本文面向集群管理员,阐述 Pod Security Admission 的相关概念
description: Kubernetes教程_对 Pod 安全性准入控制器的概述Pod 安全性准入控制器可以实施 Pod 安全性标准
meta:
- name: keywords
content: Kubernetes 教程,Pod Security Admission
@ -8,4 +8,156 @@ meta:
# Pod Security Admission
<AdSenseTitle/>
> 本文参考自 Kubernetes 官方文档 [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/)
<AdSenseTitle/>
<!-- overview -->
> FEATURE STATE `Kubernetes v1.23 [beta]`
Kubernetes [Pod 安全性标准Security Standards](./pss)
为 Pod 定义不同的隔离级别。这些标准能够让你以一种清晰、一致的方式定义如何限制 Pod 行为。
作为一项 Beta 功能特性Kubernetes 提供一种内置的 _Pod 安全性_
作为 [PodSecurityPolicies](https://kubernetes.io/docs/concepts/security/pod-security-policy/)
特性的后继演化版本。Pod 安全性限制是在 Pod 被创建时在 名称空间 层面实施的。
:::tip Note
PodSecurityPolicy API 已经被废弃,会在 Kubernetes v1.25 发行版中移除。
:::
## 启用 `PodSecurity` 准入插件
在 v1.23 中,`PodSecurity` [特性门控](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/)
是一项 Beta 功能特性,默认被启用。
在 v1.22 中,`PodSecurity` [特性门控](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/)
是一项 Alpha 功能特性,必须在 `kube-apiserver` 上启用才能使用内置的准入插件。
```shell
--feature-gates="...,PodSecurity=true"
```
## 替代方案:安装 `PodSecurity` 准入 Webhook
对于无法应用内置 `PodSecurity` 准入插件的环境,无论是因为集群版本低于 v1.22
或者 `PodSecurity` 特性无法被启用,都可以使用 Beta 版本的
[验证性准入 Webhook](https://git.k8s.io/pod-security-admission/webhook)。
来使用 `PodSecurity` 准入逻辑。
在 [https://git.k8s.io/pod-security-admission/webhook](https://git.k8s.io/pod-security-admission/webhook)
上可以找到一个预先构建的容器镜像、证书生成脚本以及一些示例性质的清单。
```shell
git clone git@github.com:kubernetes/pod-security-admission.git
cd pod-security-admission/webhook
make certs
kubectl apply -k .
```
:::tip Note
所生成的证书合法期限为 2 年。在证书过期之前,
需要重新生成证书或者去掉 Webhook 以使用内置的准入查件。
:::
## Pod 安全性级别
Pod 安全性准入插件对 Pod 的[安全性上下文](/learning/k8s-intermediate/config/sec-ctx/)
有一定的要求,并且依据 [Pod 安全性标准](./pss)
所定义的三个级别(`privileged``baseline``restricted`)对其他字段也有要求。
关于这些需求的更进一步讨论,请参阅
[Pod 安全性标准](./pss)页面。
## 为名字空间设置 Pod 安全性准入控制标签
一旦特性被启用或者安装了 Webhook你可以配置名字空间以定义每个名字空间中
Pod 安全性准入控制模式。
Kubernetes 定义了一组标签,
你可以设置这些标签来定义某个名字空间上要使用的预定义的 Pod 安全性标准级别。
你所选择的标签定义了检测到潜在违例时,控制面板要采取什么样的动作。
|模式 | 描述|
:---------|:------------
**enforce** | 策略违例会导致 Pod 被拒绝
**audit** | 策略违例会触发[审计日志](https://kubernetes.io/docs/tasks/debug-application-cluster/audit/)中记录新事件时添加审计注解;但是 Pod 仍是被接受的。
**warn** | 策略违例会触发用户可见的警告信息,但是 Pod 仍是被接受的。
名字空间可以配置任何一种或者所有模式,或者甚至为不同的模式设置不同的级别。
对于每种模式,决定所使用策略的标签有两个:
```yaml
# 针对模式的级别标签用来标示针对该模式所应用的策略级别
#
# MODE 必须是 `enforce`、`audit` 或 `warn` 之一
# LEVEL 必须是 `privileged`、baseline` 或 `restricted` 之一
pod-security.kubernetes.io/<MODE>: <LEVEL>
# 可选:针对每个模式版本的版本标签可以将策略锁定到
# 给定 Kubernetes 小版本号所附带的版本(例如 v1.23.5
#
# MODE 必须是 `enforce`、`audit` 或 `warn` 之一
# VERSION 必须是一个合法的 Kubernetes 小版本号或者 `latest`
pod-security.kubernetes.io/<MODE>-version: <VERSION>
```
关于用法示例,可参阅
[使用名字空间标签来强制实施 Pod 安全标准](https://kubernetes.io/zh/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/)。
## 负载资源和 Pod 模板
Pod 通常是通过创建 Deployment 或
Job 这类[工作负载对象](/learning/k8s-intermediate/workload/workload.html)
来间接创建的。工作负载对象为工作负载资源定义一个 _Pod 模板_ 和一个对应的
负责基于该模板来创建 Pod 的 控制器。
为了尽早地捕获违例状况,`audit``warn` 模式都应用到负载资源。
不过,`enforce` 模式并 **不** 应用到工作负载资源,仅应用到所生成的 Pod 对象上。
## 豁免
你可以为 Pod 安全性的实施设置 _豁免Exemptions_ 规则,
从而允许创建一些本来会被与给定名字空间相关的策略所禁止的 Pod。
豁免规则可以在[准入控制器配置](/zh/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller)
中静态配置。
豁免规则可以显式枚举。满足豁免标准的请求会被准入控制器 _忽略_
(所有 `enforce``audit``warn` 行为都会被略过)。
豁免的维度包括:
- **Username** 来自用户名已被豁免的、已认证的(或伪装的)的用户的请求会被忽略。
- **RuntimeClassName** 指定了已豁免的运行时类名称的 Pod
和[负载资源](#workload-resources-and-pod-templates)会被忽略。
- **Namespace** 位于被豁免的名字空间中的 Pod 和[负载资源](#workload-resources-and-pod-templates)
会被忽略。
:::warning
大多数 Pod 是作为对[工作负载资源](#workload-resources-and-pod-templates)的响应,
由控制器所创建的,这意味着为某最终用户提供豁免时,只会当该用户直接创建 Pod
时对其实施安全策略的豁免。用户创建工作负载资源时不会被豁免。
控制器服务账号(例如:`system:serviceaccount:kube-system:replicaset-controller`
通常不应该被豁免,因为豁免这类服务账号隐含着对所有能够创建对应工作负载资源的用户豁免。
:::
策略检查时会对以下 Pod 字段的更新操作予以豁免,这意味着如果 Pod
更新请求仅改变这些字段时,即使 Pod 违反了当前的策略级别,请求也不会被拒绝。
- 除了对 seccomp 或 AppArmor 注解之外的所有 meatadata 更新操作:
- `seccomp.security.alpha.kubernetes.io/pod` (已弃用)
- `container.seccomp.security.alpha.kubernetes.io/*` (已弃用)
- `container.apparmor.security.beta.kubernetes.io/*`
-`.spec.activeDeadlineSeconds` 的合法更新
-`.spec.tolerations` 的合法更新
## 下一步
- [Pod 安全性标准](./pss)
<!-- - [强制实施 Pod 安全性标准](/zh/docs/setup/best-practices/enforcing-pod-security-standards/)
- [通过配置内置的准入控制器强制实施 Pod 安全性标准](/zh/docs/tasks/configure-pod-container/enforce-standards-admission-controller/)
- [使用名字空间标签来实施 Pod 安全性标准](/zh/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/)
- [从 PodSecurityPolicy 迁移到内置的 PodSecurity 准入控制器](/zh/docs/tasks/configure-pod-container/migrate-from-psp/) -->

View File

@ -8,4 +8,601 @@ meta:
# Pod Security Standards
<AdSenseTitle/>
本文档主要参考了 Kubernetes 官方文档:[Pod Security Standards](https://kubernetes.io/zh/docs/concepts/security/pod-security-standards/)
<AdSenseTitle/>
Pod 安全性标准定义了三种不同的 _策略Policy_,以广泛覆盖安全应用场景。
这些策略是 _渐进式的Cumulative_,安全级别从高度宽松至高度受限。
本指南概述了每个策略的要求。
| Profile | 描述 |
| ------ | ----------- |
| <strong style="white-space: nowrap">Privileged</strong> | 不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。 |
| <strong style="white-space: nowrap">Baseline</strong> | 限制性最弱的策略禁止已知的策略提升。允许使用默认的规定最少Pod 配置。 |
| <strong style="white-space: nowrap">Restricted</strong> | 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。 |
## Profile 细节
### Privileged
**_Privileged_ 策略是有目的地开放且完全无限制的策略。**
此类策略通常针对由特权较高、受信任的用户所管理的系统级或基础设施级负载。
Privileged 策略定义中限制较少。对于默认允许Allow-by-default实施机制例如 gatekeeper
Privileged 框架可能意味着不应用任何约束而不是实施某策略实例。
与此不同对于默认拒绝Deny-by-default实施机制如 Pod 安全策略)而言,
Privileged 策略应该默认允许所有控制(即,禁止所有限制)。
### Baseline
Baseline 策略的目标是便于常见的容器化应用采用,同时禁止已知的特权提升。
此策略针对的是应用运维人员和非关键性应用的开发人员。
下面列举的控制应该被实施(禁止):
在下述表格中,通配符(`*`)意味着一个列表中的所有元素。
例如 `spec.containers[*].securityContext` 表示 _所定义的所有容器_ 的安全性上下文对象。
如果所列出的任一容器不能满足要求,整个 Pod 将无法通过校验。
<table>
<!-- caption style="display:none">Baseline policy specification</caption -->
<caption style="display:none">Baseline 策略规范</caption>
<tbody>
<tr>
<td>控制Control</td>
<td>策略Policy</td>
</tr>
<tr>
<td style="white-space: nowrap">HostProcess</td>
<td>
<p>Windows Pod 提供了运行 <a target="_blank" href="https://kubernetes.io/zh/docs/tasks/configure-pod-container/create-hostprocess-pod">HostProcess 容器</a> 的能力,
这使得对 Windows 节点的特权访问成为可能。
基线策略中对宿主的特权访问是被禁止的。
HostProcess Pod 是 Kubernetes <strong>v1.22</strong> 版本的
<strong>alpha</strong> 特性。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.windowsOptions.hostProcess</code></li>
<li><code>spec.containers[*].securityContext.windowsOptions.hostProcess</code></li>
<li><code>spec.initContainers[*].securityContext.windowsOptions.hostProcess</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>false</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Host Namespaces</td> -->
<td style="white-space: nowrap">宿主名字空间</td>
<td>
<p>必须禁止共享宿主名字空间。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.hostNetwork</code></li>
<li><code>spec.hostPID</code></li>
<li><code>spec.hostIPC</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>false</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Privileged Containers</td> -->
<td style="white-space: nowrap">特权容器</td>
<td>
<p>特权 Pod 关闭了大多数安全性机制,必须被禁止。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.privileged</code></li>
<li><code>spec.initContainers[*].securityContext.privileged</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.privileged</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>false</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Capabilities</td> -->
<td style="white-space: nowrap">权能</td>
<!-- <td>
<p>Adding additional capabilities beyond those listed below must be disallowed.</p>
<p><strong>Restricted Fields</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.capabilities.add</code></li>
<li><code>spec.initContainers[*].securityContext.capabilities.add</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.capabilities.add</code></li>
</ul>
<p><strong>Allowed Values</strong></p>
<ul>
<li>Undefined/nil</li>
<li><code>AUDIT_WRITE</code></li>
<li><code>CHOWN</code></li>
<li><code>DAC_OVERRIDE</code></li>
<li><code>FOWNER</code></li>
<li><code>FSETID</code></li>
<li><code>KILL</code></li>
<li><code>MKNOD</code></li>
<li><code>NET_BIND_SERVICE</code></li>
<li><code>SETFCAP</code></li>
<li><code>SETGID</code></li>
<li><code>SETPCAP</code></li>
<li><code>SETUID</code></li>
<li><code>SYS_CHROOT</code></li>
</ul>
</td> -->
<td>
<p>必须禁止添加除下列字段之外的权能。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.capabilities.add</code></li>
<li><code>spec.initContainers[*].securityContext.capabilities.add</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.capabilities.add</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>Undefined/nil</li>
<li><code>AUDIT_WRITE</code></li>
<li><code>CHOWN</code></li>
<li><code>DAC_OVERRIDE</code></li>
<li><code>FOWNER</code></li>
<li><code>FSETID</code></li>
<li><code>KILL</code></li>
<li><code>MKNOD</code></li>
<li><code>NET_BIND_SERVICE</code></li>
<li><code>SETFCAP</code></li>
<li><code>SETGID</code></li>
<li><code>SETPCAP</code></li>
<li><code>SETUID</code></li>
<li><code>SYS_CHROOT</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">HostPath Volumes</td>-->
<td style="white-space: nowrap">HostPath 卷</td>
<!-- <td>
<p>HostPath volumes must be forbidden.</p>
<p><strong>Restricted Fields</strong></p>
<ul>
<li><code>spec.volumes[*].hostPath</code></li>
</ul>
<p><strong>Allowed Values</strong></p>
<ul>
<li>Undefined/nil</li>
</ul>
</td> -->
<td>
<p>必须禁止 HostPath 卷。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.volumes[*].hostPath</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Host Ports</td> -->
<td style="white-space: nowrap">宿主端口</td>
<!-- <td>
<p>HostPorts should be disallowed, or at minimum restricted to a known list.</p>
<p><strong>Restricted Fields</strong></p>
<ul>
<li><code>spec.containers[*].ports[*].hostPort</code></li>
<li><code>spec.initContainers[*].ports[*].hostPort</code></li>
<li><code>spec.ephemeralContainers[*].ports[*].hostPort</code></li>
</ul>
<p><strong>Allowed Values</strong></p>
<ul>
<li>Undefined/nil</li>
<li>Known list</li>
<li><code>0</code></li>
</ul>
</td>-->
<td>
<p>应禁止使用宿主端口,或者至少限定为已知列表。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].ports[*].hostPort</code></li>
<li><code>spec.initContainers[*].ports[*].hostPort</code></li>
<li><code>spec.ephemeralContainers[*].ports[*].hostPort</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li>已知列表</li>
<li><code>0</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">AppArmor</td> -->
<td style="white-space: nowrap">AppArmor</td>
<td>
<p>在受支持的主机上,默认使用 <code>runtime/default</code> AppArmor Profile。
基线策略应避免覆盖或者禁用默认策略,以及限制覆盖一些 Profile 集合的权限。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>metadata.annotations["container.apparmor.security.beta.kubernetes.io/*"]</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>runtime/default</code></li>
<li><code>localhost/*</code></li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">SELinux</td> -->
<td style="white-space: nowrap">SELinux</td>
<td>
<p>设置 SELinux 类型的操作是被限制的,设置自定义的 SELinux 用户或角色选项是被禁止的。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.seLinuxOptions.type</code></li>
<li><code>spec.containers[*].securityContext.seLinuxOptions.type</code></li>
<li><code>spec.initContainers[*].securityContext.seLinuxOptions.type</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.seLinuxOptions.type</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/""</li>
<li><code>container_t</code></li>
<li><code>container_init_t</code></li>
<li><code>container_kvm_t</code></li>
</ul>
<hr />
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.seLinuxOptions.user</code></li>
<li><code>spec.containers[*].securityContext.seLinuxOptions.user</code></li>
<li><code>spec.initContainers[*].securityContext.seLinuxOptions.user</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.seLinuxOptions.user</code></li>
<li><code>spec.securityContext.seLinuxOptions.role</code></li>
<li><code>spec.containers[*].securityContext.seLinuxOptions.role</code></li>
<li><code>spec.initContainers[*].securityContext.seLinuxOptions.role</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.seLinuxOptions.role</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/""</li>
</ul>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap"><code>/proc</code> Mount Type</td> -->
<td style="white-space: nowrap"><code>/proc</code> 挂载类型</td>
<td>
<p>要求使用默认的 <code>/proc</code> 掩码以减小攻击面。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.procMount</code></li>
<li><code>spec.initContainers[*].securityContext.procMount</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.procMount</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>Default</code></li>
</ul>
</td>
</tr>
<tr>
<td>Seccomp</td>
<td>
<p>Seccomp Profile 禁止被显式设置为 <code>Unconfined</code></p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.seccompProfile.type</code></li>
<li><code>spec.containers[*].securityContext.seccompProfile.type</code></li>
<li><code>spec.initContainers[*].securityContext.seccompProfile.type</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.seccompProfile.type</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>RuntimeDefault</code></li>
<li><code>Localhost</code></li>
</ul>
</td>
</tr>
<tr>
<td>Sysctls</td>
<td>
<p>Sysctls 可以禁用安全机制或影响宿主上所有容器,因此除了若干“安全”的子集之外,应该被禁止。
如果某 sysctl 是受容器或 Pod 的名字空间限制,且与节点上其他 Pod 或进程相隔离,可认为是安全的。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.sysctls[*].name</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>kernel.shm_rmid_forced</code></li>
<li><code>net.ipv4.ip_local_port_range</code></li>
<li><code>net.ipv4.ip_unprivileged_port_start</code></li>
<li><code>net.ipv4.tcp_syncookies</code></li>
<li><code>net.ipv4.ping_group_range</code></li>
</ul>
</td>
</tr>
</tbody>
</table>
### Restricted
**Restricted 策略旨在实施当前保护 Pod 的最佳实践,尽管这样作可能会牺牲一些兼容性。**
该类策略主要针对运维人员和安全性很重要的应用的开发人员,以及不太被信任的用户。
下面列举的控制需要被实施(禁止):
::: tip Note
在下述表格中,通配符(`*`)意味着一个列表中的所有元素。
例如 `spec.containers[*].securityContext` 表示 _所定义的所有容器_ 的安全性上下文对象。
如果所列出的任一容器不能满足要求,整个 Pod 将无法通过校验。
:::
<table>
<!-- caption style="display:none">Restricted policy specification</caption -->
<caption style="display:none">Restricted 策略规范</caption>
<tbody>
<tr>
<!-- td><strong>Control</strong></td -->
<td width="30%"><strong>控制Control</strong></td>
<!-- td><strong>Policy</strong></td -->
<td><strong>策略Policy</strong></td>
</tr>
<tr>
<!-- <td colspan="2"><em>Everything from the baseline profile.</em></td> -->
<td colspan="2"><em>基线策略的所有要求。</em></td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Volume Types</td>
<td>
<p>In addition to restricting HostPath volumes, the restricted policy limits usage of non-core volume types to those defined through PersistentVolumes.</p>
<p><strong>Restricted Fields</strong></p>
<ul>
<li><code>spec.volumes[*]</code></li>
</ul>
<p><strong>Allowed Values</strong></p>
Every item in the <code>spec.volumes[*]</code> list must set one of the following fields to a non-null value:
<ul>
<li><code>spec.volumes[*].configMap</code></li>
<li><code>spec.volumes[*].csi</code></li>
<li><code>spec.volumes[*].downwardAPI</code></li>
<li><code>spec.volumes[*].emptyDir</code></li>
<li><code>spec.volumes[*].ephemeral</code></li>
<li><code>spec.volumes[*].persistentVolumeClaim</code></li>
<li><code>spec.volumes[*].projected</code></li>
<li><code>spec.volumes[*].secret</code></li>
</ul>
</td> -->
<td>卷类型</td>
<td>
<p>除了限制 HostPath 卷之外,此类策略还限制可以通过 PersistentVolumes 定义的非核心卷类型。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.volumes[*]</code></li>
</ul>
<p><strong>允许的值</strong></p>
<code>spec.volumes[*]</code> 列表中的每个条目必须将下面字段之一设置为非空值:
<ul>
<li><code>spec.volumes[*].configMap</code></li>
<li><code>spec.volumes[*].csi</code></li>
<li><code>spec.volumes[*].downwardAPI</code></li>
<li><code>spec.volumes[*].emptyDir</code></li>
<li><code>spec.volumes[*].ephemeral</code></li>
<li><code>spec.volumes[*].persistentVolumeClaim</code></li>
<li><code>spec.volumes[*].projected</code></li>
<li><code>spec.volumes[*].secret</code></li>
</ul>
</td>
</tr>
<tr>
<td style="white-space: nowrap">特权提升v1.8+</td>
<td>
<p>禁止(通过 SetUID 或 SetGID 文件模式)获得特权提升。</p>
<br>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.allowPrivilegeEscalation</code></li>
<li><code>spec.initContainers[*].securityContext.allowPrivilegeEscalation</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li><code>false</code></li>
</ul>
</td>
</tr>
<tr>
<td style="white-space: nowrap">以非 root 账号运行 </td>
<td>
<p>必须要求容器以非 root 用户运行。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.runAsNonRoot</code></li>
<li><code>spec.containers[*].securityContext.runAsNonRoot</code></li>
<li><code>spec.initContainers[*].securityContext.runAsNonRoot</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.runAsNonRoot</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li><code>true</code></li>
</ul>
<small>
如果 Pod 级别 <code>spec.securityContext.runAsNonRoot</code> 设置为
<code>true</code>,则允许容器组的安全上下文字段设置为 未定义/<code>nil</code>
</small>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Running as Non-root user (v1.23+)</td> -->
<td style="white-space: nowrap">非 root 用户v1.23+</td>
<td>
<!--
<p>Containers must not set <tt>runAsUser</tt> to 0</p>
<p><strong>Restricted Fields</strong></p>
<ul>
<li><code>spec.securityContext.runAsUser</code></li>
<li><code>spec.containers[*].securityContext.runAsUser</code></li>
<li><code>spec.initContainers[*].securityContext.runAsUser</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.runAsUser</code></li>
</ul>
<p><strong>Allowed Values</strong></p>
<ul>
<li>any non-zero value</li>
<li><code>undefined/null</code></li>
</ul>
</td> -->
<p>Containers 不可以将 <tt>runAsUser</tt> 设置为 0</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.runAsUser</code></li>
<li><code>spec.containers[*].securityContext.runAsUser</code></li>
<li><code>spec.initContainers[*].securityContext.runAsUser</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.runAsUser</code></li>
</ul>
<p><strong>允许的字段</strong></p>
<ul>
<li>any non-zero value</li>
<li><code>未定义/空值</code></li>
</ul>
</td>
</tr>
<tr>
<td style="white-space: nowrap">Seccomp (v1.19+)</td>
<td>
<p>Seccomp Profile 必须被显式设置成一个允许的值。禁止使用 <code>Unconfined</code>
Profile 或者指定 <em>不存在的</em> Profile。</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.securityContext.seccompProfile.type</code></li>
<li><code>spec.containers[*].securityContext.seccompProfile.type</code></li>
<li><code>spec.initContainers[*].securityContext.seccompProfile.type</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.seccompProfile.type</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li><code>RuntimeDefault</code></li>
<li><code>Localhost</code></li>
</ul>
<small>
如果 Pod 级别的 <code>spec.securityContext.seccompProfile.type</code>
已设置得当,容器级别的安全上下文字段可以为 未定义/<code>nil</code>
反过来说,如果 _所有的_ 容器级别的安全上下文字段已设置,则 Pod 级别的字段可为 未定义/<code>nil</code>
</small>
</td>
</tr>
<tr>
<!-- <td style="white-space: nowrap">Capabilities (v1.22+)</td> -->
<td style="white-space: nowrap">权能v1.22+</td>
<td>
<p>
容器组必须弃用 <code>ALL</code> 权能,并且只允许添加 <code>NET_BIND_SERVICE</code> 权能。
</p>
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.capabilities.drop</code></li>
<li><code>spec.initContainers[*].securityContext.capabilities.drop</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.capabilities.drop</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>包含 <code>ALL</code> 的任何一种权能列表。</li>
</ul>
<hr />
<p><strong>限制的字段</strong></p>
<ul>
<li><code>spec.containers[*].securityContext.capabilities.add</code></li>
<li><code>spec.initContainers[*].securityContext.capabilities.add</code></li>
<li><code>spec.ephemeralContainers[*].securityContext.capabilities.add</code></li>
</ul>
<p><strong>允许的值</strong></p>
<ul>
<li>未定义/nil</li>
<li><code>NET_BIND_SERVICE</code></li>
</ul>
</td>
</tr>
</tbody>
</table>
## 策略实例化
将策略定义从策略实例中解耦出来有助于形成跨集群的策略理解和语言陈述,
以免绑定到特定的下层实施机制。
随着相关机制的成熟,这些机制会按策略分别定义在下面。特定策略的实施方法不在这里定义。
[**Pod 安全性准入控制器**](./psa)
- [Privileged 名字空间](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/security/podsecurity-privileged.yaml)
- [Baseline 名字空间](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/security/podsecurity-baseline.yaml)
- [Restricted 名字空间](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/security/podsecurity-restricted.yaml)
[**PodSecurityPolicy**](https://kubernetes.io/docs/concepts/security/pod-security-policy/) (已弃用)
- [Privileged](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/policy/privileged-psp.yaml)
- [Baseline](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/policy/baseline-psp.yaml)
- [Restricted](https://raw.githubusercontent.com/kubernetes/website/main/content/zh/examples/policy/restricted-psp.yaml)
<!--
## FAQ
### Why isn't there a profile between privileged and baseline?
-->
## 常见问题
### 为什么不存在介于 Privileged 和 Baseline 之间的策略类型
这里定义的三种策略框架有一个明晰的线性递进关系从最安全Restricted到最不安全并且覆盖了很大范围的工作负载。特权要求超出 Baseline 策略者通常是特定于应用的需求,所以我们没有在这个范围内提供标准框架。这并不意味着在这样的情形下仍然只能使用 Privileged 框架,只是说处于这个范围的策略需要因地制宜地定义。
SIG Auth 可能会在将来考虑这个范围的框架,前提是有对其他框架的需求。
### 安全策略与安全上下文的区别是什么?
[安全上下文](/learning/k8s-intermediate/config/sec-ctx/)在运行时配置 Pod 和容器。安全上下文是在 Pod 清单中作为 Pod 和容器规约的一部分来定义的,所代表的是传递给容器运行时的参数。
安全策略则是控制面用来对安全上下文以及安全性上下文之外的参数实施某种设置的机制。在 2020 年 7 月,[Pod 安全性策略](https://kubernetes.io/zh/docs/concepts/security/pod-security-admission/)已被废弃,取而代之的是内置的 [Pod 安全性准入控制器](./psa)。
Kubernetes 生态系统中还在开发一些其他的替代方案,例如:
- [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper)。
- [Kubewarden](https://github.com/kubewarden)。
- [Kyverno](https://kyverno.io/policies/pod-security/)。
### 我应该为我的 Windows Pod 实施哪种框架?
Kubernetes 中的 Windows 负载与标准的基于 Linux 的负载相比有一些局限性和区别。
尤其是 Pod SecurityContext 字段
[对 Windows 不起作用](https://kubernetes.io/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#v1-podsecuritycontext)。
因此,目前没有对应的标准 Pod 安全性框架。
如果你为一个 Windows Pod 应用了 Restricted 策略,**可能会** 对该 Pod 的运行时产生影响。Restricted 策略需要强制执行 Linux 特有的限制(如 seccomp Profile并且禁止特权提升。如果 kubelet 和/或其容器运行时忽略了 Linux 特有的值,那么应该不影响 Windows Pod 正常工作。然而,对于使用 Windows 容器的 Pod 来说,缺乏强制执行意味着相比于 Restricted 策略,没有任何额外的限制。
你应该只在 Privileged 策略下使用 HostProcess 标志来创建 HostProcess Pod。在 Baseline 和 Restricted 策略下,创建 Windows HostProcess Pod 是被禁止的,因此任何 HostProcess Pod 都应该被认为是有特权的。
### 沙箱Sandboxed Pod 怎么处理?
现在还没有 API 标准来控制 Pod 是否被视作沙箱化 Pod。
沙箱 Pod 可以通过其是否使用沙箱化运行时(如 gVisor 或 Kata Container来辨别不过
目前还没有关于什么是沙箱化运行时的标准定义。
沙箱化负载所需要的保护可能彼此各不相同。例如,当负载与下层内核直接隔离开来时,
限制特权化操作的许可就不那么重要。这使得那些需要更多许可权限的负载仍能被有效隔离。
此外,沙箱化负载的保护高度依赖于沙箱化的实现方法。
因此,现在还没有针对所有沙箱化负载的建议策略。