Docker容器和内存消耗

Posted

技术标签:

【中文标题】Docker容器和内存消耗【英文标题】:Docker container and memory consumption 【发布时间】:2014-09-02 08:16:36 【问题描述】:

假设我正在启动大量基于相同 docker 映像的 docker 容器。这意味着每个 docker 容器都在运行相同的应用程序。可能是应用程序足够大并且需要大量硬盘内存。

docker 是如何处理的?

所有 docker 容器是否共享 docker 镜像中定义的静态部分?

如果没有,将应用程序复制到机器上用于运行 docker 容器并为每个 docker 容器挂载此应用程序目录的某个目录是否有意义?

【问题讨论】:

【参考方案1】:

Docker 在内核级别共享资源。这意味着应用程序逻辑在运行时永远不会被复制。如果您启动记事本 1000 次,它仍然只在硬盘上存储一次,对于 docker 实例也是如此。

如果您运行同一个 docker 映像的 100 个实例,您真正要做的就是在 100 个不同的独立时间线中保持 RAM 中同一软件的状态。主机处理器将每个容器实例的内存状态转移到控制它的软件,因此您确实消耗了运行应用程序所需的 RAM 内存的 100 倍。 为软件物理存储完全相同的字节码 100 次是没有意义的,因为应用程序的这一部分始终是静态的并且永远不会改变。 (除非您编写了一些疯狂的自我更改软件,或者您选择重建和重新部署容器的映像)

这就是为什么容器不允许开箱即用的持久性,以及 docker 与使用虚拟硬盘的常规 VM 的不同之处。但是,这仅适用于容器内部的持久性。硬盘上的 docker 软件正在更改的文件使用 docker 卷“挂载”到容器中,因此实际上并不是 docker 环境的一部分,而只是挂载到其中。 (阅读更多信息:https://docs.docker.com/userguide/dockervolumes/)

当您考虑这一点时,您可能想问的另一个问题是 docker 如何存储它在运行时对其磁盘所做的更改。真正值得一试的是 docker 是如何真正做到这一点的。容器硬盘的原始状态是镜像赋予它的。它可以写入此图像。与 docker 镜像中的内容相比,容器内部状态的变化不是写入镜像,而是由容器内部状态的变化构成。 Docker 使用了一种名为“Union Filesystem”的技术,它在 docker 镜像的初始状态之上创建了一个差异层。

这个“差异”(在下图中称为可写容器)存储在内存中,并在您删除容器时消失。 (除非你使用命令“docker commit”,但是:我不推荐这样做。你的新 docker 镜像的状态不会在 dockerfile 中表示,并且不能轻易地从重建中重新生成)

【讨论】:

以上是关于Docker容器和内存消耗的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Java 进程在 docker 容器与主机之间消耗两倍的内存

如何知道 docker 容器退出的原因?

容器docker的作用是啥 这四个好处你知道几个

docker基础

JVM故障问题排查心得「内存诊断系列」Docker容器经常被kill掉,k8s中该节点的pod也被驱赶,怎么分析?

基于Docker容器部署ELK日志分析系统