如何从一个 docker 容器执行命令到另一个容器
How to execute command from one docker container to another
我正在创建一个应用程序,允许用户上传视频文件,然后这些文件将经过一些处理。
我有两个容器。
Nginx
为用户上传视频文件的网站提供服务的容器。
- 安装了
FFmpeg
和一些其他处理工具的视频处理容器。
我想达到的目标。我需要容器 1 才能 运行 容器 2 上的 bash 脚本。
据我所知,一种可能性是让它们通过 API 通过 HTTP 进行通信。但是然后我需要在容器 2 中安装一个 Web 服务器并编写一个 API ,这似乎有点过分了。
我只想执行一个 bash 脚本。
有什么建议吗?
我相信
docker exec -it <container_name> <command>
应该可以工作,即使在容器内也是如此。
您也可以尝试在您尝试从以下命令执行命令的容器中挂载到 docker.sock
:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
运行 来自容器的 docker
命令并不简单,也不是一个好主意(在我看来),因为:
- 您需要在容器上安装 docker(并在 docker 中执行 docker)
- 您需要共享 unix 套接字,如果您不知道自己在做什么,这不是一件好事。
所以,这给我们留下了两个解决方案:
- 在你的容器上安装 ssh 并通过 ssh 执行命令
- 共享一个卷并有一个进程来监视触发你的批处理的东西
您有几个选择,但您想到的前两个是:
- 在容器 1 中,安装 Docker CLI 并绑定挂载
/var/run/docker.sock
(您需要从
启动容器时托管)。然后,在容器内,你
应该能够对绑定安装使用 docker
命令
套接字就好像你从主机上执行它们一样(你也可以
需要chmod
容器内的socket允许非root
用户执行此操作。
- 您可以在容器 2 上安装
SSHD
,然后从容器 1 中安装 ssh
和 运行 您的脚本。这里的优点是您不需要在容器内部进行任何更改来说明它们 运行ning in Docker 而不是裸机这一事实。缺点是您需要将 SSHD 设置添加到 Docker 文件或启动脚本中。
我能想到的大多数其他想法只是选项 (2) 的变体,SSHD 被其他工具取代。
还要注意 Docker 网络有点奇怪(至少在 Mac 主机上),所以你需要确保容器使用相同的 docker-网络并能够通过它进行通信。
警告:
完全清楚,不要在实验室或非常受控的开发环境之外使用选项 1。它正在使用一个安全套接字,该套接字对 主机 上的 Docker 运行 时间具有完全权限,并授予从 对其进行未经检查的访问权限集装箱。这样做可以轻而易举地突破 Docker 沙箱并危害主机系统。我认为唯一可以接受的地方是作为全栈集成测试设置的一部分,它只会由开发人员 运行 临时设置。在某些非常特殊的情况下,这是一个有用的捷径,但缺点怎么强调都不为过。
之前在这里提到过,但一个合理的、半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
的一些技巧(首先使用 sudo apt install sshpass
安装):
sshpass -p 'foobob' ssh foobob@<container-id>
我专门为此写了一个 python 包 use-case。
Flask-Shell2HTTP 是一个 Flask-extension,只需 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 micro-services,它可以使用动态参数异步执行 pre-defined shell commands/scripts 并获取结果。
支持文件上传、回调fn、响应式编程等。我建议您查看 Examples.
我正在创建一个应用程序,允许用户上传视频文件,然后这些文件将经过一些处理。
我有两个容器。
Nginx
为用户上传视频文件的网站提供服务的容器。- 安装了
FFmpeg
和一些其他处理工具的视频处理容器。
我想达到的目标。我需要容器 1 才能 运行 容器 2 上的 bash 脚本。
据我所知,一种可能性是让它们通过 API 通过 HTTP 进行通信。但是然后我需要在容器 2 中安装一个 Web 服务器并编写一个 API ,这似乎有点过分了。 我只想执行一个 bash 脚本。
有什么建议吗?
我相信
docker exec -it <container_name> <command>
应该可以工作,即使在容器内也是如此。
您也可以尝试在您尝试从以下命令执行命令的容器中挂载到 docker.sock
:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
运行 来自容器的 docker
命令并不简单,也不是一个好主意(在我看来),因为:
- 您需要在容器上安装 docker(并在 docker 中执行 docker)
- 您需要共享 unix 套接字,如果您不知道自己在做什么,这不是一件好事。
所以,这给我们留下了两个解决方案:
- 在你的容器上安装 ssh 并通过 ssh 执行命令
- 共享一个卷并有一个进程来监视触发你的批处理的东西
您有几个选择,但您想到的前两个是:
- 在容器 1 中,安装 Docker CLI 并绑定挂载
/var/run/docker.sock
(您需要从 启动容器时托管)。然后,在容器内,你 应该能够对绑定安装使用docker
命令 套接字就好像你从主机上执行它们一样(你也可以 需要chmod
容器内的socket允许非root 用户执行此操作。 - 您可以在容器 2 上安装
SSHD
,然后从容器 1 中安装ssh
和 运行 您的脚本。这里的优点是您不需要在容器内部进行任何更改来说明它们 运行ning in Docker 而不是裸机这一事实。缺点是您需要将 SSHD 设置添加到 Docker 文件或启动脚本中。
我能想到的大多数其他想法只是选项 (2) 的变体,SSHD 被其他工具取代。
还要注意 Docker 网络有点奇怪(至少在 Mac 主机上),所以你需要确保容器使用相同的 docker-网络并能够通过它进行通信。
警告:
完全清楚,不要在实验室或非常受控的开发环境之外使用选项 1。它正在使用一个安全套接字,该套接字对 主机 上的 Docker 运行 时间具有完全权限,并授予从 对其进行未经检查的访问权限集装箱。这样做可以轻而易举地突破 Docker 沙箱并危害主机系统。我认为唯一可以接受的地方是作为全栈集成测试设置的一部分,它只会由开发人员 运行 临时设置。在某些非常特殊的情况下,这是一个有用的捷径,但缺点怎么强调都不为过。
之前在这里提到过,但一个合理的、半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
的一些技巧(首先使用 sudo apt install sshpass
安装):
sshpass -p 'foobob' ssh foobob@<container-id>
我专门为此写了一个 python 包 use-case。
Flask-Shell2HTTP 是一个 Flask-extension,只需 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 micro-services,它可以使用动态参数异步执行 pre-defined shell commands/scripts 并获取结果。
支持文件上传、回调fn、响应式编程等。我建议您查看 Examples.