29

我想通过 docker-in-docker 设置与来自父 docker 容器的子 docker 容器联网。

假设我正在尝试连接到一个简单的 Apache httpd 服务器。当我在主机上运行 httpd 容器时,一切正常:

asnyder:~$ docker run -d -p 8080:80 httpd:alpine
asnyder:~$ curl localhost:8080
<html><body><h1>It works!</h1></body></html>

但是,当我从 docker-in-docker 设置中执行相同操作时,出现Connection refused错误:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl localhost:8080
curl: (7) Failed to connect to localhost port 8080: Connection refused

我已经尝试了几次更改,但没有运气。指定0.0.0.0接口:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 0.0.0.0:8080:80 httpd:alpine
/ # curl 0.0.0.0:8080
curl: (7) Failed to connect to 0.0.0.0 port 8080: Connection refused

使用主机网络:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d --network host httpd:alpine
/ # curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused

令人惊讶的是,我找不到任何关于此的现有文章。这里有没有人有一些见识?

谢谢!

4

3 回答 3

16

DinD 和绑定安装 Docker 套接字各有利弊,当然两者都有用例。例如,查看这组博客文章,它很好地解释了一个用例。

鉴于上面的示例 docker-in-docker 设置,您可以通过以下两种方式之一访问 Apache httpd 服务器:

1) 从docker:dind容器内部,它将在localhost:8080.

2)从docker:latest容器内部,您最初尝试访问它的地方,它将在为docker:dind容器设置的任何主机名上可用。在这种情况下,您使用了 Apache --name mydind,因此curl mydind:8080会给您标准的 Apache <html><body><h1>It works!</h1></body></html>

希望这是有道理的!

于 2017-07-09T13:03:30.817 回答
11

基于Yuriy 的回答

2) 从docker:latest container, [...] 内部,它将在为docker:dind容器设置的任何主机名上可用。在这种情况下,您使用了--name mydind,因此curl mydind:8080[...]

在 Gitlab CI 配置中,您可以通过其映像的名称来寻址 DinD 容器(除了其容器的名称,它是自动生成的):

访问服务


假设您需要一个 Wordpress 实例来测试与您的应用程序的某些 API 集成。

然后,您可以使用例如tutum/wordpress图像在您的.gitlab-ci.yml

services:
- tutum/wordpress:latest

如果您未指定服务别名,则在运行作业时tutum/wordpress将启动,并且您将可以从构建容器中以两个主机名访问它以供选择:

  • tutum-wordpress
  • tutum__wordpress

使用

service:
- docker:dind

将允许您访问该容器docker:8080

  script:
  - docker run -d -p 8080:80 httpd:alpine
  - curl docker:8080

编辑:如果您希望使用更明确的主机名,则可以按照文档所述使用alias

services:
- name: docker:dind
  alias: dind-service

接着

  script:
  - docker run -d -p 8080:80 httpd:alpine
  - curl dind-service:8080

Hth, dtk

于 2019-01-18T10:39:06.610 回答
1

我非常确信@Yuriy Znatokov 的答案是我想要的,但我已经理解了很长时间。为了方便后人理解,我把完整的步骤导出了。

1) 从 docker:dind 容器内部

docker run -d --name mydind --privileged docker:dind
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl localhost:8080
<html><body><h1>It works!</h1></body></html>

2) 从 docker:latest 容器内部

docker run -d --name mydind --privileged docker:dind
docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl mydind:8080
<html><body><h1>It works!</h1></body></html>
于 2019-08-26T12:39:11.700 回答