如何从Docker容器中运行Shell脚本到主机?

206

如何从Docker容器中控制主机?

例如,如何执行复制到主机的bash脚本?


13
那不会正好相反于将主机与Docker隔离吗? - Marcus Müller
107
可以的。但有时是必要的。 - Alex Ushakov
2
可能是 在 docker 容器内执行主机命令 的重复问题。 - Marcus Müller
不确定“控制主机”的含义,但我最近参加了一场由数据科学家主持的讲座,他们正在使用Docker运行脚本来处理大量工作负载(使用AWS挂载的GPU),并将结果输出到主机。这是一个非常有趣的用例。基本上,这些脚本通过Docker打包在可靠的执行环境中。 - KCD
也许我试图以错误的方式完成它,但以下是我想要实现的目标: 1.有一个“Docker软件包”,位于某个仓库中,其中包含一个带有docker-compose.yml和几个其他文件的文件夹 2.我git-clone这个仓库,cd进入它的目录并启动docker-compose up 3.结果我获得: -一个具有nginx/php-fpm/mysql等的Web服务器 -工作目录与我的主机系统上的项目代码 -…还将挂载到Web服务器上的某个文件夹。我相信获取项目代码意味着必须在Dockerfile内从主机运行几个命令? - pilat
显示剩余2条评论
15个回答

1
我有一个简单的方法。
步骤1:挂载 /var/run/docker.sock:/var/run/docker.sock (这样您就可以在容器内执行docker命令)
步骤2:在容器内执行下面的命令。关键部分是(--network host,因为它将从主机上下文中执行)
docker run -i --rm --network host -v /opt/test.sh:/test.sh alpine:3.7 sh /test.sh
test.sh 应该包含一些命令(如 ifconfig、netstat 等),以及您需要的任何其他内容。 现在,您将能够获取主机上下文输出。

4
根据 Docker 官方文档中有关使用主机网络的内容,“但是,在存储、进程名称空间和用户名称空间等所有其他方面,进程与主机隔离开来。”请查看-https://docs.docker.com/network/network-tutorial-host/。 - Peter Mutisya

0
在我的情况下,我只需通过容器登录主机(通过主机 IP),然后就可以对主机机器进行任何想做的事情。

0

根据情况,这可能是一个有用的资源。

这使用了作业队列(Celery),可以在主机上运行,命令/数据可以通过Redis(或rabbitmq)传递给它。在下面的示例中,这发生在django应用程序中(通常是docker化的)。

https://www.codingforentrepreneurs.com/blog/celery-redis-django/


0

您可以使用管道概念,但是使用主机上的文件和fswatch来实现从Docker容器中执行主机机器上的脚本的目标。像这样(自行承担风险):

#! /bin/bash

touch .command_pipe
chmod +x .command_pipe

# Use fswatch to execute a command on the host machine and log result
fswatch -o --event Updated .command_pipe | \
            xargs -n1 -I "{}"  .command_pipe >> .command_pipe_log  &

 docker run -it --rm  \
   --name alpine  \
   -w /home/test \
   -v $PWD/.command_pipe:/dev/command_pipe \
   alpine:3.7 sh

rm -rf .command_pipe
kill %1

在这个例子中,内部容器发送命令到 /dev/command_pipe,例如:
/home/test # echo 'docker network create test2.network.com' > /dev/command_pipe

在主机上,您可以检查网络是否已创建:
$ docker network ls | grep test2
8e029ec83afe        test2.network.com                            bridge              local

-3

user2915097回答进行更详细的解释:

隔离的概念是能够清晰地限制应用程序/进程/容器(无论你从哪个角度看)对主机系统的操作。因此,能够复制和执行文件会破坏整个概念。

是的。但有时是必要的。

不。这并非如此,或者说Docker不是正确的选择。你应该为想要做的事情(例如更新主机配置)声明一个清晰的接口,并编写一个最小化的客户端/服务器来实现仅仅这个功能,而不是更多。然而,一般情况下,这似乎并不是很理想。在许多情况下,您应该重新考虑您的方法并消除那种需求。当基本上所有东西都是可通过某些协议访问的服务时,Docker应运而生。我想不出任何Docker容器获得在主机上执行任意内容的适当用例。


我有一个使用情形:我已经将服务“A”(源代码在Github上)Docker化了。在“A”仓库中,我创建了适当的钩子,可以在“git pull”命令之后创建新的Docker镜像,并运行它们(并且当然删除旧的容器)。接下来:Github有Web-hooks,允许在主分支上推送后创建POST请求到任意终端点链接。因此,我想创建一个Docker化的服务B,它将是该终端点,它只会在主机上的A repo中运行“git pull”命令(重要提示:该命令必须在主机环境中执行,“而不是在B环境中,因为B无法在B内部运行新的容器A…”)。 - Kamil Kiełczewski
2
问题:我想在主机上除了Linux、Git和Docker之外什么都没有。我想要将服务A和服务B(实际上是git-push处理程序,当有人在主分支上进行git push后,它会在repo A上执行git pull)docker化。因此,Git自动部署是一个有问题的用例。 - Kamil Kiełczewski
1
@KamilKiełczewski 我也在尝试做同样的事情,你找到解决方案了吗? - user871784
1
说“不,那不是这样的”是狭隘的,并假定你知道世界上每个用例。我们的用例是运行测试。它们需要在容器中运行以正确测试环境,但考虑到测试的性质,它们还需要在主机上执行脚本。 - Senica Gonzalez
7
对于那些想知道我为什么保留了一个-7的答案:a)犯错是可以接受的。我错了。这里记录下来也没关系。b)评论实际上有价值;删除该答案也会删除它们。c)它仍然提供了一种可能明智考虑的观点(如果不必要,不要打破孤立状态。但有时候你必须这样做)。 - Marcus Müller
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接