在 Kubernetes 中通过 `securityContext.capabilities.drop/add` 实现同等效果

解读

面试官把“Docker 能力”与“K8s 能力”做横向对比,核心想验证两点:

  1. 你是否真正理解 Linux Capabilities 的最小权限原则
  2. 你是否能把 Docker CLI 的 --cap-drop/--cap-add 迁移到 Kubernetes 的声明式 YAML,并解释相同与差异
    国内云原生岗位普遍要求“能写能排错”,所以不仅要给出 YAML 片段,还要说明如何验证、如何排障、如何与 PSP/OPA Gatekeeper 配合落地企业合规

知识点

  1. Linux Capabilities 分 40+ 项,Docker 默认开启 14 项左右,Kubernetes 继承宿主机内核能力。
  2. Docker 侧:--cap-drop=ALL --cap-add=NET_BIND_SERVICE 一次性动作;K8s 侧:securityContext.capabilities.drop/addPod 级或 Container 级字段,最终写入 OCI spec,由 containerd/docker-shim 交给 runc。
  3. 国内主流发行版(Aliyun Linux、TencentOS、Kylin V10)内核 ≥3.10,Capabilities 机制完整,但部分 CNI 插件(Terway、Cilium)会额外申请 NET_ADMIN,需要提前评估。
  4. 安全合规:金融、政务云要求“所有容器必须 drop ALL 且显式 add 白名单”,此条款直接对应 YAML 写法,也是面试官追问高频点。
  5. 排障命令:
    • kubectl exec -it pod -- grep Cap /proc/self/status 查看 effective permitted 集合;
    • audit2why 解析宿主机 audit.log,定位缺失能力导致的 syscall EPERM。

答案

以下 YAML 片段把 Docker 命令
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE --cap-add=CHOWN myapp:1.0
等价地搬到 Kubernetes,并满足国内合规“必须 drop ALL”要求:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels: {app: myapp}
  template:
    metadata:
      labels: {app: myapp}
    spec:
      securityContext:          # Pod 级统一策略,可选
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: app
        image: registry.cn-hangzhou.aliyuncs.com/abc/myapp:1.0
        securityContext:
          capabilities:
            drop: ["ALL"]                    # 等价于 --cap-drop=ALL
            add:                             # 白名单能力
            - NET_BIND_SERVICE               # 允许绑定 80/443
            - CHOWN                          # 修改文件属主
        ports:
        - containerPort: 8080

验证步骤(面试现场可直接口述):

  1. 应用配置后 kubectl exec -it <pod> -- capsh --print | grep Current 确认 Current 行仅包含 cap_chown,cap_net_bind_service+ep
  2. 若容器启动失败,使用 kubectl describe pod 查看 Events,若出现 OCI runtime create failed: container_linux.go:380: starting container process caused "apply caps: operation not permitted",说明宿主机禁用了对应能力,需检查 kubelet 启动参数 --allowed-unsafe-sysctls 或主机 /etc/security/limits.conf
  3. 金融云生产环境,还需同步提交 PSP(PodSecurityPolicy)或 Gatekeeper 模板,确保集群内所有工作负载强制 drop ALL,否则会被审计扣分

拓展思考

  1. sidecar 场景:Istio 1.15+ 要求 NET_ADMIN 做透明流量拦截,与“drop ALL”冲突。国内大厂(蚂蚁、字节)的解法是给 sidecar 单独 add NET_ADMIN,业务容器仍保持 drop ALL,通过双 securityContext 实现最小权限。
  2. 多架构镜像:在鲲鹏 ARM 节点上,个别能力(如 AUDIT_WRITE)在内核配置里被裁剪,add 会失败;CI 阶段需用 docker buildx能力探测脚本,提前过滤。
  3. 未来趋势:Kubernetes 1.25 开始 PSP 被废弃,Pod Security Standards(restricted 级别) 强制要求 drop ALL;面试可主动提及“我会用 restricted profile 做基线,再配合 OPA Gatekeeper 做二次校验”,体现对国内等保 2.0 三级的落地经验。