为什么 docker 会在高内存使用率时崩溃?
Why does docker crash on high memory usage?
我有一个 docker 容器,它 运行 是我用 python Flask 编写的 REST 服务。我正在 运行 在 OSx 上使用 VirtualBox 连接容器。
这是容器启动时 OSx 上的内存统计信息:
所以,我有 ~3gb 的可用内存。所以我 运行 我的容器内存限制为 2 gb
docker run -d -m 2g --name mycontainer -p 5000:5000 foobar
现在我向容器上的服务 运行ning 发送约 100 个 REST 请求,同时 运行ning 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: 当 运行ning 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
运行ning 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
问题
如何避免此类崩溃?
这只是在我的本地机器上,但最终我打算将这个容器部署到生产环境中。我应该遵循哪些方法来防止崩溃?我应该在 Nginx 负载均衡器后面放置此容器的多个克隆吗?
在生产环境中,我计划 运行 单个服务器上的单个容器。如果我 运行 服务器上的单个容器而不 运行 该服务器上的任何其他东西,容器是否能够使用所有可用的计算资源?
欢迎来到精彩的资源世界:)
对容器施加限制并不会让你保持在限制之下,它只是告诉内核何时开始挤压你以及何时杀死你。您必须实际保持在您的限制以下。在许多情况下,这意味着观察您的内存占用情况,并在您无法在预算范围内满足请求时排队或丢弃请求。又名减载。
不过,好处是当您需要更多容器副本时,您现在有一个非常明确的信号。
我有一个 docker 容器,它 运行 是我用 python Flask 编写的 REST 服务。我正在 运行 在 OSx 上使用 VirtualBox 连接容器。
这是容器启动时 OSx 上的内存统计信息:
所以,我有 ~3gb 的可用内存。所以我 运行 我的容器内存限制为 2 gb
docker run -d -m 2g --name mycontainer -p 5000:5000 foobar
现在我向容器上的服务 运行ning 发送约 100 个 REST 请求,同时 运行ning 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: 当 运行ning 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
运行ning 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
问题
如何避免此类崩溃?
这只是在我的本地机器上,但最终我打算将这个容器部署到生产环境中。我应该遵循哪些方法来防止崩溃?我应该在 Nginx 负载均衡器后面放置此容器的多个克隆吗?
在生产环境中,我计划 运行 单个服务器上的单个容器。如果我 运行 服务器上的单个容器而不 运行 该服务器上的任何其他东西,容器是否能够使用所有可用的计算资源?
欢迎来到精彩的资源世界:)
对容器施加限制并不会让你保持在限制之下,它只是告诉内核何时开始挤压你以及何时杀死你。您必须实际保持在您的限制以下。在许多情况下,这意味着观察您的内存占用情况,并在您无法在预算范围内满足请求时排队或丢弃请求。又名减载。
不过,好处是当您需要更多容器副本时,您现在有一个非常明确的信号。