每个Docker镜像都应该包含JDK吗?

Sam*_*rly 18 java docker spring-boot microservices

所以,我对Docker很新.让我解释一下这个问题的背景.

  1. 我有10到20个Spring Boot微服务应用程序,每个应用程序都运行在我本地计算机上的不同端口上.

  2. 但是根据我的学习,为了迁移到Docker,每个服务必须位于不同的Docker容器中,以便快速部署或复制.

  3. 对于每个Docker容器,我们需要创建一个新的Docker镜像.

  4. 每个Docker镜像必须包含一个JRE,以便Spring Boot应用程序运行.最大约200 MB.这意味着每个泊坞窗图像最多为350 MB.另一方面,在我的本地PC上,我只有一个200 MB的JRE,每个应用程序只占用几MB空间.

  5. 基于此,我需要在本地系统上使用600 MB,但所有Docker镜像需要7 GB.

这种方法是否正确?应该将DockerHub中的"OpenJDK"添加到每个图像中吗?

即使目标PC可能已经拥有JDK,为什么图像的大小也很大?

atl*_*ine 28

你的理解是不正确的.

Docker图像由层组成; 见下图:

当您在映像中安装JRE时,让我们假设其校验和91e54dfb1179在下一张图片中,它将真正占用您的磁盘.

但是,如果所有容器都是基于相同的图像,并添加不同的东西,说,你的不同的微服务应用程序到薄R/W层,所有容器将共享91e54dfb1179,所以它不会是n*m关系.

您需要注意尽可能为所有Java应用程序使用相同的基本映像,并为精简R/W层添加不同的东西.

在此输入图像描述


Tez*_*zra 5

其他答案很好地涵盖了 Docker 分层,所以我只想为您的问题添加详细信息

这种方法是否正确?是否应该将 DockerHub 的“OpenJDK”添加到每个映像中?

是的。如果它不在图像中,它就不会在容器中。您可以通过重复使用尽可能多的图层来节省磁盘空间。所以试着把你的 Dockerfile 从“最不可能改变”写成“最有可能改变”。因此,当您构建映像时,您看到“使用缓存”的次数越多越好。

即使目标PC可能已经有JDK,为什么图像的大小仍然很大?

Docker 想要尽可能少地与主机打交道。Docker 甚至不想与主机打交道。它做的第一件事是创建一个虚拟机来隐藏。Docker 镜像假设主机将提供的唯一东西是空内存、磁盘和 CPU。所以每个 Docker 镜像还必须包含它自己的操作系统/内核。(这就是您最初的 FROM 所做的,选择要使用的基本操作系统映像)所以您的最终映像大小实际上是操作系统 + 工具 + 应用程序。不过,图像大小有点误导,因为它是所有层的总和,这些层在图像中重复使用。

(暗示)每个应用程序/微服务都应该在自己的容器中吗?

理想情况下,是的。通过将您的应用程序转换为隔离模块,可以更轻松地替换/负载平衡该模块。

在实践中,也许不是(对你来说)。Spring Boot 不是一个轻量级的框架。事实上,它是一个模块化代码的框架(在模块控制系统内有效运行模块控制系统)。现在您想托管 10-20 个?那可能无法在单个服务器上运行。Docker 将强制 Spring Boot 将自身加载到每个应用程序的内存中; 并且对象现在不能跨模块重用,所以那些也需要多实例化!如果您仅限于 1 个生产服务器,则不能选择水平扩展。(每个 Spring Boot 您将需要大约 1GB 的 HEAP(RAM),里程数非常基于您的代码库)。对于 10-20 个应用程序,重构以使应用程序更轻以用于 Docker 部署可能不可行/在预算内。更不用说,如果您不能在本地运行最小设置进行测试(RAM 不足),开发工作将变得更加“有趣”。

Docker 不是金锤。试一试,自己评估利弊,然后决定利弊对你和你的团队来说是否值得。