为什么docker在高内存使用率时崩溃?
我有一个docker容器,它运行用python Flask编写的REST服务。我在OSx上使用VirtualBox运行容器。为什么docker在高内存使用率时崩溃?
这是在OSX上的内存统计信息在容器启动时:
所以,我有3GB〜可用内存。所以,我跑我的容器2 GB
docker run -d -m 2g --name mycontainer -p 5000:5000 foobar
的内存限制,现在我送〜100个REST请求到容器上运行,而在同一时间运行docker stats
服务。
最终,码头容器崩溃。
在容器崩溃之前,我正在粘贴来自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:大约30之后当运行1个请求100倍(容器崩溃)
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
问题
我怎样才能避免这样的事故?
这只是在我的本地机器上,但最终我打算将此容器部署到生产中。我应该遵循什么方法来防止崩溃?我应该将这个容器的多个克隆放在Nginx负载均衡器后面吗?
在生产中,我计划在单个服务器上运行单个容器。如果我在服务器上运行单个容器,并且不在该服务器上运行其他任何内容,容器是否能够使用所有可用的计算资源?
欢迎资源:)
的容器上放置一个极限的精彩世界并没有让你留下的限制下,它只是告诉内核何时开始挤压你的时候杀您。你必须保持低于你的极限。在很多情况下,这意味着当你无法在预算范围内满足他们的需求时,观察你的内存占用情况,排队或放弃请求。 AKA减载。
不过,好处是当你需要更多的容器副本时,你现在有一个非常明确的信号。
“在很多情况下,这意味着当你无法在预算范围内满足他们的需求时,观察你的内存占用和排队或者丢弃请求”我想这样的事情是在应用程序/代码级完成的?另外,是否有东西会监视内存占用情况,并在容器崩溃之前创建副本?我从生产角度考虑这个问题 – Anthony
一些解决方案内部包括用于自我监控和卸载的库,拥有响应负载增长容器的控制系统,响应负载添加复制品的控制系统,以及“机会主义”内存借用等待控制系统。 –
哎呀,按回车。简而言之,在OSS的土地上,并非所有这些东西都可以提供给你。 Kubernetes内置支持自动缩放副本以响应加载,但只能水平。 Kubernetes也有能力描述借用记忆的容器,但我认为这并不像我们想要的那样健壮。您确实需要比普通Docker更全面的东西来使这种情况变得易于管理,这就是Kubernetes存在的原因(仅作为示例)。 –
如果内核内存不足,Linux内核就有杀死进程的习惯。找出它的原因。 –
如果您在单个服务器上运行单个容器,为什么使用contsiner? – dirn