Docker:容器A可以调用另一个容器B上的可执行文件吗? [英] Docker : Can a container A call an executable located on an other container B?

查看:131
本文介绍了Docker:容器A可以调用另一个容器B上的可执行文件吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个Docker映像,其中一个包含 pandoc (一个将不同格式的文档转换成多种格式的实用程序),另一个包含 pdflatex 的实用程序(来自 texlive ,将 tex 个文件转换为 pdf )。我的目标是将文档从 md 转换为 pdf

I have two Docker images, one containing pandoc (an utility to convert documents in different formats to many formats), and an other containing pdflatex (from texlive, to convert tex files into pdf). My goal here is to convert documents from md to pdf.

I可以分别运行每个映像:

I can run each image separately :

# 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

但是,事实上,我想要的是直接从容器中调用 pandoc md 转换为 pdf ,像这样:

But, in fact, what I want is to call pandoc (from its container) directly to convert md into pdf, like this :

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

此命令在这里不起作用,因为容器内的 pandoc 试图调用 pdflatex (必须位于 $ PATH 中)来生成pdf,但是 pdflatex 不存在,因为未安装它在 my-pandoc-image 中。

This command does not work here, because pandoc inside the container tries to call pdflatex (that must be in $PATH) to generate the pdf, but pdflatex does not exist since it is not installed in the my-pandoc-image.

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

In my case, pdflatex is installed in the image my-texlive-image.

因此,从此示例来看,我的问题是:容器可以调用吗?我可以肯定这是可能的,因为它位于另一个容器B上吗?

So, from this example, my question is : Can a container A call an executable located on an other container B ?

因为如果我在计算机上安装 pandoc 我的主机(没有 pdflatex ),我可以运行 pandoc -s test.md--latex-engine = pdflatex -o测试。 pdf ,只需将 pdflatex 命令别名为:

I am pretty sure this is possible, because if I install pandoc on my host (without pdflatex), I can run pandoc -s test.md--latex-engine=pdflatex -o test.pdf by simply aliasing the pdflatex command with :

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

因此,当 pdflatex 被调用时 pandoc ,将启动一个容器并进行转换。

Thus, when pdflatex is called by pandoc, a container starts and do the conversion.

但是当使用2个容器时,我该如何别名 pdflatex 命令在只有 pandoc 吗?

But when using the 2 containers, how could I alias the pdflatex command to simulate its existence on the container having only pandoc ?

的容器上模拟它的存在在 docker-compose ,因为我已经使用它使2个容器进行通信(应用程序与数据库进行通信)。我什至想到了从容器A到容器B的 ssh -调用 pdflatex 命令,但这绝对是< a href = https://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/ rel = noreferrer>不是正确的解决方案。

I took a look at docker-compose, since I have already used it to make 2 containers communicate (app communicating with a database). I even thought about ssh-ing from container A to container B to call the pdflatex command, but this is definitively not the right solution.

最后,我还构建了一个包含 pandoc + pdflatex 的图像(之所以起作用,是因为这两个可执行文件在同一张图片上),但我真的想将这2张图片分开保存,因为它们可以被其他图片单独使用。

Finally, I also have built an image containing pandoc + pdflatex (it worked because the two executables were on the same image), but I really want to keep the 2 images separately, since they could be used independently by other images.

在我理解所提供的答案需求的同时,此处暴露了类似的问题Docker将安装在容器A上,并且需要在主机和容器A之间使用docker套接字绑定( /var/run/docker.sock )。我不认为这是最佳实践,它似乎可以创建安全问题

A similar question is exposed here, as I understand the provided answer needs Docker to be installed on container A, and needs a docker socket binding (/var/run/docker.sock) between host and container A. I don't think this is best practice, it seems like a hack that can create security issues.

推荐答案

针对您的问题,有多种解决方案,让您选择最适合您的解决方案。下面以从最干净到最丑的顺序介绍了它们(我认为是关于一般遵循的最佳实践)。

There are multiple solutions to your problem, I'll let you choose the one that suits you best. They are presented below, from the cleanest to the ugliest (in my opinion and regarding the best practices generally followed).

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

If you end up calling it often, it may be worth exposing pandoc as an (HTTP) API. Some images already do that, for example metal3d/pandoc-server (which I already used with success, but I'm sure you can find others).

在这种情况下,您只需要使用 pandoc + pdflatex 一次,您就被设置了!

In this case, you just run a container with pandoc + pdflatex once and you're set!

制作2张图片:一个仅包含 pandoc ,另一个带有 pandoc + pdflatex 使用 FROM 指令继承第一个在 Dockerfile 中。

Make 2 images : one with pandoc only, and the other one with pandoc + pdflatex, inheriting the first one with the FROM directive in the Dockerfile.

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

It will solve your concerns about size and still being able to run pandoc without having to fetch pdflatex too. Then if you need to pull the image with pdflatex, it will just be an extra layer, not the entire image.

您也可以用另一种方法来实现,即使用基本图像 pdflatex 和另一个添加 pandoc ,如果您发现自己经常单独使用 pdflatex 图像,而很少使用没有<$的 pandoc 图像c $ c> pdflatex 。您还可以制作3张图像,分别是 pandoc pdflatex pdflatex + pandoc ,可以满足您可能需要的所有需求,但是您将至少拥有一个没有以任何方式链接到其他2个图像的图像(不能继承子图像),从而使其成为

You can also do it the other way, with a base image pdflatex and another adding pandoc to it if you find yourself using the pdflatex image alone often and rarely using the pandoc image without pdflatex. You could also make 3 images, pandoc, pdflatex, and pdflatex + pandoc, to cover every need you might have, but then you'll have at least one image that isn't linked in any way to the 2 others (can't heritate a "child" image), making it a bit harder to maintain.

这是您最后提到的解决方案,这可能是调用其他容器化命令的最最直接的解决方案,而不是使用 pandoc + <$的确切用例c $ c> pdflatex 到帐户中。

This is the solution that you mentionned at the end of your post, and which is probably the most generic and straightforward solution for calling other containerized commands, not taking your precise usecase of pandoc + pdflatex into account.

只需添加Docker客户端添加您的图像 my-pandoc-image 并在运行时使用 docker run -v /var/run/docker.sock:/var/run/docker.sock 将Docker套接字作为卷传递。而且,如果您担心无法进行 pandoc 调用 docker run ... 而不是 pdflatex 直接,只需在 / usr / local / bin / pdflatex 的可怜包装器c $ c>将负责执行 docker run

Just add the docker client tu your image my-pandoc-image and pass the Docker socket as volume at runtime using docker run -v /var/run/docker.sock:/var/run/docker.sock. And if you're concerned is not being able to make pandoc call docker run ... instead of pdflatex directly, just add a poor wrapper called pdflatex in /usr/local/bin/ which will be responsible of doing the docker run

这可能是我要在此介绍的不太干净。您可以尝试在 pdflatex 容器中获取 pandoc 二进制文件或 pdflatex 二进制文件放在 pandoc 容器中,使用-volumes-from 将所有内容打包在自己的Docker映像中。但总而言之,它不仅仅是真正的解决方案。

This one is probably the less clean I'll present here. You could try getting either the pandoc binary in a pdflatex container or the pdflatex binary in a pandoc container using --volumes-from to keep everything packaged in its own Docker image. But honnestly, it's more of a duct tape than a real solution.

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

You can chose the solution that best fits your needs, but I would advise the first 2 and strongly discourage the last one.

这篇关于Docker:容器A可以调用另一个容器B上的可执行文件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