Docker:容器A可以调用位于其他容器B上的可执行文件吗?

nor*_*bjd 14 pdflatex pandoc docker docker-compose

我有两个Docker镜像,一个包含pandoc(用于将不同格式的文档转换为多种格式的实用程序),另一个包含pdflatex(从texlive,将tex文件转换为pdf).我的目标是将文档转换mdpdf.

我可以分别运行每个图像:

# call pandoc inside my-pandoc-image (md -> tex)
docker run --rm \
    -v $(pwd):/pandoc \
    my-pandoc-image \
    pandoc -s test.md -o test.tex

# call pdflatex inside my-texlive-image (tex -> pdf)
docker run --rm \
    -v $(pwd):/texlive \
    my-texlive-image \
    pdflatex test.tex # generates test.pdf
Run Code Online (Sandbox Code Playgroud)

但是,事实上,我想要的是直接调用pandoc(从它的容器)转换mdpdf,如下所示:

docker run --rm \
    -v $(pwd):/pandoc \
    my-pandoc-image \
    pandoc -s test.md --latex-engine pdflatex -o test.pdf
Run Code Online (Sandbox Code Playgroud)

此命令在此处不起作用,因为pandoc容器内部尝试调用pdflatex(必须在$PATH)以生成pdf,但pdflatex由于未安装在pdf中,因此不存在my-pandoc-image.

在我的情况下,pdflatex安装在图像中my-texlive-image.

因此,从这个例子中,我的问题是:容器A可以调用位于另一个容器B上的可执行文件吗?

我很确定这是可能的,因为如果我pandoc 在我的主机上安装(没有pdflatex),我可以pandoc -s test.md--latex-engine=pdflatex -o test.pdf通过简单地使pdflatex命令别名来运行:

pdflatex() {
    docker run --rm \
        -v $(pwd):/texlive \
        my-texlive-image \
        pdflatex "$@"
}
Run Code Online (Sandbox Code Playgroud)

因此,当pdflatex被调用时pandoc,容器启动并进行转换.

但是当使用2个容器时,我怎么能将pdflatex命令别名来模拟它只在容器上存在pandoc

我看了一下docker-compose,因为我已经用它来制作2个容器进行通信(应用程序与数据库进行通信).我甚至考虑ssh过从容器A到容器B来调用pdflatex命令,但这绝对不是正确的解决方案.

最后,我还构建了一个包含pandoc+ 的图像pdflatex(因为两个可执行文件位于同一图像上,所以它有效),但我真的想分别保留2个图像,因为它们可以被其他图像独立使用.

编辑:

这里暴露一个类似的问题,据我所知,提供的答案需要在容器A上安装Docker,并且需要/var/run/docker.sock在主机和容器A之间使用docker socket binding().我不认为这是最佳实践,它看起来像是一个破解可能会产生安全问题.

Hor*_*gix 9

您的问题有多种解决方案,我让您选择最适合您的一种。下面列出了从最干净到最丑陋的内容(我认为是关于一般遵循的最佳做法)。

1.提供服务

如果您最终经常调用它,则值得将pandoc公开为(HTTP)API。一些图像已经做到了这一点,例如metal3d / pandoc-server(我已经成功使用了它,但是我确定您可以找到其他图像)。

在这种情况下,你只要运行一个容器pandoc+ pdflatex 一次便大功告成!

2.使用图像继承!

让2个图像:一个pandoc只,另外一个用pandoc+ pdflatex继承了第一个与FROM该指令Dockerfile

它将解决您对大小的担忧,并且仍然能够运行pandoc而无需获取pdflatex。然后,如果您需要使用拖动图像pdflatex,它将只是一个额外的图层,而不是整个图像。

如果您发现自己经常使用该图像,而很少使用没有该图像的情况,则也可以用另一种方法进行处理,即使用基本图像,pdflatex然后添加其他图像。你也可以将3张图片,,,和,覆盖每一个需要你可能有,但随后你将至少有一个是不以任何方式链接到2人(不能heritate一个“孩子”形象图片),使其难以维护。pandocpdflatexpandocpdflatexpandocpdflatexpdflatex + pandoc

3. my-pandoc-image+ Docker套接字安装中的Docker客户端

这是您在文章结尾处提到的解决方案,并且可能是调用其他容器化命令的最通用,直接的解决方案,而不是考虑pandoc+ 的确切用例pdflatex

只需将docker客户端添加到您的映像中,my-pandoc-image然后使用即可在运行时将Docker套接字作为卷传递docker run -v /var/run/docker.sock:/var/run/docker.sock。如果您担心不能够做出pandoc的呼叫docker run ...,而不是pdflatex直接,只需添加一个贫穷的包装称为pdflatex/usr/local/bin/其负责做的docker run

4.使用volumes-from获取二进制文件

这可能是我在这里要讲的不太干净的内容。你可以尝试让无论是pandoc二进制pdflatex容器或pdflatex二进制文件中pandoc使用的容器--volumes-from把一切都打包在自己的码头工人的形象。但总而言之,它更像是胶带而不是真正的解决方案。

结论

您可以选择最适合您需求的解决方案,但我建议您使用前两种,强烈建议不要使用后一种。