--ulimit 限制的是什么?默认值是多少,soft 和 hard 有什么区别,nproc 为什么会被别的容器影响?这篇逐项实测,包括 nproc 跨容器相互影响的现象。
nofile soft=1048576 hard=1048576 nproc soft=unlimited hard=unlimited core soft=0 hard=unlimited stack soft=8192 hard=unlimited memlock soft=unlimited hard=unlimited
容器默认 nofile 是 1048576(soft 和 hard),nproc 不限制。Docker Desktop 上是这个值,Linux 宿主机上取决于 dockerd 的 systemd 配置,我没有测。
默认:打开了 1048573 个文件后失败:No file descriptors available(errno 24) | soft/hard = (1048576, 1048576) --ulimit nofile=64:64:打开了 61 个文件后失败:No file descriptors available(errno 24) | soft/hard = (64, 64) --ulimit nofile=64:1024(soft 64,hard 1024):打开了 61 个文件后失败:No file descriptors available(errno 24) | soft/hard = (64, 1024)
--ulimit nofile=64:64 后能打开的文件只剩 61 个(64 减去标准输入输出错误)。soft 才是实际生效的值;hard 是 soft 能调到的上限。
sh: error setting limit: Invalid argument 把 soft 调到 200(hard 128) 退出码 1 把 soft 调到 100 退出码 0(现在 100) sh: error setting limit: Operation not permitted uid 1000 把 hard 调到 4096 退出码 1 uid 1000 把 hard 降到 100 退出码 0 sh: error setting limit: Operation not permitted 再升回 128 退出码 1
soft 不能大于 hard(Invalid argument);普通用户不能把 hard 调高(Operation not permitted),只能调低,调低之后就升不回去了。
单个容器 --user 1000 --ulimit nproc=20:创建了 19 个子进程后失败:Resource temporarily unavailable 另外 2 个同样 uid 1000 的容器各占了 7 个进程(1 个 sh 加 6 个 sleep),再跑同样的测试:创建了 5 个子进程后失败:Resource temporarily unavailable 换成 uid 2000(同样 nproc=20):创建了 19 个子进程后失败:Resource temporarily unavailable 清掉占位容器后,uid 1000 再测一次:创建了 19 个子进程后失败:Resource temporarily unavailable
nproc 限制的是同一个 uid 的进程总数,而且是在整个系统范围内数,不分容器。同 uid 1000 的另外两个容器占了 14 个进程后,新容器的 nproc=20 只剩 5 个可用;换成 uid 2000 不受影响。所以几个共用同一 uid 的容器设同一个 nproc,会互相挤占;限制容器内进程数更合适的是 --pids-limit(见后面的 pids 一篇)。