告别 PSP,拥抱零信任:Kubernetes Pod 安全体系的演进与现代化重构
作者:庸子
适用版本:Kubernetes v1.28+
前置知识:理解 Pod 基础概念、RBAC 基础
目录
[告别 PSP,拥抱零信任:Kubernetes Pod 安全体系的演进与现代化重构](#告别 PSP,拥抱零信任:Kubernetes Pod 安全体系的演进与现代化重构)
[第一部分:历史的尘埃------为什么 PSP 会被时代抛弃?](#第一部分:历史的尘埃——为什么 PSP 会被时代抛弃?)
[第二部分:新时代的标准------Pod Security Standards (PSS)](#第二部分:新时代的标准——Pod Security Standards (PSS))
[第三部分:落地的抓手------Pod Security Admission (PSA)](#第三部分:落地的抓手——Pod Security Admission (PSA))
[第四部分:超越 PSA------当标准策略不够用时](#第四部分:超越 PSA——当标准策略不够用时)
第一部分:历史的尘埃------为什么 PSP 会被时代抛弃?
【专栏正文】
在 Kubernetes 早期(v1.10 - v1.21),Pod Security Policy (PSP) 是控制 Pod 安全上下文(如特权模式、宿主机路径挂载)的唯一标准机制。PSP 是一种集群级别的资源,它定义了 Pod 必须满足的条件才能被系统接受。
然而,PSP 在生产环境中极难维护,最终被社区废弃。其核心架构缺陷包括:
- 复杂的授权模型:PSP 的生效依赖于 RBAC。用户不仅需要
create pod的权限,还需要对应的usepsp 权限。这导致了"授权爆炸"------你需要为每个用户、每个 Namespace 去绑定 PSP,极易出现配置疏漏。 - 全有或全无:如果不配置任何 PSP,默认情况下,除了集群管理员,所有用户都无法创建 Pod。这种"白名单"默认行为导致很多新入门的用户直接卡在第一步。
- 资源阻塞:PSP 是全局的,但在旧版本中无法针对特定 Namespace 施加不同的灵活策略,导致多租户隔离极其困难。
废弃时间线:
- v1.21:标记为 deprecated(废弃)。
- v1.25:PSP 控制器被移除,API Server 不再识别
policy/v1beta1/podsecuritypolicy。
【架构师手记】
导师视角的反思:
PSP 的教训是什么?
PSP 最大的痛点在于它混淆了"安全策略"和"访问控制"的概念。为了用 PSP,你必须在 RBAC 里做文章,导致权限管理变得极其臃肿。
如果你现在的集群还在用 PSP:
请立即制定迁移计划。不要等到被迫升级到 v1.25 时才发现业务全部瘫痪。很多遗留系统之所以不敢升级 K8s,就是因为陷在 PSP 的泥潭里拔不出来。架构师的核心价值之一,就是主动规避这种技术债务。
第二部分:新时代的标准------Pod Security Standards (PSS)
【专栏正文】
为了取代 PSP,Kubernetes 社区提出了更轻量、更标准化的方案:Pod Security Standards (PSS)。PSS 不再是一种复杂的 API 资源,而是一套分类明确的策略定义标准。它将 Pod 安全控制分为三个等级,清晰明了:
- Privileged(特权的):
- 定义:完全开放,没有任何限制。
- 场景:仅限系统级组件(如网络插件、Ingress 控制器、存储插件)。
- 特征:允许特权容器、允许宿主机路径挂载、允许访问宿主机网络命名空间。
- Baseline(基线的):
- 定义:限制已知的特权提升模式,提供默认的"安全护栏"。
- 场景:大部分非核心应用、普通中间件。
- 特征:禁止
allowPrivilegeEscalation,禁止 hostPath,要求限制 Linux Capabilities,但允许以 root 用户运行(如果需要)。
- Restricted(受限的):
- 定义:实施最高的安全加固策略,符合 Pod Hardening 最佳实践。
- 场景:处理敏感数据的应用、多租户环境中的不可信租户。
- 特征:强制
runAsNonRoot(禁止 root),强制Drop ALLCapabilities,限制 Seccomp Profile,禁止privileged: true。
【架构师手记】
如何选择等级?
不要试图一步到位全员 Restricted。这会导致业务大面积报错(因为很多传统应用习惯了以 root 身份运行)。
渐进式落地路径:
- 先给
kube-system打上Privileged标签。 - 给大部分业务 Namespace 打上
Baseline标签,挡住最明显的特权漏洞。 - 逐个排查安全要求高的应用,要求其适配
Restricted策略(例如修改 Dockerfile 增加 USER 指令)。
这就是架构师做安全落地的节奏感:先止血,再固本,最后强身。
第三部分:落地的抓手------Pod Security Admission (PSA)
【专栏正文】
PSS 只是"标准",真正执行这些标准的是 Pod Security Admission (PSA)。PSA 是 K8s 内置的准入控制器,它通过给 Namespace 打标签 的方式来生效。这种方式比 PSP 简洁得多,不再依赖复杂的 RBAC 绑定。
PSA 支持三种模式(针对每个 PSS 等级):
- enforce:强制执行。违反策略的 Pod 将被拒绝创建。
- audit:审计模式。允许 Pod 创建,但在审计日志中记录违规行为,并在 K8s Events 中告警。
- warn:警告模式。允许 Pod 创建,但通过 API Server 返回警告信息给用户(例如 kubectl apply 时会看到 warning)。
实战配置:
假设我们要在 production 命名空间强制执行 Restricted 策略,同时开启审计和警告:
kubectl label --overwrite ns production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
测试违规:
尝试在 production 命名空间创建一个特权 Pod:
kubectl run hack --image=busybox --restart=Never --privileged --command -- sleep 3600 -n production
结果:
API Server 会直接报错:
Error from server (Forbidden): pods "hack" is forbidden: violates PodSecurity "restricted:latest": privileged (true)
【架构师手记】
高阶技巧:标签继承与豁免
有时候,某个 Namespace 默认是Baseline,但你只想允许一个特定的 ServiceAccount 跑特权 Pod(这很危险,但有时候为了监控不得不做)。
PSA 支持更细粒度的标签配置。你可以针对特定的 ServiceAccount 覆盖 Namespace 级别的策略:
# 即使 namespace 是 restricted,这个 SA 被豁免了
kubectl label --overwrite ns production \
exempted.sa.kubernetes.io/my-sa=privileged
注意:这种豁免操作必须被严格审计!在架构设计中,我建议配合 Kyverno 的策略,禁止普通用户随意添加这类豁免标签。
第四部分:超越 PSA------当标准策略不够用时
【专栏正文】
PSS/PSA 虽然简洁,但它只能覆盖"通用安全场景"。如果你有更复杂的需求,例如:
- 禁止使用
latest标签的镜像。 - 限制每个 Pod 最多只能申请 2 个 CPU。
- 强制 Pod 必须挂载特定的 ConfigMap。
- 强制镜像必须来源自某个特定的仓库。
这时,PSA 就无能为力了。现代架构师的选择是 Policy-as-Code(策略即代码) 工具,推荐使用 Kyverno 或 OPA Gatekeeper。
为什么推荐 Kyverno?
相比于 OPA(基于 Rego 语言,学习曲线陡峭),Kyverno 使用 K8s 原生的 YAML 语法定义策略,更符合 K8s 工程师的习惯。
Kyverno 实战:禁止 latest 标签
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-image-tag
spec:
validationFailureAction: Enforce # 阻断
background: true
rules:
- name: require-image-tag
match:
resources:
kinds:
- Pod
validate:
message: "Images using the 'latest' tag are not allowed."
pattern:
spec:
containers:
- image: "!*:latest" # 否定匹配
【架构师手记】
架构师的终极选择
Kyverno vs OPA vs PSA:
- PSA:作为第一道防线。它是免费的、内置的,开箱即用。必须把所有 Namespace 都打上
baseline标签。 - Kyverno/OPA:作为第二道防线。用来解决业务逻辑合规、供应链安全等更细粒度的问题。
迁移策略总结:
- 阶段一:清理集群中所有的
policy/v1beta1/podsecuritypolicy资源。 - 阶段二:引入 PSA,默认给
defaultnamespace 打baseline标签,给kube-system打privileged。 - 阶段三:安装 Kyverno,开始将复杂的 PSP 规则转化为 Kyverno Policy。
- 阶段四:逐步提升 Namespace 的 PSA 等级至
restricted,并配合 Kyverno 处理例外情况。
这不仅仅是工具的更替,是从"静态、僵化、难维护"向"动态、声明式、可扩展"的安全理念的进化。