欢迎光临
我们一直在努力

Kubernetes Pod Security 落地:AI 容器不要跑在 privileged 模式

Kubernetes Pod Security 落地:AI 容器不要跑在 privileged 模式

一、特权容器:AI 推理最常见的错误运维姿势

生产集群上一台 GPU 节点跑着三个模型服务。查 Pod 的 securityContext 时发现是空的。运维同事解释:"模型加载需要 /dev/nvidia0 设备,不跑 privileged 模式容器起不来。"

带着这个信念部署的 GPU 节点,攻击面是裸金属级别的。特权容器可以:

  • 访问宿主机的所有设备(不只是 GPU)
  • 修改内核参数和加载内核模块
  • 挂载宿主机文件系统
  • 逃逸到节点层,横向移动到其他 Pod

这些都发生在一行 privileged: true 之后。

Pod Security Standards 在 K8s 1.25 GA 之后已经提供了三层策略:Privileged、Baseline、Restricted。大多数生产场景应该锁定在 Baseline 级别。AI 推理负载的特殊需求——GPU 设备访问、大页内存、共享内存——完全可以通过精细权限配置满足,不需要特权模式。

二、SecurityContext 精细权限:用 capabilities 替代 privileged

privileged: true 是一个安全上极大的开关。它赋予了容器几乎所有的 Linux capabilities,外加禁用 seccomp 和 AppArmor。实际需求可以通过以下分解项逐一满足:

flowchart LR
subgraph 需求分解
A[需要访问 GPU] –> A1[device plugin 挂载]
B[需要大共享内存] –> B1[tmpfs 挂载 /dev/shm]
C[需要修改内核参数] –> C1[initContainer + 特定 cap]
D[需要低端口] –> D1[NET_BIND_SERVICE cap]
end
subgraph 安全策略
A1 –> P[Pod Security: Baseline]
B1 –> P
C1 –> P
D1 –> P
end
P –> Q[统一审计与准入控制]

每个需求的解决方案:

  • GPU 设备访问:使用 NVIDIA Device Plugin + nvidia.com/gpu 资源请求,不需要特权
  • 大共享内存:mount /dev/shm 为 tmpfs 而非宿主机路径
  • 内核参数:通过 initContainers 使用 CAP_SYS_ADMIN 一次性设置,主容器不需要
  • 低端口:如果推理服务需要监听 443,添加 CAP_NET_BIND_SERVICE

Baseline 策略本质上允许以下配置:

  • hostNetwork、hostPID、hostIPC 都设为 false
  • capabilities 只添加必要的,不包含 SYS_ADMIN 和 NET_RAW
  • runAsNonRoot 设为 true,但允许 root 用户(部分模型加载需要)

常见的'我也许以后会用到这些权限'思路是高风险的。权限缩小到最小可行集,这是安全左移最直接的实践。基础设施不需要漂亮话,需要的是在每一个 Pod manifest 里把这些字段填对。

三、生产级准入控制:OPA Gatekeeper 拦截特权 Pod

YAML 里写规范没人强制遵守,等于没写。准入控制器(Admission Controller)是确保策略落地的最后一道防线。

package admission

import (
"context"
corev1 "k8s.io/api/core/v1"
)

// AIWorkloadValidator 校验 AI 推理 Pod 的安全上下文
type AIWorkloadValidator struct {
// allowedCapabilities 允许的额外 capabilities 白名单
allowedCapabilities map[string]bool
}

// Validate 检查 Pod 的 securityContext 在部署前拦截不合规配置
func (v *AIWorkloadValidator) Validate(
ctx context.Context, pod *corev1.Pod,
) error {
for i, container := range pod.Spec.Containers {
sc := container.SecurityContext
if sc == nil {
return fmt.Errorf(
"容器 %s: securityContext 不允许为空",
container.Name,
)
}

// 规则1: 禁止 privileged 模式
if sc.Privileged != nil && *sc.Privileged {
return fmt.Errorf(
"容器 %s: privileged 模式被禁止,请使用细粒度权限",
container.Name,
)
}

// 规则2: 不允许以 root 用户运行
if sc.RunAsUser == nil || *sc.RunAsUser == 0 {
return fmt.Errorf(
"容器 %s: 禁止以 root 用户运行",
container.Name,
)
}

// 规则3: root 文件系统只读
if sc.ReadOnlyRootFilesystem == nil ||
!*sc.ReadOnlyRootFilesystem {
return fmt.Errorf(
"容器 %s: root 文件系统必须为只读",
container.Name,
)
}

// 规则4: capabilities 白名单校验
caps := sc.Capabilities
if caps != nil {
for _, add := range caps.Add {
if !v.allowedCapabilities[string(add)] {
return fmt.Errorf(
"容器 %s: capability %s 不在白名单中",
container.Name, add,
)
}
}
}
}
return nil
}

部署形态使用 OPA Gatekeeper 或 Kyverno 的 ValidatingWebhookConfiguration:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-security-ai-workloads
webhooks:
– name: pod-security.ai.dev
clientConfig:
service:
name: pod-security-webhook
namespace: security
path: /validate
rules:
– operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
namespaceSelector:
matchLabels:
workload-type: ai-inference
failurePolicy: Fail
timeoutSeconds: 5

注意两处设计细节:

  • failurePolicy: Fail:Webhook 故障时拒绝创建 Pod,防止合规性被绕过。这要求 webhook 服务本身高可用部署
  • namespaceSelector:只拦截打了 workload-type: ai-inference 标签的命名空间,避免影响系统组件

四、三个你会遇到的现实问题

GPU Operator 需要特权。NVIDIA GPU Operator 的 nvidia-device-plugin-daemonset 确实需要 privileged: true。但这是系统组件,它应该跑在 kube-system 命名空间。用户的推理 Pod 不需要特权——这是两个完全不同的安全边界。

共享内存大小。推理服务的 /dev/shm 默认是 64MB,但 NCCL 通信和多进程数据加载可能需要数 GB。解决方案不是开 privileged,而是在 volumes 里显式声明:

volumes:
– name: dshm
emptyDir:
medium: Memory
sizeLimit: 16Gi

模型权重目录写权限。模型文件通常挂载自 PVC,推理服务只需读取。但有些框架在加载时会在模型目录写入缓存文件。解决方式是把缓存路径重定向到 ephemeral volume,而不是给整个模型目录写权限。

不适合 Baseline 策略的少数场景:

  • GPU Direct RDMA 需要 hostNetwork 和 CAP_SYS_ADMIN,这需要评估是否真的需要 RDMA 还是 InfiniBand 就足够
  • 调试容器需要 CAP_SYS_PTRACE,但生产环境不应出现调试容器

五、总结

privileged: true 不是 AI 推理的必需品。GPU 设备访问通过 Device Plugin 解决,大共享内存通过 emptyDir 解决,特定能力通过精细 capabilities 添加。三个必须落地的动作:

  • Pod Security Admission:在命名空间标签中设置 pod-security.kubernetes.io/enforce: baseline
  • 准入 Webhook:部署自定义 ValidatingWebhook,在创建时拦截违规 Pod
  • 最小权限清单:为每种推理框架整理 securityContext 最小集文档,作为团队 Checklists
  • 基础设施的安全不是口号。它是每个 Pod manifest 里被填对的每一行 securityContext 配置。

    赞(0)
    未经允许不得转载:171主机测评 » Kubernetes Pod Security 落地:AI 容器不要跑在 privileged 模式
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址