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>