我一直在尝试了解roribio16/alpine-sqs
在一台机器上运行 docker 镜像时遇到的问题。每当我尝试在不指定任何其他设置的情况下运行镜像时,docker run roribio16/alpine-sqs
[xxxx@yyyy ~]$ docker run roribio16/alpine-sqs
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/elasticmq.conf" during parsing
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/insight.conf" during parsing
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/sqs-init.conf" during parsing
2021-05-29 15:48:41,216 INFO Set uid to user 0 succeeded
2021-05-29 15:48:41,222 INFO RPC interface 'supervisor' initialized
2021-05-29 15:48:41,222 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2021-05-29 15:48:41,222 INFO supervisord started with pid 1
2021-05-29 15:48:42,225 INFO spawned: 'sqs-init' with pid 9
2021-05-29 15:48:42,229 INFO spawned: 'elasticmq' with pid 10
2021-05-29 15:48:42,230 INFO spawned: 'insight' with pid 11
cp: can't stat '/opt/custom/*.conf': No such file or directory
> [email protected] start /opt/sqs-insight
> node index.js
15:48:42.605 [main] INFO org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
Loading config file from "/opt/sqs-insight/lib/../config/config_local.json"
15:48:42.929 [elasticmq-akka.actor.default-dispatcher-2] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
Unable to load queues for undefined
Config contains 0 queues.
library initialization failed - unable to allocate file descriptor table - out of memorylistening on port 9325
2021-05-29 15:48:43,233 INFO success: sqs-init entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,233 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,234 INFO success: insight entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,234 INFO exited: sqs-init (exit status 0; expected)
2021-05-29 15:48:44,318 INFO exited: elasticmq (terminated by SIGABRT (core dumped); not expected)
2021-05-29 15:48:45,322 INFO spawned: 'elasticmq' with pid 67
15:48:45.743 [main] INFO org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
15:48:46.044 [elasticmq-akka.actor.default-dispatcher-2] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
library initialization failed - unable to allocate file descriptor table - out of memory2021-05-29 15:48:47,223 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:47,389 INFO exited: elasticmq (terminated by SIGABRT (core dumped); not expected)
2021-05-29 15:48:48,393 INFO spawned: 'elasticmq' with pid 89
15:48:48.766 [main] INFO org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
15:48:49.066 [elasticmq-akka.actor.default-dispatcher-3] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
library initialization failed - unable to allocate file descriptor table - out of memory^C2021-05-29 15:48:49,559 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:49,559 WARN received SIGINT indicating exit request
2021-05-29 15:48:49,559 INFO waiting for insight, elasticmq to die
2021-05-29 15:48:49,566 INFO stopped: insight (terminated by SIGTERM)
2021-05-29 15:48:50,431 INFO stopped: elasticmq (terminated by SIGABRT (core dumped))
经过一番谷歌搜索,我发现这个帖子有人在运行其他随机图像时遇到了同样的问题,然后发帖称他们设法通过在运行图像时设置一些 ulimit 来使图像运行,这对我也有用(docker run --ulimit nofile=122880:122880 roribio16/alpine-sqs
)。
当我没有使用此配置时,我检查了容器内部设置的 ulimits
docker exec -it ca bash
$ ulimit -a
发现nofile
设置太高了,我认为如果同时打开太多文件,则会导致容器内存耗尽。但我不太了解这是如何工作的,因此如果有人能就该特定主题做出澄清,我将不胜感激。
无论如何,我之所以这么胡言乱语,是想尝试找到默认 docker 容器 ulimits 的设置位置,因为我不明白为什么在我使用的机器上它们这么高。我有另一台机器没有这个问题。
我可以找到很多方法来更改默认限制,但似乎没有太多关于这些限制在哪里设置的信息。我理解根据docker 文档如果未设置自定义值,则 ulimits 应该从我的系统继承,但据我所知,我的系统 nofile 设置比我在容器中看到的要低得多。
(两台机器都运行 manjaro linux,但没有这个问题的是 XFCE,而有这个问题的是 KDE)。
答案1
我找到了这个问题的解释这个帖子。
在某些时候,Java 8 似乎会为定义的打开文件数量分配内存。如果此数字太大,java 进程将退出并报告错误消息:
库初始化失败 - 无法分配文件描述符表 - 内存不足 *** JBossAS 进程 (85) 收到 ABRT 信号 ***
在我的例子中,我尝试在 Docker 容器中使用 Java 8 启动 Wildfly 17 应用程序服务器。应启动服务器的用户设置了大量打开的文件:
bash-4.2$ ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 29783
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1073741816
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) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
在当前 Docker 版本(对我来说:20.10.21)中,默认打开文件数为infinity
。您必须注意,docker 守护进程(dockerd)的打开文件数量与启动容器时打开的文件数量不同。
打开文件的数量docker 守护进程在 systemd 服务配置文件中配置。您可以使用命令覆盖它systemctl edit docker.service
。这将在中创建一个新文件/etc/systemd/system/docker.service/docker.service.d/
。在本例中,我将文件命名为override.conf
。我设置了以下属性:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --default-ulimit nofile=8096:8096 --containerd=/run/containerd/containerd.sock
Environment="HTTP_PROXY=http://xxx.xxx.xxx.xxxx:yyyy"
Environment="HTTPS_PROXY=http://xxx.xxx.xxx.xxxx:yyyy"
**# LimitNOFILE=infinity**
请注意,我没有覆盖infinity
docker 守护进程本身的默认值 ()。您可以使用命令# cat /proc/$pid/limits
($pid = process id) 检查为进程设置的实际打开文件数量。这将打印出 docker 守护进程的大量打开文件:
# cat /proc/828/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes unlimited unlimited processes
Max open files 1073741816 1073741816 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 29783 29783 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
正如你已经发现的那样链接帖子,您必须限制启动 docker 容器时打开的文件数量。容器内的进程从此值 (-> ) 继承。这是通过docker 守护进程的ulimit -a
程序参数实现的,该参数也在我的服务配置文件中定义。8096 个打开文件的值对于我的 wildfly 应用服务器来说已经足够了,并为我解决了这个问题。--default-ulimit nofile=8096:8096
/etc/systemd/system/docker.service.d/override.conf
我希望这个答案有助于澄清这个问题。