需要了解主机和容器中“ulimit”的 nofile 设置

Bil*_*ill 5 linux ubuntu debian docker kubernetes

据我所知,如果我们需要nofile在Linux系统中调整“打开文件”(软和硬),我们需要运行命令ulimit或在相关配置文件中进行设置才能永久获得设置。但我对主机中运行的容器的设置有点困惑

例如,如果 Linux 操作系统将ulimitnofile 设置为 1024(软)和硬(4096),并且我使用 运行 docker --ulimit nofile=10240:40960,容器是否可以比其主机使用更多的 nofile?

更新

在我的环境中,当前运行的泊坞窗设置,

  • 在主机上 (Debian) - 65535(软)65535(硬)
  • Docker 守护进程设置最大值 - 1048576(软)1048576(硬)
  • 默认 docker run - 1024(软)4096(硬)
  • 定制 docker run - 10240(软)40960(硬)

我发现该应用程序可以运行大约 100K 个打开的文件,然后崩溃。这怎么理解呢?

真正的限制是什么?

Wil*_*.F. 7

例如,如果 Linux 操作系统将ulimitnofile 设置为 1024(软)和硬(4096),并且我使用 运行 docker ----ulimit nofile=10240:40960,容器是否可以比其主机使用更多的 nofile?

  • Docker 具有CAP_SYS_RESOURCE针对其权限设置的功能。这意味着 Docker 能够设置ulimit与主机不同的值。根据man 2 prlimit

特权进程(在 Linux 下:在初始用户命名空间中具有 CAP_SYS_RESOURCE 功能的进程)可以对任一限制值进行任意更改。

  • 因此,对于容器来说,要考虑的限制是由 docker 守护进程设置的。您可以使用以下命令检查 docker 守护进程限制:
$ cat /proc/$(ps -A | grep dockerd | awk '{print $1}')/limits | grep "files"
Max open files            1048576              1048576              files 
Run Code Online (Sandbox Code Playgroud)
  • 正如你所看到的,docker 19 有一个相当高的限制,1048576所以你的 40960将像魅力一样工作。

  • 如果您运行一个--ulimit设置为高于节点但低于守护进程本身的 docker 容器,您将不会发现任何问题,并且不需要授予额外的权限,如下例所示:

$ cat /proc/$(ps -A | grep dockerd | awk '{print $1}')/limits | grep "files"
Max open files            1048576              1048576              files     

$ docker run -d -it --rm --ulimit nofile=99999:99999 python python;
354de39a75533c7c6e31a1773a85a76e393ba328bfb623069d57c38b42937d03

$ cat /proc/$(ps -A | grep python | awk '{print $1}')/limits | grep "files"
Max open files            99999                99999                files 
Run Code Online (Sandbox Code Playgroud)
  • 您可以在文件上为 dockerd 设置新的限制/etc/init.d/docker
$ cat /etc/init.d/docker | grep ulimit
                ulimit -n 1048576
Run Code Online (Sandbox Code Playgroud)
  • 至于容器本身具有ulimit比docker守护进程更高的权限,这有点棘手,但可行,请参考这里
  • 我看到您已经标记了 Kubernetes 标签,但在您的问题中没有提及它,但是为了使其在 Kubernetes 上工作,容器将需要,这样您就可以在容器内以 root 身份securityContext.priviledged: true运行命令,这里是一个示例ulimit
image: image-name
  command: ["sh", "-c", "ulimit -n 65536"]
  securityContext:
    privileged: true
Run Code Online (Sandbox Code Playgroud)