【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节点内存资源的。

相关推荐
JAVA学习通1 小时前
励志从零打造LeetCode平台之C端竞赛列表
java·vscode·leetcode·docker·状态模式
сокол2 小时前
【网安-等保评测-基础记录】网络安全等级保护2.0 详解(定级、备案、测评、整改一站式指南)
网络·笔记·网络安全·云计算
qeen874 小时前
【算法笔记】模拟与高精度加减乘除
c++·笔记·算法·高精度·模拟
U盘失踪了5 小时前
什么是B/S 架构和 C/S 架构
笔记
像一只黄油飞5 小时前
第二章-02-注释
笔记·python·学习·零基础
xiebingsuccess5 小时前
ThingsPanel IoT Platform 学习笔记
笔记·学习
是上好佳佳佳呀5 小时前
【前端(七)】CSS3 核心属性笔记:单位、背景、盒子模型与文本换行
前端·笔记·css3
雾岛听蓝5 小时前
Qt 输入与多元素控件详解
开发语言·经验分享·笔记·qt
WAIT_TIME6 小时前
昇腾910B虚拟卡(vNPU)创建以及Docker挂载
docker·容器·昇腾·runtime·虚拟显卡·vnpu
大大杰哥6 小时前
Docker笔记
java·docker