【问题标题】:Docker - issue command from one linked container to anotherDocker - 从一个链接容器发出命令到另一个
【发布时间】:2016-01-08 22:51:09
【问题描述】:

我正在尝试使用 2 个 Docker 容器设置原始 CI/CD 管道——我将它们称为 jenkins 和 node-app。我的目标是让 jenkins 容器在提交到 GitHub 存储库时运行作业(已完成)。该作业应该在 node-app 容器上运行 deploy.sh 脚本。因此,当开发人员向 GitHub 提交时,jenkins 会接收提交,然后开始一项工作,包括自动化测试(将来),然后在 node-app 上进行部署.

jenkins 容器正在使用最新的图像 (Dockerfile).

node-app 容器的 Dockerfile 是:

FROM node:latest
EXPOSE 80
WORKDIR /usr/src/final-exercise
ADD . /usr/src/final-exercise

RUN apt-get update -y
RUN apt-get install -y nodejs npm
RUN cd /src/final-exercise; npm install

CMD ["node", "/usr/src/final-exercise/app.js"]

jenkins 和 node-app 使用 Docker Compose 链接,docker-compose.yml 文件包含(更新,感谢@alkis):

node-app:
  container_name: node-app
  build: .
  ports:
   - 80:80
  links:
   - jenkins
jenkins:
  container_name: jenkins
  image: jenkins
  ports:
   - 8080:8080
  volumes:
   - /home/ec2-user/final-exercise:/var/jenkins

容器使用docker-compose up -d 构建并按预期启动。 docker ps 产量(更新):

CONTAINER ID        IMAGE                    COMMAND                  CREATED                 STATUS              PORTS                               NAMES
69e52b216d48        finalexercise_node-app   "node /usr/src/final-"   3 hours ago         Up 3 hours          0.0.0.0:80->80/tcp                  node-app
5f7e779e5fbd        jenkins                  "/bin/tini -- /usr/lo"   3 hours ago         Up 3 hours          0.0.0.0:8080->8080/tcp, 50000/tcp   jenkins

我可以从 node-app ping jenkins,反之亦然。

这甚至可能吗?如果不是,我是否在这里犯了架构错误?

非常感谢您,我很感激!

编辑: 我偶然发现了nsenter,并使用this 和this 轻松进入容器的外壳。但是,它们都假设源(在他们的情况下是主机,在我的情况下是 jenkins 容器)安装了 Docker,以便找到目标容器的 PID。我可以从主机 nsenter 进入 node-app,但仍然没有来自 jenkins 的运气。

【问题讨论】:

标签: jenkins docker continuous-integration docker-compose continuous-delivery


【解决方案1】:
node-app:
  build: .
  ports:
   - 80:80
  links:
   - finalexercise_jenkins_1

jenkins:
  image: jenkins
  ports:
   - 8080:8080
  volumes:
   - /home/ec2-user/final-exercise:/var/jenkins

试试上面的。您通过图像名称链接,但您必须使用容器名称。 在您的情况下,由于您没有明确指定容器名称,因此它会像这样自动生成

finalexercise : folder where your docker-compose.yml is located
node-app      : container configs tag
1             : you only have one container with the prefix finalexercise_node-app. If you built a second one, then its name will be finalexercise_node-app_2

yml 文件的设置:

node-app:
  build: .
  container_name: my-node-app
  ports:
   - 80:80
  links:
   - my-jenkins

jenkins:
  image: jenkins
  container_name: my-jenkins
  ports:
   - 8080:8080
  volumes:
   - /home/ec2-user/final-exercise:/var/jenkins

当然,您也可以为 node-app 指定容器名称,这样您就可以使用常量进行通信。

更新

为了测试,登录到 jenkins 容器的 bash 终端

docker exec -it my-jenkins bash

然后尝试 ping my-node-app,甚至 telnet 以获取特定端口。

ping my-node-app:80

或者你可以

telnet my-node-app 80

更新

execcommand 可以轻松完成您想做的事情。 您可以从您的主机执行此操作(试一试以确保它正常工作)

docker exec -i <container_name> ./deploy.sh

如果上述方法有效,那么您的问题就在于从容器中执行相同的命令。因为你不能这样做,因为发出命令的容器(jenkins)无权访问你主机的 docker 安装(它不仅识别命令,而且控制你需要访问的容器)。

我没用过,但我知道两种解决方案

  1. 使用此官方guide 访问您主机的 docker 守护程序并从您的容器发出 docker 命令,就像您在主机上一样。
  2. 将 docker 二进制文件和套接字挂载到容器中,这样容器就好像它是主机一样(每个命令都将由主机的 docker 守护程序执行,因为它是共享的)。

来自 SO 的 thread 提供了有关此问题的更多见解。

【讨论】:

  • 这对组织我的容器非常有帮助——谢谢。但是,我仍在努力弄清楚如何为我的节点应用程序容器从我的詹金斯容器启动命令。例如,jenkins 告诉 node-app 它需要运行deploy.sh。
  • 同样适用。为您的 node-app 容器命名,并在 jenkins 中将其用作主机名,以与 node-app 进行通信。我已经更新了我的答案,使其更加清晰
  • 欣赏这一点。但是,我一直能够 ping node-app 容器。我想不通的是如何从 jenkins 调用 deploy.sh 脚本。
  • 我已经更新了我的答案。如果它解决了您的问题,请不要忘记接受答案。
  • 除了alkis的回答外,我还使用了very helpful link。我的最终解决方案涉及作者所说的 Docker-outside-of-Docker (DooD),其中 jenkins 容器实际上运行 docker exec -i node-app bash,然后将部署命令传递给 node-app 容器。请注意,alkis 答案中docker exec -it node-app bash 中的 -t 标志将不起作用,因为您会收到一个 tty 错误。
猜你喜欢
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2017-10-15
相关资源
最近更新 更多