Docker - 容器和宿主机之间的 ulimit 差异

9

我曾认为docker容器与主机共享这些属性。但是,在一个docker主机上,有以下的ulimit设置:

ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63399
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63399
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

但是在容器内部,有以下情况:

ulimit -a
-f: file size (blocks)             unlimited
-t: cpu time (seconds)             unlimited
-d: data seg size (kb)             unlimited
-s: stack size (kb)                8192
-c: core file size (blocks)        unlimited
-m: resident set size (kb)         unlimited
-l: locked memory (kb)             64
-p: processes                      unlimited
-n: file descriptors               65536
-v: address space (kb)             unlimited
-w: locks                          unlimited
-e: scheduling priority            0
-r: real-time priority             0

具体看 -n 设置 - 容器是否被限制为只有1024个打开文件,因为主机受到限制?请问有人能够解释一下容器内部的 ulimit 和底层 docker 主机的含义差异吗?


Docker 守护进程的 ulimit 设置会继承自 init(通常是 systemd),而 ulimit 命令行则会应用于用户限制。除非你手动覆盖默认设置,否则守护进程的限制会传递给容器。 - BMitch
1个回答

14

Docker在容器启动时可以设置资源限制,并且您可以使用--ulimit参数调整这些设置。例如,可以通过对containerd进程进行strace来轻松验证容器启动期间的设置,如下命令:

$ docker run -it --ulimit nofile=1024 alpine

将产生以下跟踪:

prlimit64(7246, RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024},  <unfinished ...>

在容器内检查 ulimit,可以得到预期的限制值:

Translated:

在容器中检查 ulimit,可以得到预期的限制值:

-n: file descriptors               1024
在没有显式指定--ulimit的情况下运行容器,此检查会给出不同的值(可能是从containerd继承而来),例如:
-n: file descriptors               1048576

为什么Docker允许设置比您在主机上通过检查ulimit观察到的限制更高的限制? 让我们打开man 2 prlimit

为什么Docker可以将限制设置得比您检查主机上的观察到的限制更高? 让我们打开man 2 prlimit
A privileged process (under Linux: one with the CAP_SYS_RESOURCE capability
in the initial user namespace) may make arbitrary changes to either limit value.

这意味着任何拥有CAP_SYS_RESOURCE权限的进程都可以设置任何资源限制,而Docker具有此权限。您可以通过检查/proc/$PID/status文件中的CapEff字段来验证它,其中$PIDcontainerd进程的PID,并使用capsh --decode解码此值:

$ pidof docker-containerd
675
$ cat /proc/675/status | grep CapEff
CapEff: 0000003fffffffff
$ capsh --decode=0000003fffffffff
0x0000003fffffffff=cap_chown,<...>,cap_sys_resource,<...>

总之:是的,Docker可以增加容器的资源限制,因为它有这样做的特权,并且您可以使用--ulimit参数调整这些限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接