在GitLab Docker Runner中向另一个正在运行的Docker容器的标准输入注入命令

43次阅读
没有评论

问题描述

一个用户在GitLab Docker Runner中遇到了一个需求:他想要向同一Docker守护程序上运行的另一个Docker容器的标准输入注入一个命令。Docker守护程序套接字已经被挂载到了GitLab Runner中并且运行正常。目标容器的配置如下:

tty: true
stdin_open: true

他已经尝试了一个解决方案,使用了socat命令来注入命令,但在GitLab CI中无法正常工作,他怀疑是因为在GitLab Runner中不存在TTY。

解决方案

注意:以下操作可能会因版本差异而有所不同。确保在进行任何更改之前备份相关数据。

方案1:使用docker exec命令

在GitLab CI环境中,由于缺少TTY,直接使用docker attach可能不会按预期工作。一个替代的方法是使用docker exec命令来在目标容器中执行命令。

以下是解决方案的步骤:
1. 确保你在GitLab CI的脚本中有执行的权限,以及已经挂载了Docker守护程序的套接字。
2. 使用docker exec命令来在目标容器中执行需要的命令。例如:
bash
docker exec -it targeted_docker sh -c 'echo "my_command" > /dev/tty0'

这里我们使用了sh -c来在目标容器中执行一个命令。我们将需要注入的命令输出到/dev/tty0,这会被目标容器的标准输入接受。

方案2:使用docker-compose配置文件

如果你使用的是docker-compose来管理容器,你可以在配置文件中定义一个自定义的命令,然后在GitLab CI中使用docker-compose exec来执行这个命令。

以下是解决方案的步骤:
1. 确保你的docker-compose.yml文件中已经定义了目标容器的配置。
2. 在docker-compose.yml文件中为目标容器添加一个自定义的命令,例如:
yaml
services:
targeted_docker:
tty: true
stdin_open: true
command: ["sleep", "infinity"]

在这个示例中,我们将目标容器的命令设置为["sleep", "infinity"],这将使容器一直保持运行状态。
3. 在GitLab CI中使用docker-compose exec来执行需要的命令,例如:
bash
docker-compose exec targeted_docker sh -c 'echo "my_command" > /dev/tty0'

同样地,我们将需要注入的命令输出到/dev/tty0

方案3:使用FIFO命令管道

另一种方法是使用FIFO(命名管道)来在两个容器之间建立一个通信通道。你可以将命令写入FIFO管道,然后目标容器从管道读取并执行命令。

以下是解决方案的步骤:
1. 在GitLab CI环境中创建一个FIFO管道,例如:
bash
mkfifo my_pipe

2. 在一个后台任务中将FIFO管道的内容重定向到目标容器的标准输入,例如:
bash
cat my_pipe | docker exec -i targeted_docker sh

3. 在GitLab CI中,通过将命令写入FIFO管道来实现向目标容器注入命令,例如:
bash
echo "my_command" > my_pipe

这将会被重定向到目标容器的标准输入。

请注意,使用FIFO管道需要更多的配置和管理,但可以在没有TTY的情况下实现容器之间的通信。

总结

在GitLab Docker Runner中向另一个正在运行的Docker容器的标准输入注入命令可以通过使用docker exec命令、在docker-compose中定义自定义命令或使用FIFO管道来实现。这些方法可以在缺少TTY的情况下在容器之间建立通信通道并执行所需的命令。根据你的具体需求,选择合适的方法来实现你的目标。

在进行任何操作之前,请确保已经充分了解操作的影响,以及可能引发的问题。

正文完