【docker笔记-001】如何设置docker使得容器能在多个numa之间均匀使用内存

【未经授权,请勿转载,感谢支持】

都知道 numactl 有个 --interleave 的参数,可以将运行的应用绑定在指定的numa节点上,而且使用的内存可以均匀的在多个numa节点上。

例如运行一个脚本 我们可以这样:

bash 复制代码
// 假设本地有两个numa节点,分别为 0,1
// 如果不知道有多少个numa,可以用 lscpu 查询本地信息
numactl --interleave=0,1 bash ./test.sh

上述命令即可实现运行 test.sh 脚本时,在 0,1 两个numa上都均匀使用内存。

那么问题来了,如果我们是 docker 容器场景,怎样在不修改 docker 镜像的前提下,通过设置docker的配置,使得运行起来的所有容器,都自动可以绑定到多个numa 上,且均匀使用这些numa节点的内存呢?

有的兄弟,有的!下面,直接讲干货!

大致原理如下:

通过截获底层创建容器时 create 命令,在命令前面加上 numactl --interleave 即可。

步骤如下:

  1. 编写如下脚本
bash 复制代码
#!/bin/bash

# 定义 NUMA 策略
# 这里设置绑定节点 0,1 并交错分配内存
NUMA_ARGS="--interleave=0,1"

# 真正的 OCI 运行时路径 (通常是 runc,可以通过 which runc 确认)
# 如果你的系统使用的是 crun,请改为 /usr/bin/crun
REAL_RUNTIME="/usr/sbin/runc"

if [ ! -x "$REAL_RUNTIME" ]; then
    # 尝试备用路径
    REAL_RUNTIME="/usr/bin/runc"
fi

if [ ! -x "$REAL_RUNTIME" ]; then
    echo "Error: Cannot find runc. Please install runc or update the script." >&2
    exit 1
fi

# 解析参数
# Docker/containerd 会传递一系列参数,我们需要找到 "create" 或 "run" 命令,
# 并在其执行前插入 numactl。
# 但更简单的方法是:如果最后一个参数是 bundle 目录,或者命令是 create,
# 我们直接用 numactl 包裹 runc 的执行。

# 检查是否包含 "create" 子命令 (containerd 通常调用 create)
if [[ "$@" == *"create"* ]]; then
    # 构造新命令:numactl [numa_args] runc [original_args]
    exec numactl $NUMA_ARGS "$REAL_RUNTIME" "$@"
else
    # 如果是其他命令 (如 delete, kill, spec 等),直接透传给 runc,不加 numactl
    exec "$REAL_RUNTIME" "$@"
fi

将上面脚本内容存入到一个脚本文件中,例如我这里存放到如下路径中:

/usr/local/bin/docker-numa-runtime

然后将这个脚本添加可执行权限:

bash 复制代码
chmod +x /usr/local/bin/docker-numa-runtime
  1. 修改docker的daemon.json文件

vim /etc/docker/daemon.json

如果没有这个文件,可以先创建。添加如下 runtime 信息:

bash 复制代码
{
        "runtimes": {
                // numa-balanced 这个名字,建议不要修改
                "numa-balanced": {
                        "path": "/usr/local/bin/docker-numa-runtime", // 如果脚本的位置是自定义的路径,这里记得改一下路径,且确保脚本有可执行权限,最好是 root 权限。
                        "runtimeArgs": []  // 这里之所以参数留空,是因为脚本中已经处理参数了
                }
        },
        "default-runtime": "numa-balanced"  // 这里设置了默认运行时,表示所有的容器都按照上述情况执行;也可以不设置这个,只需要添加 docker run 参数即可,例如 "docker run --runtime numa-balanced ..."
}
  1. 重启docker
bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

ok,至此docker设置已完成!下面来验证成果!

先手动运行一个容器:

说明一下,容器中运行了一个redis,其中规格为16g,且运行了压测命令,让容器尽量使用完分配的内存。如果我设置在numa 0,1 上均匀使用的话,理论上 每个numa肯定会占用超过8G内存。

那么用如下命令,看一下实时的内存使用情况:

watch -n 1 "numastat -m"

bash 复制代码
                          Node 0          Node 1           Total
                 --------------- --------------- ---------------
MemTotal              1547117.36      1572864.00      3119981.36
MemFree               1508840.50      1562577.61      3071418.11
MemUsed                 38276.86        10286.39        48563.25
SwapCached                  0.00            0.00            0.00

可以看到,numa 0,1 上都使用了内存超过8GB,验证成功!

另外说明一下,我在 k3s 集群中用工具自动化部署容器,生成的容器也是会均匀使用多个numa节点内存资源的。

相关推荐
果壳science4 小时前
张祥前实验如何获取正电荷
笔记·科技·嵌入式硬件·硬件工程·制造
程序员老赵4 小时前
Docker 部署 Hue:轻松搭建数据库与数据仓库 SQL 查询平台
sql·docker·开源
上火的金鱼妹5 小时前
节点调度优化 + redis 现有问题优化
k8s
大叔学Linux5 小时前
FreeRTOS任务切换笔记
arm开发·笔记
职豚求职小程序刷题8 小时前
易方达基金2027秋招笔试|考什么+场次提醒
笔记
m0_617493948 小时前
昇腾 NPU Docker 部署实战:解决 stub library 报错并实现模型正常加载
运维·docker·容器
无锡银洲自动化9 小时前
煤粉测点频繁堵管?FD 防堵风压取样器现场调试小结
笔记·产品运营
ACP广源盛139246256739 小时前
Type-C 扩展坞选型笔记:DP1.4a 转 HDMI2.0 桥接方案 GSV2201E @ACP评估
笔记·硬件架构·硬件工程·视频·hdmi·国产芯片
xixiaoyunya9 小时前
Docker 常用命令与实战:从入门到部署一个简单应用
docker·容器·eureka
xian_wwq9 小时前
【学习笔记-一文读懂系列】读懂GBZ-195-2026《人工智能 工业智能体参考架构》
笔记·学习