PodSecurityPolicy:历史背景
从 Kubernetes v1.25 开始,PodSecurityPolicy (PSP) admission 控制器已被移除。其弃用已在为 Kubernetes v1.21 发布而撰写的博客文章PodSecurityPolicy 弃用:过去、现在和未来中宣布和详细说明。
本文旨在提供 PSP 诞生和演进的历史背景,解释为什么该功能未能达到稳定版,并说明它为何被移除并被 Pod Security admission 控制所取代。
PodSecurityPolicy 与其他专用 admission 控制插件一样,以内置策略 API 的形式,对 Pod 安全设置的特定字段提供了细粒度的权限。它认识到集群管理员和集群用户通常不是同一类人,并且以 Pod 或任何将创建 Pod 的资源形式创建工作负载不应等同于“集群上的 root 权限”。它还可以通过变动配置更安全的默认值,并将低级别 Linux 安全决策与部署过程解耦,从而鼓励最佳实践。
PodSecurityPolicy 的诞生
PodSecurityPolicy 源自 OpenShift 的 SecurityContextConstraints (SCC),该功能在 Red Hat OpenShift Container Platform 的第一个版本中就已存在,甚至早于 Kubernetes 1.0。PSP 是 SCC 的精简版本。
PodSecurityPolicy 创建的起源很难追溯,特别是因为它主要是在 Kubernetes 增强提案 (KEP) 流程之前添加的,当时设计提案仍然是一种形式。实际上,最终设计提案的存档仍然可用。然而,在第一个 pull request 合并后,创建了KEP Issue 号码五。
在添加创建 PSP 的第一段代码之前,有两个主要的 pull request 合并到 Kubernetes 中:一个定义了 Pod 容器新字段的 SecurityContext
子资源,以及 ServiceAccount API 的第一个迭代。
Kubernetes 1.0 于 2015 年 7 月 10 日发布,除了一个 alpha 质量的 SecurityContextDeny admission 插件(当时称为 scdeny
)之外,没有任何机制来限制工作负载的安全上下文和敏感选项。SecurityContextDeny 插件至今仍存在于 Kubernetes 中(作为 alpha 功能),并创建一个阻止使用安全上下文中某些字段的 admission 控制器。
PodSecurityPolicy 的根基是通过第一个关于安全策略的 pull request 添加的,该 PR 添加了基于 SCC (Security Context Constraints) 的新 PSP 对象的设计提案。这是一段为期九个月的漫长讨论,其中涉及 OpenShift SCC 的反复修改、多次 rebase,以及最终在 2016 年 2 月被重命名为 PodSecurityPolicy 并合并到上游 Kubernetes。现在 PSP 对象已经创建,下一步是添加一个可以强制执行这些策略的 admission 控制器。第一步是在不考虑用户或组的情况下添加 admission。添加了一个特定的issue 以跟踪将 PodSecurityPolicy 带入可用状态的进度,并且 admission 控制器的第一个版本在 2016 年 5 月的名为 PSP admission 的 pull request 中合并。大约两个月后,Kubernetes 1.3 发布。
这是一个时间表,概述了 PodSecurityPolicy 及其 admission 控制器诞生时的主要 pull request,并以 1.0 和 1.3 版本作为参考点。
之后,通过添加最初被搁置的功能,PSP admission 控制器得到了增强。授权机制于 2016 年 11 月初合并,允许管理员在集群中使用多个策略,为不同类型的用户授予不同级别的访问权限。后来,2017 年 10 月合并的pull request 修复了关于 PodSecurityPolicy 在变动顺序和字母顺序之间的排序设计问题,并继续构建我们所知的 PSP admission。之后,又进行了许多改进和修复,构建了近期 Kubernetes 版本中的 PodSecurityPolicy 功能。
Pod Security Admission 的兴起
尽管 PodSecurityPolicy 试图解决的问题至关重要,但它存在一些主要缺陷:
- 有缺陷的授权模型 - 用户可以创建 Pod,如果他们对允许该 Pod 的 PSP 具有 use 动词权限,或者该 Pod 的 service account 对允许的 PSP 具有 use 权限。
- 难以推出 - PSP 是 fail-closed 的。也就是说,在没有策略的情况下,所有 Pod 都会被拒绝。这主要意味着它不能默认启用,并且用户在启用此功能之前必须为所有工作负载添加 PSP,因此不提供审计模式来发现哪些 Pod 不会被新策略允许。选择加入模型还导致测试覆盖率不足,并由于跨功能不兼容而频繁出现故障。与 RBAC 不同,没有一种强烈的文化要求项目随附 PSP 清单。
- 不一致的无边界 API - API 增长过程中存在大量不一致之处,尤其是有许多针对小众用例的需求:例如 labels, scheduling, fine-grained volume controls 等。它具有糟糕的可组合性和弱优先顺序模型,导致意外的变动优先顺序。这使得将 PSP 与其他第三方 admission 控制器结合使用非常困难。
- 需要安全知识 - 有效使用仍然需要理解 Linux 安全原语。例如 MustRunAsNonRoot + AllowPrivilegeEscalation。
PodSecurityPolicy 的经验得出结论,大多数用户只关心两到三个策略,这促使创建了Pod Security Standards,该标准定义了三个策略:
- Privileged - 无限制策略。
- Baseline - 限制最小的策略,允许默认的 Pod 配置。
- Restricted - 安全最佳实践策略。
PSP 的替代品,新的Pod Security Admission 是 Kubernetes v1.25 中的一个内置的稳定版 admission 插件,用于在命名空间级别强制执行这些标准。它使得无需深厚的安全知识也能轻松实施基本的 Pod 安全。对于更复杂的用例,你可能需要一个可以轻松与 Pod Security Admission 结合使用的第三方解决方案。
下一步
有关 SIG Auth 流程的更多详细信息,包括 PodSecurityPolicy 的移除和 Pod Security admission 的创建,可以查阅KubeCon NA 2019 上的 SIG auth 更新和KubeCon NA 2021 上关于 PodSecurityPolicy 替代方案:过去、现在和未来的演讲记录。
特别是关于 PSP 的移除,博客文章PodSecurityPolicy 弃用:过去、现在和未来仍然准确。
对于新的 Pod Security admission,文档已经可用。此外,博客文章Kubernetes 1.23: Pod Security 晋级 Beta 版以及 KubeCon EU 2022 演讲Pod Security 漫游指南提供了很棒的实践教程供学习。