16.7.4 Pod安全策略与运行时约束

Pod安全策略与运行时约束#

本节聚焦于限制 Pod 运行时权限、降低容器逃逸与横向移动风险。核心目标是通过安全策略与运行时约束,确保容器以最小权限运行、访问受控、行为可审计。

原理草图:准入与运行时约束链路

文章图片

关键安全控制要点(含示例)
- 禁用特权容器:避免 privileged: true,禁止挂载宿主机敏感目录。
- 用户与权限:设置 runAsNonRootrunAsUserfsGroup,避免 root 运行。
- 能力裁剪:通过 capabilities.drop 移除不必要的 Linux capabilities。
- 只读文件系统:启用 readOnlyRootFilesystem
- Seccomp 与 AppArmor:配置安全配置文件限制系统调用与权限。
- Pod 安全等级:按 restricted/baseline/privileged 分层约束。

示例:最小权限 Pod/Deployment 模板

# 文件:safe-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-safe
  namespace: prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-safe
  template:
    metadata:
      labels:
        app: web-safe
      annotations:
        container.apparmor.security.beta.kubernetes.io/web: localhost/k8s-web
        seccomp.security.alpha.kubernetes.io/pod: runtime/default
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
        fsGroup: 20001
      containers:
      - name: web
        image: nginx:1.25.4
        ports:
        - containerPort: 80
        securityContext:
          privileged: false
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop: ["ALL"]
        volumeMounts:
        - name: cache
          mountPath: /var/cache/nginx
      volumes:
      - name: cache
        emptyDir: {}

命令执行与解释

# 1) 创建命名空间
kubectl create ns prod

# 2) 启用 Pod Security Admission:强制 restricted,并开启告警/审计
kubectl label ns prod \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

# 3) 应用最小权限模板
kubectl apply -f safe-deploy.yaml

# 4) 验证 Pod 运行用户与只读根文件系统
kubectl exec -n prod deploy/web-safe -- id
kubectl exec -n prod deploy/web-safe -- sh -c 'touch /etc/test || echo "rootfs readonly"'
  • enforce: 准入强制策略,不符合直接拒绝。
  • warn/audit: 不阻断,但产生告警/审计日志。
  • runAsNonRoot/runAsUser: 防止 root 运行。
  • allowPrivilegeEscalation: false: 禁止提权。
  • capabilities.drop: ["ALL"]: 移除全部 capabilities,按需添加。
  • readOnlyRootFilesystem: 根文件系统只读,需写入的路径使用 emptyDir

Seccomp 与 AppArmor 安装与配置示例

# 1) 在节点上准备 AppArmor Profile(示例)
sudo mkdir -p /etc/apparmor.d
sudo tee /etc/apparmor.d/k8s-web >/dev/null <<'EOF'
#include <tunables/global>
profile k8s-web flags=(attach_disconnected) {
  # 允许基本读写
  file,
  # 拒绝挂载/内核模块
  deny mount,
  deny /sys/** wklx,
  deny /proc/** wklx,
}
EOF

# 2) 加载 AppArmor Profile
sudo apparmor_parser -r /etc/apparmor.d/k8s-web

# 3) 确认加载成功
sudo aa-status | grep k8s-web
  • apparmor_parser -r: 重新加载配置。
  • aa-status: 查看已加载的 profile。
  • Pod 注解 container.apparmor... 指定节点已加载的 profile 名称。

Pod Security Admission(PSA)强制策略示例

# 为测试命名空间启用 baseline(允许更宽松的能力)
kubectl create ns test
kubectl label ns test \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/enforce-version=latest

常见风险与排错
1. Pod 被拒绝创建(Admission 拒绝)

kubectl describe pod -n prod <pod-name>
kubectl get events -n prod --sort-by=.lastTimestamp | tail -n 10
  • 关注事件中的 violates PodSecurity "restricted" 提示,按提示补齐 securityContext
  1. AppArmor/Secomp 不生效
# 查看节点 AppArmor 支持
kubectl get node -o jsonpath='{.items[*].status.nodeInfo.kernelVersion}'

# 检查容器注解是否正确
kubectl get pod -n prod <pod-name> -o yaml | grep -A2 apparmor
  • AppArmor profile 未加载会导致 Pod 启动失败或不生效。
  1. 只读根文件系统导致应用异常
kubectl logs -n prod deploy/web-safe
# 应用写入路径需挂载 emptyDir 或 PVC

运行时约束落地建议
- 统一通过 CI 模板下发 securityContext,避免手工遗漏。
- 对必须提权的工作负载建立白名单与审批流程。
- 定期巡检命名空间标签,确保 enforce 未被移除。

练习
1. 在 dev 命名空间启用 restricted,尝试创建 privileged: true 的 Pod,观察拒绝信息。
2. 将示例 web-safereadOnlyRootFilesystem 去掉,验证应用能否创建 /etc/test
3. 为 test 命名空间启用 baseline,对比 restricted 下的拒绝差异并记录事件输出。