如何从一个Docker容器执行命令到另一个

时间:2019-11-25 15:51:58

标签: docker docker-container docker-networking docker-command

我正在创建一个应用程序,该应用程序将允许用户上传视频文件,然后再进行一些处理。

我有两个容器。

  1. Nginx容器,用于为网站提供服务,用户可以在其中上传视频文件。
  2. 已安装FFmpeg和其他一些处理内容的视频处理容器。

我想要实现的目标。我需要容器1才能在容器2上运行bash脚本。

据我所知,一种可能性是使它们通过API通过HTTP进行通信。但是随后,我需要在容器2中安装Web服务器并编写API,这似乎有些过分了。 我只想执行一个bash脚本。

有什么建议吗?

5 个答案:

答案 0 :(得分:1)

从容器中运行docker命令并不简单,也不是一个好主意(在我看来),因为:

  1. 您需要在容器上安装docker(并在docker容器中安装docker)
  2. 您需要共享unix套接字,如果您不知道自己在做什么,那不是一件好事。

所以,这给了我们两个解决方案:

  1. 在您的容器上安装ssh并通过ssh执行命令
  2. 共享一个卷,并有一个过程来监视某些东西来触发您的批次

答案 1 :(得分:1)

您有一些选择,但是想到的前两个是:

  1. 在容器1中,安装Docker CLI并绑定安装 /var/run/docker.sock(您需要从 启动容器时托管)。然后,在容器内,您 应该能够对已安装的绑定使用docker命令 套接字,就好像您是从主机执行它们一样(也可能是 需要chmod容器内的套接字以允许非root用户 用户执行此操作。
  2. 您可以在容器2上安装SSHD,然后从容器1中安装ssh并运行脚本。这样做的好处是,您无需在容器内进行任何更改即可解决它们在Docker中运行而不是裸机运行这一事实。缺点是您需要将SSHD设置添加到Dockerfile或启动脚本中。

我能想到的大多数其他想法只是选项(2)的变体,SSHD被某些其他工具取代了。

还请注意,Docker网络有点奇怪(至少在Mac主机上如此),因此您需要确保容器使用相同的docker-network并能够通过它进行通信。

答案 2 :(得分:1)

我专门为此用例编写了一个python包。

Flask-Shell2HTTP是Flask扩展,仅需5行代码即可将命令行工具转换为RESTful API。

示例代码

from flask import Flask
from flask_executor import Executor
from flask_shell2http import Shell2HTTP

app = Flask(__name__)
executor = Executor(app)
shell2http = Shell2HTTP(app=app, executor=executor, base_url_prefix="/commands/")

shell2http.register_command(endpoint="saythis", command_name="echo")
shell2http.register_command(endpoint="run", command_name="./myscript")

可以很容易地被称为

$ curl -X POST -H 'Content-Type: application/json' -d '{"args": ["Hello", "World!"]}' http://localhost:4000/commands/saythis

您可以使用它来创建RESTful微服务,这些服务可以异步执行带有动态参数的预定义Shell命令/脚本并获取结果。

它支持文件上传,回调fn,反应式编程等。我建议您结帐Examples

答案 3 :(得分:0)

我相信

docker exec -it <container_name> <command>

即使在容器内部也应该起作用。

您还可以尝试在尝试从以下位置执行命令的容器中挂载到docker.sock上:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

答案 4 :(得分:0)

之前已经提到过,但是合理的,半hacky的选择是在两个容器中都安装SSH,然后使用ssh在另一个容器上执行命令:

# install SSH, if you don't have it already
sudo apt install openssh-server

# start the ssh service
sudo service start ssh

# start the daemon
sudo /usr/sbin/sshd -D &

假设您不想一直是root用户,则可以添加默认用户(在本例中为'foobob'):

useradd -m --no-log-init --system  --uid 1000 foobob -s /bin/bash -g sudo -G root

#change password
echo 'foobob:foobob' | chpasswd

在源容器和目标容器上都执行此操作。现在,您可以执行从container_1到container_2的命令。

# obtain container-id of target container using 'docker ps'
ssh foobob@<container-id> << "EOL"
echo 'hello bob from container 1' > message.txt
EOL

您可以使用ssh-agent来自动设置密码,也可以对sshpass使用一些更hacky(首先使用sudo apt install sshpass安装):

sshpass -p 'foobob' ssh foobob@<container-id>