L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Déploiement et opérations · SKILL.md

implementing-pod-security-admission-controller

implementing-pod-security-admission-controller

使用内置准入控制器在命名空间级别实施 Kubernetes Pod Security Admission(Pod 安全准入),强制执行基线和受限安全配置文件。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: implementing-pod-security-admission-controller description: 使用内置准入控制器在命名空间级别实施 Kubernetes Pod Security Admission(Pod 安全准入),强制执行基线和受限安全配置文件。 domain: cybersecurity subdomain: container-security tags: [kubernetes, pod-security-admission, psa, pod-security-standards, admission-controller] version: "1.0" author: mahipal license: Apache-2.0

实施 Pod Security Admission 控制器

概述

Pod Security Admission(PSA,Pod 安全准入)是 Kubernetes 内置的准入控制器(v1.25 起稳定版),在命名空间级别强制执行 Pod 安全标准(Pod Security Standards)。它替代了已弃用的 PodSecurityPolicy(PSP),提供三种安全配置文件:Privileged(特权)、Baseline(基线)和 Restricted(受限),以及三种强制模式:enforce(强制)、audit(审计)和 warn(警告)。

前置条件

  • Kubernetes v1.25+(PSA 为稳定/GA 版)
  • 具有 cluster-admin 权限的 kubectl
  • 无需依赖外部工具 - PSA 内置于 kube-apiserver

Pod 安全标准

Privileged(特权)配置文件

  • 无限制 - 不施加任何限制
  • 用例:系统级 Pod(kube-system、监控)

Baseline(基线)配置文件

  • 最低限制 - 防止已知权限提升
  • 阻止:特权容器、hostPID、hostIPC、hostNetwork、hostPorts、某些卷类型、超出运行时默认值的能力添加

Restricted(受限)配置文件

  • 严格限制 - 遵循安全最佳实践
  • 要求:非 root 运行、放弃所有能力、seccomp RuntimeDefault、考虑只读根文件系统
  • 阻止:基线配置文件中的一切,加上 root 运行、权限提升、非批准的卷类型

强制模式

模式行为用例
enforce拒绝违反策略的 Pod生产强制执行
audit将违规记录到审计日志强制执行前评估
warn向用户显示警告开发者反馈

实施

通过 Label 应用到命名空间

# 受限强制执行,同时启用审计和警告
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: v1.28
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.28
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.28
# staging 使用基线强制执行
apiVersion: v1
kind: Namespace
metadata:
  name: staging
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: v1.28
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.28
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.28
# 系统命名空间使用特权模式
apiVersion: v1
kind: Namespace
metadata:
  name: kube-system
  labels:
    pod-security.kubernetes.io/enforce: privileged

使用 kubectl 应用 Label

# 设置受限强制执行
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=v1.28 \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

# 设置基线强制执行
kubectl label namespace staging \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

# 检查当前 label
kubectl get namespace production -o jsonpath='{.metadata.labels}' | jq .

演练测试

# 测试在命名空间上应用受限策略的效果
kubectl label --dry-run=server --overwrite namespace staging \
  pod-security.kubernetes.io/enforce=restricted

# 输出显示已有哪些 Pod 会违反该策略
# 警告:命名空间 "staging" 中的现有 Pod 违反了新的 PodSecurity enforce 级别 "restricted:latest"

集群范围默认值(AdmissionConfiguration)

# /etc/kubernetes/psa-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
  - name: PodSecurity
    configuration:
      apiVersion: pod-security.admission.config.k8s.io/v1
      kind: PodSecurityConfiguration
      defaults:
        enforce: baseline
        enforce-version: latest
        audit: restricted
        audit-version: latest
        warn: restricted
        warn-version: latest
      exemptions:
        usernames: []
        runtimeClasses: []
        namespaces:
          - kube-system
          - kube-public
          - kube-node-lease
          - calico-system
          - gatekeeper-system
          - monitoring
          - falco

应用到 API Server

# 添加到 kube-apiserver 清单
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    - --admission-control-config-file=/etc/kubernetes/psa-config.yaml
    volumeMounts:
    - name: psa-config
      mountPath: /etc/kubernetes/psa-config.yaml
      readOnly: true
  volumes:
  - name: psa-config
    hostPath:
      path: /etc/kubernetes/psa-config.yaml
      type: File

合规 Pod 示例

符合 Restricted 要求的 Pod

apiVersion: v1
kind: Pod
metadata:
  name: restricted-pod
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  automountServiceAccountToken: false
  containers:
    - name: app
      image: myregistry/myapp:v1.0.0
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      resources:
        limits:
          cpu: 500m
          memory: 256Mi
        requests:
          cpu: 100m
          memory: 128Mi
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir: {}

符合 Baseline 要求的 Pod

apiVersion: v1
kind: Pod
metadata:
  name: baseline-pod
  namespace: staging
spec:
  containers:
    - name: app
      image: myregistry/myapp:v1.0.0
      securityContext:
        allowPrivilegeEscalation: false
      resources:
        limits:
          cpu: 500m
          memory: 256Mi

从 PodSecurityPolicy 迁移

步骤 1:审计当前状态

# 检查现有 PSP
kubectl get psp

# 检查哪些 ServiceAccount 使用了哪个 PSP
kubectl get clusterrolebinding -o json | \
  jq '.items[] | select(.roleRef.name | startswith("psp-")) | {name: .metadata.name, subjects: .subjects}'

步骤 2:将 PSP 映射到 PSA 配置文件

# 对每个命名空间确定所需的 PSA 级别
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
  echo "命名空间:$ns"
  kubectl label --dry-run=server namespace $ns \
    pod-security.kubernetes.io/enforce=restricted 2>&1 | head -5
done

步骤 3:应用 PSA Label(先审计)

# 从审计模式开始
kubectl label namespace production \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

步骤 4:审查并修复违规

# 检查审计日志中的违规
kubectl get events --field-selector reason=FailedCreate -A

步骤 5:启用强制执行

kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted

监控

# 检查事件中的 PSA 违规
kubectl get events --all-namespaces --field-selector reason=FailedCreate

# 检查审计日志
kubectl logs -n kube-system kube-apiserver-* | grep "pod-security.kubernetes.io"

# 列出命名空间的 PSA label
kubectl get namespaces -L pod-security.kubernetes.io/enforce

最佳实践

  1. 先用审计+警告,在强制执行前评估影响
  2. 使用演练测试,应用前测试强制执行效果
  3. 豁免系统命名空间(kube-system、监控),在集群默认值中排除
  4. 固定版本(enforce-version),确保跨升级的可预测行为
  5. 将集群范围基线设为默认值,然后针对特定命名空间收紧
  6. 与 Gatekeeper 结合,实现 PSA 之外的额外自定义策略
  7. 所有生产工作负载使用受限配置文件
  8. 记录豁免并附清晰理由
Skills enregistrées