2015-07-09 1 views
73

У меня есть докер-контейнер, работающий с jenkins. В рамках процесса сборки мне нужно получить доступ к веб-серверу, который выполняется локально на главной машине. Есть ли способ, которым веб-сервер хоста (который может быть настроен для работы на порту) может быть открыт контейнеру jenkins?Как получить доступ к порту хоста из контейнера-докера

EDIT: Я запускаю докер на машине Linux.

UPDATE:

В дополнение к @larsks ответить ниже, чтобы получить IP-адрес хоста IP с хост-машины, я следующее:

ip addr show docker0 | grep -Po 'inet \K[\d.]+' 
+0

Использование комментария, так как это ужасный ответ, но я считаю, что вы можете получить доступ к нему на 172.17.1.78 - если это не настройка boot2docker. – CashIsClay

+0

@CashIsClay Я пробовал это, и эта ошибка все еще терпит: (7) Не удалось подключиться к порту 172.17.1.78 7000: нет маршрута к хосту –

+0

Вы не указали; вы запускаете boot2docker, или вы запускаете Docker изначально на Linux? – larsks

ответ

84

При запуске Docker изначально на Linux , вы можете получить доступ к услугам хоста, используя IP-адрес интерфейса docker0. Изнутри контейнера это будет ваш маршрут по умолчанию.

Например, в моей системе:

$ ip addr show docker0 
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 
     valid_lft forever preferred_lft forever 
    inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link 
     valid_lft forever preferred_lft forever 

И внутри контейнера:

# ip route show 
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0 src 172.17.0.4 

Это довольно легко извлечь этот IP-адрес, используя простую оболочку сценария:

#!/bin/sh 

hostip=$(ip route show | awk '/default/ {print $3}') 
echo $hostip 

Возможно, вам потребуется изменить правила iptables на вашем хосте t o Разрешить соединения из контейнеров Docker. Нечто подобное будет делать трюк :

# iptables -A INPUT -i docker0 -j ACCEPT 

Это позволило бы доступ к любым портам на хосте от Docker контейнеров. Обратите внимание, что:

  • IPTables правила упорядоченные, и это правило, может или не может сделать правильно в зависимости от того, что другие правила вступают перед ним.

  • вы сможете только получить доступ к услугам хозяев, которые либо (а) прослушивания на INADDR_ANY (ака 0.0.0.0) или, что явно прослушивания на интерфейсе docker0.

+0

Спасибо. Получение IP-адреса было всем, что было необходимо для меня, без изменения iptables :) –

+0

У меня такая же проблема с возвратом Нет пути к хосту, @TriNguyen, что вы сделали после того, как получили ip-адрес хоста, чтобы он работал? Спасибо –

+0

@ mino.me Что IP-адрес хоста выглядит для вас? не совсем уверен, почему это не сработало –

0

Если у вас есть два изображения докеров, которые уже созданы, и вы хотите связать два контейнера друг с другом.

Для этого вы можете удобно запускать каждый контейнер со своим собственным именем и использовать флаг -link для обеспечения связи между ними. Однако вы не получите этого во время сборки докеров.

Когда вы находитесь в сценарии, как я, и это не ваш

docker build -t "centos7/someApp" someApp/ 

Это ломает, когда вы пытаетесь

curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz 

и вы застряли на «скручивание/Wget» возвращение нет " маршрут к хозяину ".

Причиной является безопасность, установленная на месте докерером, которая по умолчанию запрещает связь с контейнером в сторону хоста или других контейнеров, работающих на вашем хосте. Это было совершенно неожиданно для меня, я должен сказать, вы ожидаете, что эхосистемы докеровских машин, работающих на локальной машине, просто безупречно могут получить доступ друг к другу без особого препятствия.

Объяснение для этого подробно описано в следующей документации.

http://www.dedoimedo.com/computers/docker-networking.html

Два быстрых обходные дано, что поможет вам двигаться за счет снижения вниз безопасности сети.

Простейшая альтернатива - просто отключить брандмауэр или разрешить все. Это означает, что нужно выполнить команду, которая может быть остановлена ​​системой stoppack, iptables -F или эквивалентной.

Надеюсь, эта информация поможет вам.

+0

Как примечание, '--link' теперь устарел –

76

Раствор для MacOS

Docker для Mac против 17.06 и выше (июнь 2017)

Connect в специальный Mac-только DNS-имя docker.for.mac.localhost, который позволит решить на внутренний IP-адрес, используемый гостья. (Спасибо пользователю @Kyr)

Docker для Mac 17.05 и ниже

Чтобы получить доступ к хосту из Докер контейнера необходимо прикрепить IP псевдоним к сетевому интерфейсу. Вы можете связать любой IP-адрес, который вы хотите, просто убедитесь, что вы не используете его ни для чего другого.

sudo ifconfig lo0 alias 123.123.123.123/24

Затем убедитесь, что вы сервер прослушивания IP упоминалось выше или 0.0.0.0. Если он прослушивает localhost 127.0.0.1, он не будет принимать соединение.

Затем просто укажите контейнер вашего докера на этот IP-адрес, и вы можете получить доступ к главной машине!

Для проверки вы можете запустить что-то вроде curl -X GET 123.123.123.123:3000 внутри контейнера.

Псевдоним сбрасывается при каждой перезагрузке, поэтому при необходимости создайте сценарий запуска.

Solution и больше документации здесь: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

+0

Я успешно протестировал это. Нет необходимости отключать брандмауэр. –

+12

Начиная с 17.06, выпущенный в июне 2017 года, их рекомендация - подключиться к специальному DNS-имени под Mac 'docker.for.mac.localhost', который будет разрешать внутренний IP-адрес, используемый принимающей! ... Я тестировал его, и он действительно работает! :) – Kyr

+0

Пятно на ответ для пользователей Mac, таких как я. Благодарю. Одна вещь, которую я не понимаю, - это почему 'ip route show ' awk '/ default/{print $ 3}' дающий один IP и 'docker.for.mac.localhost' является другим. – dmmd

2

Использование --net="host" в вашей команде docker run, то localhost в вашем Docker контейнере будет указывать на ваш Docker хозяина.