4. Pod安全标准(PSA):Kyverno实现Pod Security Admission(基线/受限模式)

在Serverless集群中,用户Pod的权限控制是安全合规的核心。Kubernetes 1.23+内置了Pod Security Admission(PSA),通过定义特权(Privileged)、基线(Baseline)和受限(Restricted)三种标准来限制Pod行为。然而,原生PSA仅支持命名空间级别的标签控制,缺乏细粒度策略和审计能力。Kyverno作为动态准入控制器,可以增强PSA的实现,支持基于资源标签、命名空间、集群角色的精细化策略,并提供审计(Audit)和报告(Report)功能。

核心目标:使用Kyverno策略引擎,在Serverless集群中强制实施Pod安全标准(基线/受限模式),确保所有工作负载符合最小权限原则,同时保留Serverless弹性伸缩的优势。

4.1 Pod安全标准(PSA)概述

Pod安全标准定义了三个策略级别,每个级别对Pod的安全上下文、卷类型、容器运行时等有不同的限制。下表对比了三个级别的关键差异:

策略级别 适用场景 核心限制 典型Serverless用例
Privileged 系统组件、监控Agent 无限制,允许特权容器、hostNetwork、hostPID等 节点级DaemonSet(如日志采集器)
Baseline 通用工作负载 禁止特权容器、hostNetwork、hostPID、hostIPC;限制seccomp默认配置 无状态微服务、API网关
Restricted 高安全敏感工作负载 在Baseline基础上,强制只读根文件系统、禁止allowPrivilegeEscalation、限制capabilities、强制seccomp=RuntimeDefault 金融交易、数据处理、用户数据服务
Serverless最佳实践:推荐对大多数Serverless工作负载使用Restricted模式,因为Serverless Pod通常不需要持久化存储或特权操作。对于需要挂载ConfigMap或Secret的Pod,使用Baseline模式即可。

4.2 Kyverno实现PSA的策略架构

Kyverno通过ClusterPolicy资源来定义PSA策略。每个策略包含match(匹配条件)、validate(验证规则)和background(后台扫描)三个核心部分。下图展示了Kyverno PSA策略的完整执行流程:

Kyverno PSA策略执行流程 用户提交Pod Kyverno准入控制器 策略匹配(Match) 验证规则(Validate) 审计/报告(Audit) 允许 / 拒绝 / 警告 Pod创建/更新 说明: • 策略匹配:按命名空间、标签、PodSpec选择 • 验证规则:检查securityContext、capabilities等 • 审计模式:不拒绝,仅生成报告

4.3 基线模式(Baseline)策略实现

基线模式适用于大多数Serverless工作负载。它禁止特权容器、hostNetwork、hostPID等高风险配置,但允许挂载卷、使用非root用户等常见操作。以下是一个完整的Kyverno基线策略示例:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: psa-baseline
spec:
  validationFailureAction: Enforce  # 强制模式:拒绝违规Pod
  background: true                 # 后台扫描已有资源
  rules:
  - name: baseline-privileged-containers
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "基线模式:禁止特权容器。"
      pattern:
        spec:
          containers:
          - securityContext:
              privileged: false
  - name: baseline-host-network
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "基线模式:禁止使用hostNetwork。"
      pattern:
        spec:
          hostNetwork: false
  - name: baseline-host-pid
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "基线模式:禁止使用hostPID。"
      pattern:
        spec:
          hostPID: false
  - name: baseline-seccomp
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "基线模式:seccomp必须设置为RuntimeDefault或Localhost。"
      pattern:
        spec:
          securityContext:
            seccompProfile:
              type: "RuntimeDefault | Localhost"
注意:基线模式允许使用非root用户和挂载卷,但禁止hostPath卷类型。在Serverless集群中,建议使用emptyDir或ConfigMap卷替代hostPath。

4.4 受限模式(Restricted)策略实现

受限模式在基线模式的基础上增加了更严格的限制,包括:强制只读根文件系统、禁止权限提升、限制capabilities、强制seccomp=RuntimeDefault。这是Serverless集群中推荐的默认策略。以下是一个完整的受限模式策略:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: psa-restricted
spec:
  validationFailureAction: Enforce
  background: true
  rules:
  - name: restricted-privileged-containers
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:禁止特权容器。"
      pattern:
        spec:
          containers:
          - securityContext:
              privileged: false
  - name: restricted-allow-privilege-escalation
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:禁止allowPrivilegeEscalation。"
      pattern:
        spec:
          containers:
          - securityContext:
              allowPrivilegeEscalation: false
  - name: restricted-capabilities
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:必须删除所有capabilities,仅保留NET_BIND_SERVICE。"
      pattern:
        spec:
          containers:
          - securityContext:
              capabilities:
                drop: ["ALL"]
                add: ["NET_BIND_SERVICE"]
  - name: restricted-read-only-rootfs
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:根文件系统必须为只读。"
      pattern:
        spec:
          containers:
          - securityContext:
              readOnlyRootFilesystem: true
  - name: restricted-seccomp
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:seccomp必须设置为RuntimeDefault。"
      pattern:
        spec:
          securityContext:
            seccompProfile:
              type: "RuntimeDefault"
  - name: restricted-run-as-non-root
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "受限模式:必须使用非root用户运行。"
      pattern:
        spec:
          securityContext:
            runAsNonRoot: true

