3. Serverless 安全基线:最小权限原则、只读根文件系统、禁止特权容器

Serverless 架构通过将基础设施管理抽象化,显著提升了部署效率,但也引入了新的安全挑战。在 Serverless 集群中,Pod 的生命周期极短、数量庞大,传统的安全边界模型难以适用。因此,建立一套基于容器运行时的安全基线,是保障 Serverless 工作负载安全合规的基石。本章聚焦于三大核心安全基线:最小权限原则、只读根文件系统和禁止特权容器,并阐述如何通过 Kyverno 策略引擎实现自动化强制实施。

3.1 安全基线总览

下表对比了三大安全基线的核心目标、风险场景及 Kyverno 策略类型:

安全基线 核心目标 典型风险场景 Kyverno 策略类型
最小权限原则 限制容器进程的 Linux Capabilities 和用户 ID 容器以 root 运行,攻击者利用高权限进行容器逃逸 validate / mutate
只读根文件系统 禁止容器在运行时修改其根文件系统 恶意脚本写入木马、篡改系统二进制文件 validate / mutate
禁止特权容器 禁止 privileged: true 及高危 Capabilities 特权容器直接操作宿主机内核,完全绕过隔离 validate

3.2 最小权限原则

最小权限原则要求每个容器只拥有完成其任务所必需的最小权限集。在 Kubernetes 中,这主要体现在两个方面:Linux Capabilities 的裁剪和 SecurityContext 中 runAsNonRoot 的强制。

3.2.1 核心策略:禁止添加高危 Capabilities

Kyverno 可以通过 validate 策略拒绝包含 SYS_ADMIN、NET_ADMIN、SYS_PTRACE 等高危 Capabilities 的 Pod。同时,建议使用 mutate 策略自动为未显式声明 SecurityContext 的容器添加 drop: ["ALL"],实现“默认拒绝”的安全模型。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-capabilities
spec:
  validationFailureAction: Enforce
  rules:
  - name: drop-all-and-add-only-required
    match:
      any:
      - resources:
          kinds:
          - Pod
    preconditions:
      all:
      - key: "{{ request.operation }}"
        operator: In
        value:
        - CREATE
        - UPDATE
    validate:
      message: "容器必须 drop ALL capabilities,且只能添加白名单内的 capabilities。"
      foreach:
      - list: "request.object.spec.containers"
        deny:
          conditions:
            any:
            - key: "{{ element.securityContext.capabilities.drop }}"
              operator: AnyNotIn
              value:
              - ALL
    mutate:
      patchStrategicMerge:
        spec:
          containers:
            - (name): "*"
              securityContext:
                capabilities:
                  drop:
                  - ALL
                  add:
                  - NET_BIND_SERVICE
                runAsNonRoot: true
关键点: 上述策略同时使用了 validate 和 mutate。validate 部分确保用户不会绕过规则,mutate 部分则自动为合规的 Pod 注入安全配置,降低用户的使用门槛。

3.3 只读根文件系统

只读根文件系统(readOnlyRootFilesystem: true)是防止容器被持久化篡改的有效手段。即使攻击者通过应用漏洞获得了容器内的 shell,也无法修改系统二进制文件、安装持久化后门或篡改配置文件。

3.3.1 策略实现:强制只读并允许临时存储

Kyverno 策略需要强制设置 readOnlyRootFilesystem: true,同时允许容器挂载 emptyDir 卷用于写入临时数据(如日志、缓存)。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-readonly-rootfs
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-readonly-rootfs
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "容器必须设置 readOnlyRootFilesystem: true。"
      foreach:
      - list: "request.object.spec.containers"
        deny:
          conditions:
            any:
            - key: "{{ element.securityContext.readOnlyRootFilesystem }}"
              operator: NotEquals
              value: true
  - name: auto-mount-tmp-volume
    match:
      any:
      - resources:
          kinds:
          - Pod
    mutate:
      patchStrategicMerge:
        spec:
          containers:
            - (name): "*"
              volumeMounts:
                - name: tmp-volume
                  mountPath: /tmp
          volumes:
            - name: tmp-volume
              emptyDir: {}
最佳实践: 对于需要写入数据的应用(如数据库、消息队列),应使用 PersistentVolumeClaim 或 emptyDir 显式挂载可写路径,而非直接修改根文件系统。Kyverno 的 mutate 策略可以自动为容器添加 /tmp 的 emptyDir 挂载,确保兼容性。

3.4 禁止特权容器

特权容器(privileged: true)拥有宿主机内核的全部权限,完全破坏了容器的隔离性。在 Serverless 环境中,特权容器是禁止的。此外,还应禁止 hostPID、hostNetwork、hostIPC 等共享宿主机命名空间的配置。

3.4.1 策略实现:一票否决

以下 Kyverno 策略直接拒绝任何包含特权模式或共享宿主机命名空间的 Pod:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged-containers
spec:
  validationFailureAction: Enforce
  rules:
  - name: privileged-containers
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "特权容器(privileged: true)是禁止的。"
      foreach:
      - list: "request.object.spec.containers"
        deny:
          conditions:
            any:
            - key: "{{ element.securityContext.privileged }}"
              operator: Equals
              value: true
  - name: host-namespaces
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "禁止使用 hostPID、hostIPC 或 hostNetwork。"
      deny:
        conditions:
          any:
          - key: "{{ request.object.spec.hostPID }}"
            operator: Equals
            value: true
          - key: "{{ request.object.spec.hostIPC }}"
            operator: Equals
            value: true
          - key: "{{ request.object.spec.hostNetwork }}"
            operator: Equals
            value: true

3.5 安全基线实施流程

下图展示了从策略定义到集群强制实施的完整流程:

Serverless 安全基线实施流程 Serverless 安全基线实施流程 1. 策略定义 2. 策略审计 3. 策略强制 4. 持续监控 各阶段说明: • 策略定义:编写 Kyverno ClusterPolicy YAML,定义安全基线规则。 • 策略审计:设置 validationFailureAction: Audit,观察违规事件而不阻断。 • 策略强制:切换为 Enforce 模式,自动拒绝不合规 Pod 创建。 • 持续监控:通过 Kyverno 报告和告警,持续跟踪策略命中情况。

3.6 策略组合与优先级

在实际生产环境中,上述三条基线应组合使用,形成纵深防御。Kyverno 支持策略的 优先级排序 和 异常豁免。例如,对于监控组件(如 Prometheus Node Exporter),可能需要 hostPID: true,此时应通过 exclude 字段或命名空间标签进行豁免。

注意: 豁免必须严格审批,并记录在案。建议为豁免 Pod 添加明确的注解(如 security-policy-exception: "monitoring"),便于审计追踪。切勿为所有命名空间或所有工作负载开启豁免。

3.7 本章小结

Serverless 安全基线是保障集群安全的第一道防线。通过 Kyverno 策略引擎,我们可以将“最小权限”、“只读根文件系统”和“禁止特权容器”等安全要求代码化、自动化,实现“安全左移”。在下一阶段,我们将深入探讨如何利用 Kyverno 进行镜像签名验证和供应链安全防护。