--cpuset-cpus用于将容器进程严格绑定到指定物理cpu核心,实现cpu亲和性隔离;支持离散编号(如"0,2")和连续范围(如"1-3"),但不控制使用率,需配合--cpus等参数协同限频。
可以通过 docker run 的 --cpuset-cpus 参数,将容器内所有进程严格绑定到指定的物理 cpu 核心上,实现确定性的 cpu 资源隔离与性能优化。
理解 --cpuset-cpus 的作用
该参数指定容器可使用的 CPU 核心编号(从 0 开始),内核调度器会将容器中所有线程限制在这些核心上运行,不会跨到其他核心。它不控制 CPU 使用率(那是 --cpus 或 --cpu-quota 的职责),而是做“亲和性绑定”(CPU affinity)。
例如,在 8 核机器上:
-
--cpuset-cpus="0-3"表示只允许使用物理核心 0、1、2、3 -
--cpuset-cpus="0,2,4"表示仅限核心 0、2、4(跳过 1、3、5 等) -
--cpuset-cpus="1"表示独占核心 1,适合低延迟或实时任务
确认宿主机 CPU 核心编号与拓扑
Linux 中核心编号由内核按物理顺序分配,但可能受超线程(SMT)、NUMA 节点影响。需先查清真实拓扑,避免误绑逻辑核或跨 NUMA 节点:
- 用
lscpu查看总核数、Socket 数、每个 Socket 的核心数、是否启用超线程 - 用
cat /sys/devices/system/cpu/cpu*/topology/core_id查各逻辑 CPU 对应的物理 core ID - 用
numactl --hardware查 NUMA 节点与 CPU 核心映射关系
例如:若 CPU 0 和 CPU 1 属于同一物理核心(超线程对),而 CPU 2 和 CPU 3 属于另一核心,则 --cpuset-cpus="0,2" 比 --cpuset-cpus="0,1" 更能保障并行能力。
实际运行时绑定容器
启动容器时直接传参即可,无需额外配置:
- 绑定到核心 2 和 3:
docker run --cpuset-cpus="2,3" -it ubuntu:22.04 - 绑定到核心 0~1(连续范围):
docker run --cpuset-cpus="0-1" nginx - 配合内存节点绑定(提升 NUMA 局部性):
docker run --cpuset-cpus="4-7" --cpuset-mems="1" redis(假设 NUMA node 1 对应 CPU 4–7)
进入容器后可用 taskset -p $$ 验证当前 shell 进程的 CPU 亲和掩码,或用 cat /proc/self/status | grep Cpus_allowed_list 查看生效的核心列表。
注意事项与常见问题
该参数在容器生命周期内生效,但有几点需注意:
- 必须确保指定的核心编号真实存在,否则启动失败(报错 “invalid cpuset”)
- 若宿主机启用了 CPU 热插拔或动态拓扑变更,核心编号可能变化,建议在稳定环境中使用
- 多个容器绑定同一组核心时,仍会竞争该组内的 CPU 时间片(需配合
--cpu-shares或 CFS 配额调控) - 不兼容 Windows/macOS Docker Desktop 的 WSL2 或 HyperKit 后端——它们无法透传物理核心控制权,仅 Linux 主机原生运行有效
对于需要确定性延迟、避免缓存抖动、或与硬件设备(如 DPDK、GPU)协同调度的场景,--cpuset-cpus 是关键基础配置。











