为什么docker在高内存使用率上崩溃?

我有一个docker容器运行我的REST服务写在Python Flask。 我在OSx上使用VirtualBox运行容器。

这是容器启动时OSx上的内存统计信息:

在这里输入图像说明

所以,我有~3GB的免费内存。 所以我运行我的容器内存限制为2 GB

docker run -d -m 2g --name mycontainer -p 5000:5000 foobar 

现在,我发送了100个REST请求到容器上运行的服务,同时运行docker stats

最终,docker集装箱崩溃。

在容器崩溃之前,我在docker stats的数据之下粘贴。

崩溃1 :运行100个不同的请求(容器崩溃几乎是瞬间的。

 CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 27ee4ed4f98a 99.27% 256.9 MB / 2.147 GB 11.96% 163.2 kB / 7.958 kB 107.4 MB / 0 B CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 27ee4ed4f98a 99.77% 324 MB / 2.147 GB 15.09% 163.2 kB / 7.958 kB 107.4 MB / 0 B CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 

崩溃2 :运行1次请求100次(大约30次后容器崩溃)

 CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 79.00% 891.5 MB / 2.147 GB 41.52% 12.13 MB / 429.8 kB 2.379 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 85.83% 892 MB / 2.147 GB 41.54% 12.13 MB / 429.8 kB 3.071 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 85.83% 892 MB / 2.147 GB 41.54% 12.13 MB / 429.8 kB 3.071 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 86.01% 892 MB / 2.147 GB 41.54% 12.13 MB / 429.8 kB 3.81 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 86.01% 892 MB / 2.147 GB 41.54% 12.13 MB / 429.8 kB 3.81 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 86.28% 892.2 MB / 2.147 GB 41.55% 12.13 MB / 429.8 kB 4.508 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 41fc484677fb 86.28% 892.2 MB / 2.147 GB 41.55% 12.13 MB / 429.8 kB 4.508 GB / 61.85 MB CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O 

docker ps -a在崩溃后显示以下内容

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 41fc484677fb foobar "python service.py" 7 minutes ago Exited (137) 2 minutes ago mycontainer 

运行dmesg会显示几个内存不足的错误:

 ➜ ~ docker exec -it mycontainer dmesg | grep "Out of memory" Out of memory: Kill process 2006 (python) score 872 or sacrifice child Out of memory: Kill process 2496 (python) score 873 or sacrifice child Out of memory: Kill process 2807 (python) score 879 or sacrifice child Out of memory: Kill process 3101 (python) score 875 or sacrifice child Out of memory: Kill process 5393 (python) score 868 or sacrifice child Out of memory: Kill process 5647 (python) score 868 or sacrifice child Out of memory: Kill process 5926 (python) score 877 or sacrifice child Out of memory: Kill process 6328 (python) score 873 or sacrifice child Out of memory: Kill process 7923 (python) score 872 or sacrifice child Out of memory: Kill process 10183 (python) score 873 or sacrifice child 

  1. 我怎样才能避免这样的崩溃?

  2. 这只是在我的本地机器上,但最终我打算将这个容器部署到生产。 我应该遵循什么方法来防止崩溃? 我应该在Nginx负载均衡器的后面放置这个容器的多个克隆吗?

  3. 在生产中,我打算在单个服务器上运行单个容器。 如果我在服务器上运行单个容器,而不在该服务器上运行其他任何东西,容器是否能够使用所有可用的计算资源?

欢迎来到精彩的资源世界:)

限制一个容器不会让你停留在限制之下,它只是告诉内核什么时候开始挤压你,什么时候要杀了你。 你必须保持低于你的限制。 在许多情况下,这意味着在预算内无法满足需求时,观察您的内存占用情况,排队或放弃请求。 AKA减载。

好处是,当你需要更多的容器副本时,你现在已经有了一个非常清晰的信号。

Interesting Posts