在容器内运行 `perf` 需要哪些 Capabilities

解读

国内云原生面试中,这道题常被用来区分“只会拉镜像”与“真正懂内核”的候选人。
perf 依赖内核的 perf_event_open 系统调用,而默认的 Docker 容器只保留 14 个默认 Capabilities,并未包含访问性能监控子系统所需的权限。
如果直接 docker runperf stat,会看到 Operation not permittedNo such file or directory,此时必须显式追加 CAP_SYS_ADMINCAP_SYS_PTRACE,并解决 /proc/sys/kernel/perf_event_paranoid 限制,否则镜像里即使装了 perf 也无法采样。

知识点

  1. perf_event_open 系统调用 需要 CAP_SYS_ADMIN 才能访问 CPU 性能计数器。
  2. CAP_SYS_PTRACE 保证容器可以读取 /proc/*/fd/* 及调试接口,避免 perf 附加到进程时再次被拒。
  3. perf_event_paranoid 内核参数:
    • 值为 3(部分国产操作系统默认)时,容器内完全禁止性能事件;
    • 需宿主机执行 echo 1 > /proc/sys/kernel/perf_event_paranoid--privileged 才能绕过。
  4. --cap-add 与 `--cap-drop** 的“白名单”机制:Docker 以白名单方式最小化权限,面试时必须明确说出具体 Capability 名称,而不是一句“给特权”糊弄。
  5. seccomp 与 AppArmor:国产云平台(如阿里云 ACK、腾讯云 TKE)默认加严规则,可能把 perf_event_open 直接拉黑,此时还需 --security-opt seccomp=unconfined 或自定义 profile。
  6. 多阶段构建优化:把 perf 工具链放在最终镜像里会增大体积,国内仓库拉取速度敏感,建议用 --no-install-recommends 并结合 dpkg -l | grep linux-tools 裁剪。

答案

容器内运行 perf 至少需要显式添加 CAP_SYS_ADMINCAP_SYS_PTRACE
若宿主机 perf_event_paranoid 大于 2,还需在宿主机侧调低该值或授予 --privileged
在国产云环境,还需检查 seccompAppArmor 是否拦截 perf_event_open,必要时加 --security-opt seccomp=unconfined
完整示例命令:

docker run --rm -it \
  --cap-add SYS_ADMIN \
  --cap-add SYS_PTRACE \
  --security-opt seccomp=unconfined \
  -v /proc/sys/kernel/perf_event_paranoid:/proc/sys/kernel/perf_event_paranoid \
  myperf:alpine perf stat -e cycles,instructions ls

拓展思考

  1. 最小权限实践:生产环境不可能直接 --privileged,可编写自定义 seccomp JSON,仅放行 perf_event_open,并结合 CAP_PERFMON(Linux 5.8+ 新 Capability)替代部分 CAP_SYS_ADMIN 权限,实现“国产等保”要求下的最小可用权限。
  2. sidecar 采集方案:把 perf 放到宿主机节点的 DaemonSet 容器里,通过 --pid=host 采样目标业务容器,业务容器无需任何额外 Capabilities,既满足审计又避免权限放大。
  3. eBPF 替代:国内不少金融客户已禁用 perf,转向 bcclibbpf 工具链,面试可补充“eBPF 只需 CAP_BPF + CAP_PERFMON 即可做 CPU 火焰图”,展示对下一代可观测技术的跟进。