使用 `stress-ng` 容器打满 CPU 并观测 cgroups 限流

解读

国内云原生面试常把“压测+观测”作为动手能力分水岭
题目表面让候选人“跑个容器把 CPU 吃满”,实则考察四层:

  1. 能否在国产操作系统(麒麟、统信 UOS 或 CentOS 7)上快速起容器;
  2. 是否理解cgroup v1/v2在国产内核里的挂载差异;
  3. 会不会用docker run --cpus做硬限制,并实时验证throttle
  4. 能否把压测、监控、日志三板斧做成一条可复制命令,体现自动化思维。
    答不出“throttled_time”或“/sys/fs/cgroup/cpu…/cpu.stat”细节,会被直接判定为“只背过八股文”。

知识点

  • stress-ng 镜像源:国内建议用 registry.cn-hangzhou.aliyuncs.com/google_containers/stress-ng:latest,避免 dockerhub 拉不动。
  • --cpus--cpu-quota/--cpu-period 的换算关系:--cpus=1.5 等价于 quota=150000 & period=100000
  • cgroup 文件树
    – v1 路径 /sys/fs/cgroup/cpu,cpuacct/docker/<container>/cpu.stat 里的 nr_throttledthrottled_time
    – v2 路径 /sys/fs/cgroup/docker/<container>/cpu.stat,字段相同,但需确认系统已开启 systemd.unified_cgroup_hierarchy=1
  • 现场观测三件套
    1. docker stats 看实时百分比;
    2. cat cpu.stat 看累计节流;
    3. perf top -p $(pidof stress-ng) 看热点,证明真在跑满而非 idle loop。
  • 国产芯片适配:鲲鹏/飞腾 ARM 下需加 --cpu 0-7 绑定核,防止调度器漂移导致观测失真。

答案

  1. 准备镜像
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/stress-ng:latest

  2. 起容器并限制 0.5 核
    docker run -d --name stress --cpus 0.5 registry.cn-hangzhou.aliyuncs.com/google_containers/stress-ng:latest stress-ng --cpu 4 --timeout 600s

  3. 实时观测
    watch -n1 'docker stats --no-stream stress'
    可见 CPU 利用率被硬压到 50% 左右。

  4. 查看 cgroup 节流统计
    CONTAINER_ID=$(docker inspect stress -f '{{.Id}}')
    cat /sys/fs/cgroup/cpu,cpuacct/docker/$CONTAINER_ID/cpu.stat
    输出示例

    nr_periods 11983  
    nr_throttled 11980  
    throttled_time 299132488747  
    

    nr_throttled ≈ nr_periodsthrottled_time 持续增加,证明限流生效

  5. 清理
    docker stop stress && docker rm stress

拓展思考

  • 若面试官追问“业务容器被限流却未设置 --cpus”,优先排查宿主机 /etc/docker/daemon.json 是否写了 "default-cpus": 0.5;国产 PaaS 平台(阿里 ACK、腾讯 TKE 专有版)常在后台注入此参数。
  • 混合部署场景:宿主机为国产麒麟 + 鲲鹏 64 核,需用 taskset 把 stress 绑到特定 NUMA 节点,再观测 /proc/pressure/cpusome avg10,可量化节流对隔壁在线业务的延迟冲击。
  • 安全红线:生产 Namespace 必须加 --security-opt=no-new-privilegesdrop=ALL,防止 stress-ng 借 92 号 syscall 提权;央企护网演练中,此点被一票否决