4.5 策略模式:Enforce vs Audit

Kyverno支持两种策略执行模式:Enforce(强制)和Audit(审计)。在Serverless集群中,建议采用分阶段部署策略:

阶段 模式 行为 适用场景
1. 发现 Audit 不拒绝Pod创建,仅生成策略报告 评估现有工作负载的合规状态
2. 警告 Audit + 告警 生成报告并发送告警(如Slack、邮件) 通知团队需要整改
3. 强制 Enforce 拒绝违规Pod创建/更新 生产环境强制执行
Serverless迁移建议:对于已有Serverless集群,先使用Audit模式运行一周,收集所有违规Pod的清单。然后逐步修复,最后切换到Enforce模式。这样可以避免影响现有业务。

4.6 命名空间级别的策略绑定

Kyverno支持通过命名空间标签来绑定PSA策略。例如,为不同安全级别的命名空间应用不同的策略:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: psa-namespace-binding
spec:
  validationFailureAction: Enforce
  background: true
  rules:
  - name: restricted-for-high-security
    match:
      any:
      - resources:
          kinds:
          - Pod
          namespaceSelector:
            matchLabels:
              security-level: high
    context:
    - name: psa-restricted
      apiCall:
        urlPath: "/apis/kyverno.io/v1/clusterpolicies/psa-restricted"
        jmesPath: "spec.rules"
    validate:
      message: "命名空间security-level=high必须使用受限模式。"
      foreach:
      - list: "request.object.spec.containers"
        deny:
          conditions:
            any:
            - key: "{{ element.securityContext.privileged }}"
              operator: Equals
              value: true
  - name: baseline-for-medium-security
    match:
      any:
      - resources:
          kinds:
          - Pod
          namespaceSelector:
            matchLabels:
              security-level: medium
    validate:
      message: "命名空间security-level=medium必须使用基线模式。"
      pattern:
        spec:
          hostNetwork: false
          hostPID: false

4.7 策略测试与验证

部署策略后,可以使用以下命令验证策略是否生效:

# 查看所有Kyverno策略
kubectl get clusterpolicy

# 查看策略报告(Audit模式)
kubectl get policyreport -n <namespace>

# 测试基线模式:创建一个特权容器
kubectl run test-privileged --image=nginx --privileged=true

# 预期输出:Error from server: admission webhook "validate.kyverno.svc" denied the request:
# 基线模式:禁止特权容器。

# 测试受限模式:创建一个允许权限提升的容器
kubectl run test-escalation --image=nginx --overrides='{"spec":{"containers":[{"name":"nginx","securityContext":{"allowPrivilegeEscalation":true}}]}}'

# 预期输出:Error from server: admission webhook "validate.kyverno.svc" denied the request:
# 受限模式:禁止allowPrivilegeEscalation。
关键指标:在Serverless集群中实施PSA后,预期可以减少90%的容器逃逸攻击面,消除所有特权容器和hostNetwork的使用,提升集群的合规评分至95%以上。

4.8 常见问题与避坑指南

  • 问题1:Init容器被忽略
    Kyverno策略默认只检查spec.containers,需要额外添加spec.initContainers的验证规则。
  • 问题2:Ephemeral容器未覆盖
    临时容器(Ephemeral Containers)也需要纳入PSA检查,建议在策略中增加spec.ephemeralContainers的匹配。
  • 问题3:Serverless平台自动注入的Sidecar
    某些Serverless平台(如Knative)会自动注入Sidecar容器,这些容器可能不符合PSA标准。需要与平台团队协调,确保Sidecar也遵循安全策略。
  • 问题4:策略冲突
    当多个ClusterPolicy同时匹配同一个Pod时,Kyverno会按优先级执行。建议使用policy.preconditions来避免冲突。
重要:在Serverless集群中,不要对系统命名空间(如kube-system、knative-serving、istio-system)应用受限模式,否则可能导致控制平面组件无法启动。建议使用命名空间选择器来排除系统命名空间。

4.9 本章小结

通过Kyverno实现Pod Security Admission,Serverless集群可以获得以下收益:

  • 细粒度控制:支持基于命名空间、标签、PodSpec的精细化策略
  • 审计能力:Audit模式帮助发现合规问题而不影响业务
  • 自动化合规:Enforce模式自动拒绝违规Pod,减少人工审核
  • Serverless适配:支持Knative、OpenFaaS等Serverless平台的Pod安全