假设我正在构建一个微服务,用于调整和优化图像文件的大小。这是一个长期运行的守护进程,它提供响应标准GET
/POST
响应的 HTTP API。根据我对 Docker 的了解,这是一个完美的容器化用例——一个进程(HTTP 服务器守护进程)在专用容器中无限期运行。
对我来说,如果我们更深入地研究构建此服务的可能方式,事情就会变得模糊。假设对于每个传入的请求,该服务都会生成一个 ImageMagick 进程来调整图像大小,然后生成另一个 pngquant 或类似进程来减小文件大小。由于这些程序将处理可能不可信的用户提供的图像数据,因此能够在这些新版本发布后立即将每个组件更新到最新可用版本非常重要。但是,如何根据 Docker 映像和容器来拆分这些组件?
我想出了几种不同的方法,但似乎仍然缺少一些东西:
1.一个大容器。构建 HTTP API 容器时,同时安装/编译 ImageMagick/pngquant 实用程序。就 API 守护程序而言,它就像在任何其他计算机上运行一样。要更新其中一个二进制文件,请重建整个容器(即使 API 守护程序本身没有更改)。如果需要独立针对 ImageMagick 进行测试/开发,可能会很尴尬,因为这不是此容器布局的重点。
2. 容器运行容器。HTTP API 有自己的容器,ImageMagick 有自己的容器,pngquant 有自己的容器,等等。当 API 处理需要调用其中一个实用程序的请求时,API 代码会启动一个容器来转换一个图像文件,转换完成后该容器就会被销毁。据我了解,HTTP API 代码需要一些相当高的权限才能创建新的容器;从安全角度来看,这可能不是一个合理的方法。
3.包装纸和胶水。将 ImageMagick 和 pngquant 包装在自定义的长期运行守护程序代码中,这样这些容器就永远不必退出。让 HTTP API 容器根据需要通过 Docker 网络与其他容器通信。这似乎有很多毫无意义的间接性和复杂性,却没有真正的好处。
4. 我遗漏了一些有关图像合成的内容。看起来似乎没有一种干净的方法可以将多个可独立替换的图像“分段”拼凑成一个容器。如果有一种方法可以将多个图像(每个图像包含 ImageMagick、pngquant 和 HTTP API 之一)组合成一个容器,那将会很有趣。根据我所见,替换/修改图像也会更改在其上构建的所有图像,这使得这种方法与方法 #1 并无太大区别。
我真正想要的是能够独立开发/构建/测试/部署容器软件堆栈的组件,而无需重建或重新安装未更改的部分。如果这与 Docker 设计理念相冲突,我愿意改变我对该方法的看法或寻找不同的工具。
答案1
只需使用多个“独立”容器进行设计,其中一些容器通过远程 API 依赖于其他容器。
没有必要让“容器运行容器”。您只需让一个容器接收请求并由 ImageMagick 处理,然后等待持续处理请求即可。如果您需要单独升级该容器,请执行此操作。这个持续运行的过程类似于您的“包装和粘合”点。
请注意,您可以将其构建为仅将 ImageMagick 作为批处理运行。这可能就是您所需要的。但是,在容器中构建 ImageMagick 使您能够连接运行不同版本的 ImageMagick 的 ImageMagick 容器的不同实例,以便同时进行比较和测试。
至于从其他镜像的片段组装一个镜像,是的,没有直接的方法可以做到这一点,但在 DockerHub 上有镜像由基础镜像中的两个不同框架组成的例子(比如 tomcat 和 JDK),并且集成额外的更改来安装和配置镜像中的另一个特定框架只需要从可能的公共 Dockerfile 中摘录一段来展示如何做到这一点。