【问题标题】:Why does docker crash on high memory usage?为什么 docker 在高内存使用时会崩溃?
【发布时间】:2016-08-14 00:53:01
【问题描述】:

我有一个 docker 容器,它运行我用 python Flask 编写的 REST 服务。我在 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

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

【问题讨论】:

  • Linux 内核有在内存不足时杀死进程的习惯。寻找它这样做的原因。
  • 如果你在单个服务器上运行单个容器,为什么要使用 contsiner?

标签: python flask docker scalability


【解决方案1】:

欢迎来到美妙的资源世界:)

对容器设置限制并不会让你停留在限制之下,它只是告诉内核什么时候开始挤压你,什么时候杀死你。你实际上必须保持在你的极限之下。在许多情况下,这意味着当您无法在预算范围内满足请求时,请注意您的内存占用和排队或丢弃请求。又名减载。

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

【讨论】:

  • “在许多情况下,这意味着当您无法在预算范围内满足请求时,观察您的内存占用并排队或丢弃请求”我想这样的事情是在应用程序/代码级别完成的?此外,是否有一些东西可以观察内存占用并在容器崩溃之前创建一个副本?我正在从生产角度考虑这个问题
  • 一些解决方案在内部包括用于自我监控和减载的库,具有响应负载增长容器的控制系统、响应负载添加副本的控制系统以及“机会性”内存在等待控制系统时借用。
  • 糟糕,按回车键。简而言之,在 OSS 领域,并非所有这些东西都可供您使用。 Kubernetes 内置支持自动缩放副本以响应负载,但仅限水平。 Kubernetes 也有能力描述借用内存的容器,但我认为这还没有我们想要的那么健壮。您确实需要比普通 Docker 更全面的东西来使这种情况变得易于管理,这就是 Kubernetes 存在的原因(仅作为示例)。
  • @TimHockin 我看到这个问题在 2016 年得到了回答;现在快 2020 年了,我刚刚进入 Docker-verse。到目前为止,我只使用“常规”Docker(没有 Kubernetes),因为我的使用场景只是用于少数个人容器的家庭服务器,还没有看到对 swarm 的需求。我最近遇到了守护进程崩溃的问题,想知道您是否认为 Kube“足够强大”?(根据您的最后评论)。:p
  • Kubernetes 正被世界各地的 很多 人以小型和大型集群的形式使用。我们现在确实有垂直 pod 自动缩放,但是没有它人们也相处得很好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
相关资源
最近更新 更多