Docker Container Networking с Docker-in-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>

Но когда я делаю то же самое с установки докеров в докере, я получаю ошибку 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

Удивительно, но я не смог найти никаких существующих статей об этом. Кто-нибудь здесь имеет представление?

Спасибо!

Ответ 1

Есть плюсы и минусы как для установки DinD, так и для bind на разъем Docker, и, безусловно, есть варианты использования для обоих. В качестве примера, посмотрите этот набор постов в блоге, который хорошо объясняет один из вариантов использования.

Учитывая приведенный выше пример настройки Docker-in-Docker, вы можете получить доступ к серверу Apache httpd одним из двух способов:

1) Внутри контейнера docker:dind он будет доступен на localhost:8080.

2) Внутри контейнера docker:latest, где вы пытались получить к нему доступ изначально, он будет доступен на любом имени хоста, установленном для контейнера docker:dind. В этом случае вы использовали --name mydind, поэтому curl mydind:8080 даст вам стандартный Apache <html><body><h1>It works!</h1></body></html>.

Надеюсь, это имеет смысл!

Ответ 2

Опираясь на ответ юрия:

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, ДТК

Ответ 3

Я очень убежден, что ответ @Yuriy Znatokov - это то, что я хочу, но я его давно понял. Чтобы облегчить понимание последующим пользователям, я экспортировал все этапы.

1) Из докера: контейнер 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 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>