为什么docker会因高内存使用率而崩溃?

时间:2016-04-21 03:33:21

标签: python flask docker scalability

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

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

enter image description here

所以,我有大约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. 在生产中,我打算在单个服务器上运行单个容器。如果我在服务器上运行单个容器而不在该服务器上运行任何其他容器,容器是否能够使用它可用的所有计算资源?

1 个答案:

答案 0 :(得分:3)

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

对容器施加限制不会让你保持在极限之下,它只会告诉内核何时开始挤压你以及何时杀死你。你必须实际上保持在你的极限以下。在许多情况下,这意味着在您无法满足预算要求的情况下,观察您的内存占用情况以及排队或丢弃请求。 AKA减载。

但好处是,当你需要更多容器副本时,你现在有一个非常明确的信号。