Moby: Задокументируйте, как подключиться к хосту Docker из контейнера

Созданный на 5 июл. 2013  ·  263Комментарии  ·  Источник: moby/moby

У меня были некоторые проблемы с выяснением того, как подключить хост докера из контейнера. Не удалось найти документацию, но нашел журналы irc, говорящие что-то об использовании 172.16.42.1 , что работает.

Было бы неплохо, если бы это поведение и то, как оно связано с docker0 , было задокументировано.

Самый полезный комментарий

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

Все 263 Комментарий

когда вы заглянете внутрь network.go, вы обнаружите, что докер ищет внутренние сети, которые не маршрутизируются.

сначала 172.16.42.1 угадывается как адрес моста, затем другие.

Так что документирование этого не сильно поможет. Это динамическая схема, на которую нельзя положиться.

Я думаю, что вам нужен скорее способ определить адреса, используемые для моста и клиента.
может ли это быть?

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

+1 Было бы неплохо иметь хороший способ подключения к хост-системе

+1, в ветке 1.0 будет определен API самоанализа, чтобы каждый контейнер мог взаимодействовать с хостом ограниченным и контролируемым образом.

В настоящее время это запланировано для версии 0.8.


@соломонстр
@getdocker

В четверг, 8 августа 2013 г., в 13:10, EJ [email protected]
написал:

+1 Было бы неплохо иметь хороший способ подключения к хост-системе

Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment-22351792

Итак, как я могу подключиться к хосту докера из контейнера? Я пытаюсь подключиться к контейнеру докеров через хост-порт, а не через частный IP-адрес контейнера.

@gerhard : API самоанализа запланирован на 0.8. Между тем, если вы хотите получить доступ к API Docker из контейнеров, вы можете настроить Docker для прослушивания IP-адреса моста Docker.

Для этого вы должны:

  • создать мост

ip link add docker0 type bridge

  • присвоить ему IP-адрес

ip link set docker0 up
ip addr add 172.17.0.1/16 dev docker0

  • запустите докер и привяжите API к мосту

docker -d -H 172.17.0.1:4242

Теперь вы можете получить доступ к Docker API из своих контейнеров.

В настоящее время (версия 0.7) докер не поддерживает надежное предоставление неограниченного доступа к своему собственному управляющему сокету одному из своих контейнеров. Обходные пути, описанные в этой ветке, — это хаки, работа которых не гарантируется, и если они сработают, они могут сломаться в любой момент — пожалуйста, не используйте их в рабочей среде или ожидайте, что мы их поддержим. Поскольку нет официальной функции для документирования, эту проблему с документацией нельзя исправить.

Чтобы обсудить хаки и обходные пути для отсутствующих функций, я рекомендую либо список рассылки _docker-user_, либо канал _#docker_ irc на Freenode.

Удачного взлома

@shykes В таком случае есть ли еще одна проблема, которая отслеживает создание такой функции?

Кстати, для мотивации такой функции: это полезно при локальном тестировании сервера (где раньше я бы использовал vagrant), и я хочу подключить сервер в контейнере к базе данных или другому серверу, работающему на моя машина разработки (докер-хост).

Я уже убежден в ценности этой функции :)

В понедельник, 2 декабря 2013 г., в 9:09, Калеб Спейр, [email protected]
написал:

Кстати, для мотивации такой функции: это полезно при локальном тестировании сервера (где раньше я бы использовал vagrant), и я хочу подключить сервер в контейнере к базе данных или другому серверу, работающему на моя машина разработки (докер-хост).

Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment-29636528

Я на Fedora 20 с докером 0.7.2, настраиваю пользовательский интерфейс Docker . Мне пришлось открыть порт, на котором слушает демон docker, чтобы брандмауэр не блокировал его:

  • firewall-cmd --permanent --zone=trusted --add-interface=docker0
  • firewall-cmd --permanent --zone=trusted --add-port=4243/tcp

После этого _docker-ui_ смог подключиться к сокету управления демоном docker.

ХТН
Это четкая и законная потребность в такой функции.

Извините, если я оживляю крепкую нить.

Название этого выпуска гласит: "Как подключиться к хосту из контейнера докеров".
Я не понимаю, как это связано с функцией docker inspect . Функция проверки используется на стороне хоста для поиска IP-адреса контейнера, если я не ошибаюсь.

Я думаю, что проблема с bkad заключается в поиске IP-адреса хоста внутри контейнера. Конечно, я не сетевой мастер, но не совсем безопасно предположить, что ip-шлюз (изнутри контейнера) сопоставляется с хостом.
(Предполагая, что никто не настраивает настройку моста или что-то в этом роде).

Используя шлюз для 0.0.0.0 из netstat -nr , у меня определенно не было проблем с доступом к серверу, работающему на моем хост-компьютере. Я подозреваю, что IP-адрес шлюза является статическим (после запуска докера), кто-нибудь может это подтвердить?

Альтернативой может быть передача общедоступного IP-адреса моего хоста в контейнер с использованием переменных среды, но общедоступный IP-адрес может не быть статическим. И хотя имя хоста может лучше работать в продакшене, его сложно использовать локально.

Я все же предпочел бы способ вызова из контейнера докера на хост через петлю и отображать его как 127.0.0.1 на хосте. Или, если безопасность вызывает беспокойство, другое петлевое устройство, которое всегда имеет один и тот же IP-адрес.
Или, может быть, вещь, которую я нашел, не выставляет мое сообщение на всеобщее обозрение? Как говорится, я не сетевой волшебник :)
Обратите внимание: если использование ip-шлюза для вызова хоста докера является «правильным способом», разве мы не можем это задокументировать?

Для тех, кто хочет найти IP-адрес шлюза из контейнера /proc/net/route , вероятно, это подходящее место для его чтения.

Мотивация для этой функции включает в себя различные службы метаданных. Разоблачение вещей из службы метаданных ec2 было бы неплохо. Распределение учетных данных и более сложных структурированных данных, которые не вписываются в переменные среды.

@jonasfj : на самом деле есть более простой способ, теперь, когда Docker поддерживает привязку файлов с хоста к контейнеру. Вы можете привязать контрольный сокет Docker, например: docker run -v /var/run/docker.sock:/var/run/docker.sock … ; это проще, чем возиться с сетевыми правилами.

Я не уверен, как помогает сокет докера. Я все еще думаю, что вопрос должен быть открыт повторно, нет документации для следующего сценария:

1) На «хосте» служба работает на порту 8080 (например, «и т. д.»)
2) С этого хоста запускается докер-контейнер
3) Как можно получить доступ к службе на порту 8080 на хосте из контейнера докеров? Какой будет URL/IP?

@jpetazzo Как настройка docker.sock помогает решить вышеуказанную проблему?

@vrvolle , разоблачение docker.sock не решает исходную проблему, описанную @bkad.
Но можно было бы открыть другой сокет домена unix для связи между хостом и контейнером докеров.

Например, если вы хотите открыть mysql с хоста, вы должны открыть сокет mysql: /tmp/mysql.sock .

Или, если вы, как и я, имеете API метаданных, через который контейнеры должны иметь возможность запрашивать у хоста различные полезные вещи, вы создаете свой собственный сокет домена unix и предоставляете его контейнеру. HTTP через сокеты домена unix должен работать очень хорошо. Также у вас нет всех проблем с настройкой сети и проблем с безопасностью.

просто пришлось прочитать о «сокетах домена unix».
но:

http://stackoverflow.com/questions/14771172/http-over-af-unix-http-connection-to-unix-socket

утверждает, что URL-адреса нет, и поэтому ни один обычный клиент не может использовать этот механизм из коробки.

С другой стороны:

http://stackoverflow.com/questions/14771172/http-over-af-unix-http-connection-to-unix-socket

показывает, что каким-то образом можно использовать такой сокет.

Но все же я хотел бы просто иметь IP-адрес и порт, которые могла бы просто использовать программа внутри докера. Я буду -- пока -- использовать

 netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

Должен ли я создать новую проблему или кто-то может открыть эту.

@vrvolle
Я не сетевой парень, но я полагаю , что есть некоторые трюки, которые можно сделать, чтобы проксировать локальный хост в контейнер через сокет unix, а затем внутри прокси-сокета unix контейнера для контейнеров-localhost (устройство обратной связи)...

Было бы неплохо задокументировать, как это сделать. Но похоже, что это не обязательно функция, которая нужна докеру для активной поддержки.

Есть несколько способов решить эту проблему, в зависимости от того, чего именно вы хотите достичь.

Если вы хотите подключиться к службе, работающей на хосте (любая служба, например, какой-либо API или база данных, которая будет работать прямо на хосте), вам нужно выяснить IP-адрес хоста.

Один из способов — полагаться на тот факт, что хост Docker доступен через адрес моста Docker, который является шлюзом по умолчанию для контейнера. Другими словами, грамотный анализ ip route ls | grep ^default может быть всем, что вам нужно в этом случае. Конечно, это зависит от деталей реализации (шлюзом по умолчанию является IP-адрес хоста Docker), которые могут измениться в будущем.

Другой способ — использовать Docker API для получения этой информации. Затем возникает проблема «как мне подключиться к Docker API из контейнера?», и потенциальное решение (используемое многими, многими контейнерами!) состоит в том, чтобы связать /var/run/docker.sock с хоста на контейнер. У этого есть большой недостаток: API становится полностью доступным для контейнера, который может сделать с ним плохие вещи.

В долгосрочной перспективе Docker предоставит лучший API для самоанализа, позволяющий получить доступ к этой информации, не отдавая слишком много привилегий контейнерам.

TL,DR: краткосрочный, проверьте маршрут контейнера по умолчанию. В долгосрочной перспективе будет отличный API для самоанализа.

у меня тоже проблема из-за выскочки. я ничего не могу найти в /var/run/docker.sock. и использовал команду «-v /etc/run/docker.sock:/etc/run/docker.sock», но ничего не произошло.
я думаю, что проблема связана с некоторыми новыми обновлениями о возможностях ядра. пожалуйста, дайте мне краткую заметку по этому вопросу. и полная команда, чтобы решить эту проблему. Спасибо

используйте -v /var/run/docker.sock, а не /etc (что обычно зарезервировано для файлов conf).

какие-нибудь обновления по этому поводу в новой версии 1.0.0?

Есть nsenter, но я думаю, что рекомендуется запускать sshd на этом
сцена.

В пятницу, 13 июня 2014 г., Камило Агилар ( [email protected] ) написал:

есть новости об этом в новой версии 1.0.0?


Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/dotcloud/docker/issues/1143#issuecomment-45958769 .

Майкл Д. Нил
домашняя страница: www.michaelneale.net
блог: michaelneale.blogspot.com

vrvolle, спасибо за это. Многие люди, такие как мы, ищут такой лакомый кусочек

netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

Автоматическое обновление Docker /etc/hosts в каждом контейнере с IP-адресом хоста, например, 172.17.42.1 , и вызов его, например, dockerhost , было бы удобным решением.
Думаю, пока мы застряли с netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

+1 за dockerhost в /etc/hosts

+1 для dockerhost в /etc/hosts, звучит как хорошая идея

Редактирование файла в изображении никогда не должно выполняться, ЕСЛИ ДЛЯ этого специально не указан аргумент или флаг. Кроме того, не обязательно, чтобы 100 % изображений следовали за младшим битом, поэтому может даже не существовать каталога /etc . Имя файла, используемого для хранения IP-адреса хоста, также должно быть указано в аргументе команды.

docker --host /etc/hosts

+1 для dockerhost в /etc/hosts

+1 за запись /ec/hosts

Докер @Sepero уже заполняет /etc/hosts связанными контейнерами, поэтому ваши аргументы на самом деле не имеют силы.

@matleh Это правда, но я думаю, что правильный способ не заполнять /etc/hosts напрямую или, по крайней мере, предоставить нам возможность указать местоположение, если у нас его нет.

В любом случае, запись dockerhost в hosts.

Я также хотел бы иметь IP-адрес хоста докера в /etc/hosts .

+1 к IP-адресу узла докера в /etc/hosts

Возможно, лучший способ облегчить доступ к сетевым службам на хосте — упростить настройку записей iptables, которые перенаправляют порты в обратном порядке, то есть из контейнера на хост. Я думаю, что вариант -p или --publish был бы прекрасно дополнен опцией -s или --subscribe , которая имеет обратный эффект. Думаю, я бы назвал их --forward и --reverse. Как бы вы это ни называли, этот подход кажется мне гораздо более последовательным, чем другие предложения здесь.

Это может быть очевидным, но простой способ сделать это, который работает в настоящее время и, возможно, менее зависит от реализации, заключается в том, чтобы определить IP-адрес на хосте перед запуском контейнера и соответствующим образом установить переменную среды в контейнере. Вдоль этих строк:

#!/bin/bash
HOSTNAME=$(hostname)
HOST_IP=$(ip route | awk '/docker/ { print $NF }')
docker run -e HOST=$HOSTNAME -e HOST_PORT=tcp://$HOST_IP:8000 mycontainer

Это было бы по существу параллельно тому, как работает --link . Это по-прежнему зависит от моста, имеющего имя, которое соответствует /docker/ , и существует только один такой мост, но мост устанавливается при запуске демона docker. Было бы неплохо, если бы docker info дал нам имя используемого моста и/или IP-адрес хоста. Другой мыслью было бы добавить параметр --link-host PORT к docker run , который сделал бы по существу вышеописанное.

имхо это лучший вариант. С --link-host контейнеру не нужно знать, находится ли служба, к которой он обращается, на хосте или в другом контейнере.

Я не уверен, как другие вызывают свои контейнеры, но когда я запускаю их с помощью --net=host , я вижу ту же настройку сети, что и мой узел докера. Без этого переключателя я получаю автономный сетевой стек, как описано в справочных страницах docker-run .

$ docker run -i --net=host fedora ip route ls
default via 10.0.2.2 dev eth0  metric 1
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
127.0.0.1 dev lo  scope link
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.42.1
192.168.59.0/24 dev eth1  proto kernel  scope link  src 192.168.59.103

работа без переключателя дает это:

$ docker run -i fedora ip route ls
default via 172.17.42.1 dev eth0
172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.4

То, что мы ищем, — это способ получить IP-адрес либо 10.0.2.15 (IP-адрес eth0 i/f моего хоста докера), либо 172.17.42.1 (IP-адрес моего моста docker0 i/f).

Меня не особенно волнует подход добавления некоторого хоста в мой файл контейнеров /etc/hosts, который кажется мне немного хакерским. Скорее, размещение этой информации внутри, чтобы я мог получить ее, когда это необходимо, было бы более разумным способом пойти сюда.

+1 за --link-host или другим интуитивным способом

+1 за запись /etc/hosts
Кажется довольно удобным и следует текущим правилам общения.

Просто чтобы уточнить мои предыдущие комментарии: что хорошего в --link <container>:<alias> , так это то, что он предоставляет _service_ через _alias_. Точно так же механизм предоставления хоста контейнеру должен обеспечивать доступ к конкретной службе, а не только к IP-адресу. Контейнер будет обращаться к этой службе через псевдоним; ему не нужно знать, где на самом деле находится служба. Параметр должен иметь обратную семантику -p и вести себя как --link . Другими словами, --link-host <ip address>:<port>:<alias> установит переменные env и запись /etc/hosts , а также настроит записи iptables по мере необходимости, т.е. если служба на хосте прослушивает IP-адрес, который иначе недоступен. к контейнеру.

@altaurog Как насчет чего-то подобного?

docker run --name someservice -d host-exposing-image --expose 8000

someservice будет просто любым именем, которое вы затем сможете использовать для --link , а host-exposing-image будет специальным образом, который перенаправляет хост-порты на открытые порты. Вероятно, эту идею можно было бы реализовать, разделив /var/run/docker.sock хоста с изображением.

Может что-то подобное уже есть, не знаю.

Редактировать:

docker run --name someservice -d --expose 8000 host-exposing-image

Забудьте вышеизложенное, не читал все комментарии здесь (все еще не читал). Это то, что работает для меня на docker-osx (и извините за то, что не отправил сообщение в список рассылки):

docker run --rm -ti -e HOST_IP="$(docker-osx ssh -c 'route -n' 2> /dev/null |
  awk '/^0.0/ { print $2 }')" debian:jessie

+1. --link-host — хорошая идея, как и просто иметь запись dockerhost в /etc/hosts

Я создал новую проблему, так как эта проблема закрыта (но не решена): #8395

+1 за dockerhost или любым другим удобным способом.

+1 любым удобным способом

Поскольку подход dockerhost получил здесь несколько голосов, самый простой способ, который я нашел (из комментариев к 3 связанным проблемам # 8395 # 10023), чтобы иметь такую ​​​​запись hosts, — добавить аргумент --add-host=dockerhost:$(ip route | awk '/docker0/ { print $NF }') при запуске изображения, например:

run --add-host=dockerhost:$(ip route | awk '/docker0/ { print $NF }')  ubuntu ping -c2 dockerhost

Хотя это добавляет требуемую запись /etc/hosts, все же жаль, что dockerhost отсутствует по умолчанию. При распространении изображения у меня есть выбор:

  • поручить пользователям добавить указанный выше параметр
  • сделать несколько скриптов, работающих в контейнере, которые адаптируют файлы конфигурации на основе таблицы маршрутизации

Я лично не понимаю, почему dockerhost не существует по умолчанию, это сделало бы создание и распространение образов, которые обычно обращаются к службам на хосте (XServer, CUPS, Puleaudio), намного удобнее.

+1 для докерхоста. Я бы на самом деле выставил это как env var, запись /etc/hosts и флаг cli. Он обязательно будет использоваться во многих отношениях.

:+1: для докерхоста

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

cat << EOF > /etc/profile.d/dockerhost.sh
 grep dockerhost /etc/hosts || echo $(ip r ls | grep ^default | cut -d" " -f3) dockerhost >> /etc/hosts
EOF

работает для меня всякий раз, когда я вхожу в систему (с учетной записью root)

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста :yum:

+1 для докерхоста

+1 для докерхоста: +1:

В итоге написал этот скрипт, может кому пригодится:

#!/bin/bash

SED="$(which sed)"
NETSTAT="$(which netstat)"
GREP="$(which grep)"
AWK="$(which awk)"
CAT="$(which cat)"


$SED '/dockerhost$/d' /etc/hosts > /etc/hosts.tmp
DOCKERHOST="$($NETSTAT -nr | $GREP '^0\.0\.0\.0' | $AWK '{print $2}')"

echo "$DOCKERHOST dockerhost" >> /etc/hosts.tmp

$CAT /etc/hosts.tmp > /etc/hosts

rm -rf /etc/hosts.tmp

+1 докерхост

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

Некоторое время назад я открыл https://github.com/docker/docker/issues/8395 и тоже закрыл. До сих пор нет документированного решения

хорошо, хотя есть обходные пути, я думаю, что основная причина, вероятно, заключается в том, что доступ к хосту является частично изолированным вариантом использования.

поскольку есть функция ссылок на докеры, я думаю, что имеет смысл предоставить ссылку на хост.

Возможно https://github.com/docker/docker/pull/10902 решает это

Привет!

К вашему сведению, теперь это задокументировано :

Примечание. Иногда вам нужно подключиться к хосту Docker, что означает получение IP-адреса хоста. Вы можете использовать следующие команды оболочки, чтобы упростить этот процесс:

$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run --add-host=docker:$(hostip) --rm -it debian

Спасибо, @icecrime.

Может ли специалист по докеру заблокировать эту проблему, чтобы люди перестали ее обновлять?

+1 для докерхоста

+1 для dockerhost - необходимость запуска псевдонима локальной команды hostip несовместима, например, с docker-compose, docker-swarm и т. д. и т. д.

+1 для докерхоста

@icecrime , который дает хост-шлюз, а не IP-адрес хоста на моей Ubuntu. Разве это не должна быть только команда ниже?

$ ip address show

+1, что-то полезное без запуска команд было бы идеально

Как это до сих пор не решено? Выполнение команд в контейнере, чтобы сделать контейнер для размещения сети функциональным, совершенно неприемлемо.

+1 за все простое
Кстати, обходной путь с ip работает на моей Ubuntu, но не работает на OS X, верно?

+1 Это проблема двухлетней давности и полезная функция. Мне нужен простой способ подключения к удаленному API-интерфейсу докера изнутри контейнера.

@ianchildress , если ваш демон настроен на прием подключений к сокетам, просто привяжите сокет к вашему контейнеру, например, docker run -d -v /var/run/docker.sock:/var/run/docker.sock myimage

+1 для докерхоста
Обнаружил эту проблему при просмотре решений для варианта использования: xdebug.remote_host=dockerhost

+1 для докерхоста

@thaJeztah, а как мне оттуда получить имя хоста или IP-адрес?

@mbonaci Я отвечал @ianchildress , который хотел подключиться к Docker API внутри контейнера (для которого использование подключения через сокет является общим подходом)

Я запутался. @icecrime выше сказал выше, что теперь это задокументировано, но ссылка, которую он дал, мертва. Я не могу быстро найти цитируемую часть документации. Я отмечаю, что пример apt-cache-ng использует dockerhost, но не определяет, что это такое (#11556). Единственная ссылка, которую я мог легко найти, была эта тема. Я просмотрел весь исходный код и документацию докера, и, похоже, он не упоминается в этом контексте .

@pwaller С марта мы разделили этот огромный длинный документ на отдельные ссылки. Новое место для этого материала:

http://docs.docker.com/reference/commandline/run/#добавление -entries-to-a-container-hosts-file

+1 для докерхоста

@moxiegirl Я думаю, что параметр --add-host удовлетворительный. Спасибо

А как подключиться к хосту из докер-контейнера? Например, для того, чтобы сделать git pull? Без объемов?

@a93ushakov все это объясняется в ссылке, которую предоставила @moxiegirl .
Когда вы делаете docker run , добавьте следующий параметр: --add-host=dockerhost:replace_with_docker_host_ip , который создает запись в файле /etc/hosts контейнера.
Что, конечно же, означает, что вы можете ссылаться на свой хост-докер из этого контейнера, используя его имя dockerhost .

@mbonaci > Что, конечно же, означает, что вы можете обращаться к своему хосту докеров из этого контейнера, используя его имя, dockerhost.

Через сш?

@thaJeztah > если ваш демон настроен на прием сокет-соединений, ...
Как это сделать?

@ a93ushakov SSH: если он установлен и работает на хосте (и его порт не заблокирован), да.

@a93ushakov @thaJeztah относится к соединению сокета Unix. Я думаю, что это значение по умолчанию - посмотрите, есть ли у вас файл /var/run/docker.sock на вашем хосте.

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста
Было бы неплохо получить это имя хоста без каких-либо дополнительных действий.

1 для докерхоста

+1 за dockerhost

Не удается подключиться к хосту докера из контейнера. Любые идеи, что я делаю неправильно?

$ hostip=$(ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }')
$ nc -l -p 1234 &
[1] 17361
$ docker run --add-host=docker:$(hostip) --rm -it hiromasaono/curl curl docker:1234
curl: (7) Failed to connect to docker port 1234: Connection refused

+1 для докерхоста

Когда я добавляю IP-адрес моста Docker, он работает.

Сначала прослушайте порт 1234 с помощью netcat

$ nc -l -p 1234

Получить IP моста

$ ifconfig docker0 | grep 'inet addr'
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0

Затем подключите

$ docker run --add-host=docker:172.17.42.1 --rm -it hiromasaono/curl curl 172.17.42.1:1234

Затем я вижу ответ

GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 172.17.42.1:1234
Accept: */*

+1 для докерхоста
Блин, когда?

+1 за dockerhost, который работает и на Mac, т. е. прозрачно обрабатывает виртуальную машину.

Может ли кто-нибудь сказать мне, как я буду вызывать Docker API изнутри контейнера? Я не линуксщик. Я уже запустил контейнер с -v /var/run/docker.sock:/var/run/docker.sock .
Все говорят, как сделать монтирование, но никто не упомянул, как вызывать api внутри.

Я пытался позвонить с помощью curl, это не сработало. Я использовал IP-адрес хоста, например

завиток -XGET http://hostip : 2375/images/json

Вот как я запустил своего демона. т.е. докер -H unix:///var/run/docker.sock -H tcp://0.0.0.0 :2375

Любая помощь будет оценена.

@jprogn средство отслеживания проблем github не предназначено для общих вопросов поддержки; эти вопросы лучше задавать в IRC-канале #docker, в группе docker-users в Google или на forums.docker.com.

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

Может кто-нибудь ответить, как вызвать docker api внутри контейнера??????????????

@jprogn, пожалуйста, следуйте моему комментарию выше; это средство отслеживания проблем, используемое для отслеживания ошибок и запросов функций; не форум поддержки по использованию докера; используйте другие методы, упомянутые выше https://github.com/docker/docker/issues/1143#issuecomment -146924892

+1 для докерхоста

На моем хосте докера CentOS7 я не могу получить маршрут от контейнера к хосту:

[root@docker-host-fkb slehmann]# ifconfig docker0 | grep 'inet'

inet 172.17.42.1  netmask 255.255.0.0  broadcast 0.0.0.0
inet6 fe80::42:a7ff:fe4d:4cb2  prefixlen 64  scopeid 0x20<link>


[root@docker-host-fkb slehmann]# docker run --add-host=docker:172.17.42.1 --rm -it hiromasaono/curl curl 172.17.42.1:1234

curl: (7) Failed to connect to 172.17.42.1 port 1234: No route to host

Есть идеи?

+1, может быть, для этого должна быть переменная среды.

Мне самому хотелось бы наоборот; ссылка с моей хост-машины на контейнеры докеров по имени

+1 для переменной среды dockerhost

Очень сложно объединить специальную запись DNS для доступа к хосту без жесткого кодирования 172.17.42.1. например

extra_hosts:
     - "docker:172.17.42.1"

+1 для dockerhost везде (/etc/host ENV)

+1 это все еще нужно!

мой +1 тоже, потому что добавление ip route list dev eth0 | grep -Eo 'via \S+' | awk '{ print \$2 }' в каждый проект (потому что в dev все проекты находятся на одном хосте и должны иметь возможность вызывать друг друга) начинает казаться плохим взломом

Как решить эту проблему в кластере, например Docker Swarm, где мы не знаем, какой машине будет назначен контейнер при его запуске? IP-адрес шлюза docker0 может отличаться от одного хоста к другому в кластере swarm, поэтому мы не можем просто запустить команду ip route на одном хосте, а затем предположить, что IP-адрес одинаков для всех хостов.

Я также хотел бы иметь возможность сопоставить порт контейнера с портом на мосту docker0, не зная IP-адреса моста docker0. Что-то вроде этого:

eval $(docker-machine env --swarm swarm-master-node)
docker run -d -p "$HOST_GATEWAY_IP:80:80" my-image

$HOST_GATEWAY_IP заменяется тем же IP-адресом, который вы получили бы, выполнив команду ip route на хосте, на котором контейнер в конечном итоге развертывается в кластере.

Это должно поддерживаться для любых других команд, использующих IP-адреса, например, опция --dns для docker run .

Я нашел эту команду проще:

ip ro | grep docker | sed 's|.* \(\([0-9]\+\(.[0-9]\+\)\{3\}\)\)\s*|\1|'

+1 для dockerhost в /etc/hosts

+1 докерхост

+1 за наличие dockerhost в /etc/hosts

+1000 за докерхост

+1 докерхост

+1

+1 или больше.

Я запускаю веб-сервер в контейнере, и мне нужно подключить его к моему mysql, работающему на хосте.
IP-адрес хоста меняется с помощью dhcp, поэтому необходимо что-то динамическое.

@wederbrand альтернативный подход (и, вероятно, более эффективный) может заключаться, например, в подключении к сокету mysql;

docker run -v /var/lib/mysql/mysql.sock:/mysql.sock mywebapp

Это сделало бы сокет MySQL доступным как /mysql.sock внутри контейнера.

@thaJeztah Это может быть вариантом. Однако образ докера, который я использую, также используется для других сред, где сервер mysql находится на удаленном сервере, а образ имеет конфигурацию host:port для базы данных.

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

+1

+1

+1

+1

@peterbollen @radek1st @BradRuderman @aldarund @wederbrand @pataiadam @jllado @geniousphp @coreylenertz @dgtlmoon @xlight (все +1 только за декабрь 2015 г.)
_эта_ проблема закрыта, как и #8395
Не думаю, что добавление +1 к старой проблеме поможет. Создайте новый (я сделал с # 8395) или попробуйте другой маршрут для решения этой проблемы.

Спасибо!

+1

+1 докерхост

+1 для докерхоста

+1 для докерхоста

+1 за докерхост, да ладно...

+1 для докерхоста

использование docker-compose и масштабирование n-арных контейнеров в рое, естественно, не дает средств для выполнения поиска IP-адресов узлов на лету на всех машинах.

Это, как указано выше и изменено для шлюза, не вариант:

extra_hosts:
     - "docker:172.18.0.1"

👍 и для докерхоста...

+1 для докерхоста

+1

+1

+1

+1 докерхост

+1 докерхост

+1 докерхост

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста.
Так как этот вопрос закрыт открываем новый тикет.

+1

+1

Чтобы получить хост в настройке docker-machine , вы можете использовать эту команду:

docker-machine ssh "${DOCKER_MACHINE_NAME}" 'echo ${SSH_CONNECTION%% *}'

Он сообщает о машине, к которой вы подключаетесь через ssh , поэтому он должен работать достаточно хорошо как для локальных, так и для удаленных машин, если на пути нет NAT. Было бы неплохо, если бы docker-machine inspect также где-нибудь сообщал об этом значении, если это технически возможно.

+1

+1 для докерхоста. Звучит как ценная функция, практически не требующая усилий для реализации.

На данный момент, если вам нужно получить доступ к dockerhost в контейнерах, созданных из образов, которыми вы управляете, вы можете добавить этот смысл в сценарий entrypoint.sh для вашего образа: https://gist.github.com/dimitrovs/493678fd86c7cdf0c88312d9ddb4906b .

Или, я думаю, вы можете добавить его в /etc/rc.local, если ваш образ не использует сценарий оболочки в качестве точки входа. Что делает этот gist, так это проверяет наличие dockerhost в /etc/hosts и добавляет его, если его там нет. Это должно происходить каждый раз при запуске контейнера.

Получите IP-адрес шлюза из /proc/net/route:

export ipaddr=$(printf "%d." $(
  echo $(awk '$2 == "00000000" {print $3}' /proc/net/route) | sed 's/../0x& /g' | tr ' ' '\n' | tac
  ) | sed 's/\.$/\n/')

@dimitrovs Можете ли вы показать пример конфигурации? Я возился с этим и не мог получить правильные результаты.

Какие результаты вы получили @amcdnl ? Вы можете поместить ссылку, которую я связал, в файл entrypoint.sh, чтобы он запускался каждый раз при запуске контейнера, или в /etc/rc.local внутри контейнера. Это нужно будет сделать при сборке образа, но сам скрипт будет выполняться при запуске контейнера.

+1 для хоста докеров

@dimitrovs В итоге я написал скрипт, который будет генерировать композицию во время выполнения.

StartDocker.sh

#!/bin/bash
built_docker_file="docker-compose.dev.built.yml"

rm -rf docker-compose.dev.built.yml
localhost_ip="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"
sed -e "s/\${localhost}/$localhost_ip/" docker-compose.dev.template.yml > $built_docker_file

docker-compose -f $built_docker_file build
docker-compose -f $built_docker_file up

docker-compose.dev.template.yml

version: '2'

services:
  nginx:
    container_name: sw_nginx
    image: nginx:latest
    ports:
      - 80:80
    links:
     - search
    volumes:
      - ./Web/wwwroot:/var/www/public
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    extra_hosts:
      - "dockerhost:${localhost}"

@amcdnl Хороший обходной путь. Обратите внимание, что docker-compose поддерживает подстановку переменных (среды).

например (баш):

$ export localhost=$(...)
$ docker-compose (...)

@sebastiannm мое предложение должно быть независимым от хоста, потому что оно выполняется внутри образа докера, но если вы запускаете его на Mac в VirtualBox, то IP-адрес, который вы получите, — это IP-адрес виртуальной машины VirtualBox, а не ваш IP-адрес Mac. Я думаю, что это требование, которое мы обсуждаем. Если вы хотите узнать IP-адрес Mac из экземпляра докера, вам нужен другой подход.

+1 для докерхоста.

Но на данный момент я делаю взлом, аналогичный описанному выше, который позволяет вам динамически получать IP-адрес хоста с помощью простого скрипта, который работает как в Linux, так и в OSX : http://stackoverflow.com/questions/24319662/from-inside -of-a-docker-container-как-я-подключаюсь-к-местному-узлу-машины#38753971

+1 для докерхоста.

+1 для докерхоста

+1+1 докерхост

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

Я не могу подключиться к базовому хост-серверу netcat из контейнера докеров, когда --net=bridge (по умолчанию) с помощью различных методов, обсуждаемых в этом выпуске.

@frankscholten Я не могу воспроизвести ваш успешный тест netcat

Я создал проблему с переполнением стека, описывающую точную проблему: http://stackoverflow.com/questions/38936738/communicate-to-docker-host-from-docker-container
и хотел опубликовать здесь, если это поможет кому-то в будущем

Хотя все это говорит об обмене данными от контейнера к хосту с использованием IP-адреса docker0 в режиме моста, я хочу знать, может ли контейнер также общаться с общедоступным IP-адресом хоста (скажем, с его исходным IP-адресом eth0). Ценю ваш ответ. Я не преуспел в этом.

@sburnwal Я не понимаю, почему вы не сможете связаться с eth0 ip хоста. Контейнер отправит запрос на свой шлюз по умолчанию (docker0), и хост должен ответить без дальнейшей переадресации, поскольку он знает, что у него есть IP-адрес. Ваш пинг на eth0 ip из контейнера истекает, или у вас нет маршрута к хосту, или что происходит? Может ли контейнер подключаться к Интернету?

К сожалению, это не работает для меня. Хотя я могу пропинговать IP-адрес контейнера с хоста, я не могу пропинговать IP-адрес хоста (LAN/eth0 хоста) с контейнера. Я использую докер 1.9.1. Я застрял здесь, так как мне нужен мой контейнер для связи с веб-сервером, который прослушивает только IP-адрес хоста eth0.

Я настроил docker0, используя опцию:
Демон /bin/docker --bip=169.254.0.254/24 --fixed-cidr=169.254.0.0/24

Итак, у меня есть эти интерфейсы на моем хосте (здесь не перечислены интерфейсы veth *):

[root@pxgrid-106 irf]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtg 1500
        inet 169.254.0.254  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::42:84ff:fe87:d510  prefixlen 64  scopeid 0x20<link>
        ether 02:42:84:87:d5:10  txqueuelen 0  (Ethernet)
        RX packets 512  bytes 150727 (147.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 653  bytes 281686 (275.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtg 1500
        inet 172.23.166.176  netmask 255.255.255.128  broadcast 172.23.166.255
        inet6 fe80::20c:29ff:fecc:7d0f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:cc:7d:0f  txqueuelen 1000  (Ethernet)
        RX packets 58462  bytes 12056152 (11.4 MiB)
        RX errors 0  dropped 69  overruns 0  frame 0
        TX packets 30877  bytes 18335042 (17.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Мой контейнер имеет IP-адрес 169.254.0.2, и я могу пропинговать этот IP-адрес контейнера с хоста. Конечно, я могу пропинговать из контейнера его шлюз 169.254.0.254 (ip-адрес docker0), но я не могу пропинговать хост eth0 ip 172.23.166.176.

Я попытался полностью остановить брандмауэр и добавил эти явные правила в брандмауэр в цепочку INPUT, но пока безуспешно. Кто может помочь мне в этом? Или это ошибка?

ACCEPT     all  --  172.23.166.176       169.254.0.0/24      
ACCEPT     all  --  169.254.0.0/24       172.23.166.176   

Кроме того, позвольте мне также вывести вывод «ip route» на моем хосте:

[root@pxgrid-106 bin]# ip route
default via 172.23.166.129 dev eth0 
169.254.0.0/24 dev docker0  proto kernel  scope link  src 169.254.0.254 
172.23.166.128/25 dev eth0  proto kernel  scope link  src 172.23.166.176 

@tn-osimis спасибо за предложение, я обновил и работает хорошо, вот мой код для других:

докер-compose.yml

version: '2'

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    extra_hosts:
      - "dockerhost:${localhost_ip}"

StartDocker.sh

#!/bin/bash
dev_docker_file="docker-compose.yml"

export localhost_ip="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"

docker-compose -f $dev_docker_file build
docker-compose -f $dev_docker_file up

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

Решение @magicalbob действительно волшебное 🎉

+1 для докерхоста

+1, кстати, почему это закрыто? Проблема/запрос функции еще не решена

Любые обновления по этому поводу? Каков правильный путь?

+1

У кого-нибудь есть обновления о том, как подключиться к хосту (общедоступный IP-адрес хоста, например, eth0 ip, а не ip-адрес интерфейса docker0) из контейнера?

@sburnwal docker run --add-host=publicip:$(hostname --ip) ubuntu ping -c2 publicip

См. ответ @retog

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

оставив это здесь, возможно, это поможет хотя бы некоторым из вас:

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

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

Я настроил сетевые настройки докера в файле docker-compose следующим образом:

``` сети:
По умолчанию:
водитель: мост
IPAM:
конфигурация:
- подсеть: 10.10.0.0/24
шлюз: 10.10.0.1

if you are only running one container, you could first create a network (`docker network create`) and connect to it with `docker run --network=<network-name>|<network-id> <image name>`

BUT if you don't want to do this (i.e. force the docker network) and really want to get the default gateway IP, you could get it more cleanly than using `docker0` network interface, for example by parsing the `docker network inspect <network name>`, which outputs the gateway IP (among other things):

...
"ИПАМ": {
"Драйвер": "по умолчанию",
"Конфигурация": [
{
«Подсеть»: «172.17.0.1/16»,
«Шлюз»: «172.17.0.1»
}
]
}
...

you could also use the `--format` option of `docker network inspect` to get only the fields that are of interest, like this:

$ docker network inspect bridge --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}'
$ 172.17.0.1
```

ПРИМЕЧАНИЕ. Если бы было больше записей .IPAM.Config , вы бы получили их все в выводе, поэтому потребуется дополнительная логика выбора правильной.

+1 для докерхоста

Обратите внимание: это было бы очень полезно, когда вы просто хотите использовать xdebug внутри контейнера php-fpm для подключения к вашей IDE для отладки, поскольку вы, очевидно, не можете запустить IDE в контейнере.

+1 для докерхоста

Мое резюме вышеперечисленных хаков:

в docker-compose.yml :

nginx:
  restart: always
  build: ./nginx/
  ports:
    - "80:80"
  extra_hosts:
    # requires `export DOCKERHOST="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"` in ~/.bash_profile
    - "dockerhost:$DOCKERHOST"

в ~/.bash_profile :

# see https://github.com/docker/docker/issues/1143
export DOCKERHOST="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"

в nginx-conf :

location / {
        proxy_pass http://dockerhost:3000;
        proxy_set_header host $host;
        proxy_set_header x-real-ip $remote_addr;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}

Я обычно использую образ докера svendowideit/ambassador, чтобы обойти эту проблему.

Например, если я хочу привязаться к узлу elasticsearch, работающему на хосте Docker:

docker run --restart always -d --name elasticsearch --expose 9200 -e ELASTICSEARCH_PORT_9200_TCP=tcp://<host>:9200 svendowideit/ambassador

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

+1 для докерхоста

... пока вы можете сделать это:

$ docker build --build-arg HTTP_PROXY=172.16.42.1 .

... или в моем аналогичном случае с docker-compose - я делаю так:

client:
        build: ./client
        extra_hosts:
            - "foobar:${HTTP_PROXY}"

установите свой хост во время сборки:

export HTTP_PROXY=172.16.42.1 && docker-compose build

@rattrayalex на Mac, я обнаружил, что это напрямую распечатывает IP: ipconfig getifaddr en0

+1 для докерхоста

Могут ли те из вас, кто просто делает +1 для dockerhost, просто добавить палец вверх (реакцию) на существующий комментарий того же характера? Комментарии +1 просто без необходимости расширяют/заполняют эту ветку проблемы. Их уже так много, нет необходимости добавлять больше, но мы всегда можем поставить большой палец вверх! 👍

Я думаю, что комментаторы пишут обширный +1, чтобы подчеркнуть, что это распространенный вариант использования с известными обходными путями, и для его кодирования командой докеров требуется время, оцениваемое в часах.
Тем не менее, он открыт уже 3 года 👍

Итак, мне кажется, это больше похоже на "мы все еще здесь"? Вместо этого просто смайлик

Решение @magicalbob в https://github.com/docker/docker/issues/1143#issuecomment -233152700 работает безупречно во всех установках контейнеров и мостах, которые я пробовал до сих пор!

решение с https://github.com/docker/docker/issues/1143#issuecomment -70052272 не работает при использовании docker compose extra_hosts

+1 для докерхоста

Все еще нет докерхоста?

+1 для докерхоста

+1 для докерхоста

этого не будет, он был закрыт 3 года назад, и они не планируют это когда-либо реализовывать. по той же причине, по которой docker.sock является пушкой для обеспечения безопасности, dockerhost тоже. ИМХО, наличие разрешимого доменного имени внутри вашего приложения является серьезной проблемой безопасности. если вам нужно, просто используйте обходные пути, выборочно только там, где доступ к службам хоста по IP не будет увеличенной поверхностью атаки.

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

Отправлено с BlueMail​

16 декабря 2016 г., 17:58, 17:58, Пауло Сезар, [email protected] написал:

этого не будет, его закрыли 3 года назад и не планируют
реализовать это. по той же причине docker.sock является пушкой для обеспечения безопасности,
докерхост тоже. наличие разрешимого доменного имени внутри вашего
приложение является серьезной проблемой безопасности ИМХО. если вам нужно, просто используйте
обходные пути, выборочно только там, где доступ к службам хоста по IP не будет
иметь увеличенную поверхность атаки.

--
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/docker/docker/issues/1143#issuecomment-267655915

+1 для докерхоста

+1 для докерхоста

IP-адрес хост-машины 192.168.0.208 .

Файл docker-compose выглядит следующим образом:

version: '2'
 services:
   zl-tigervnc:
     image: zl/dl-tigervnc:1.5
     container_name: zl_dl_tigervnc
     restart: always
     tty: true
     ports:
       - "8001:8888"
       - "6001:6006"
       - "8901:5900"
       - "10001:22"
     devices:
       - /dev/nvidia0
     volumes:
       - ~/data:/root/data
       - /var/run/docker.sock:/var/run/docker.sock
     extra_hosts:
       - "dockerhost:192.168.0.208"

Контейнер был запущен этим скриптом. Контейнер хочет получить доступ к порту 8080 на хост-компьютере (например, 192.168.0.208:8080 ). Но это не работает.

Однако я использую переадресацию портов, чтобы сопоставить 8080 на хост-компьютере с 8080 на маршрутизаторе. IP-адрес маршрутизатора был 63.25.20.83 . Контейнер может получить доступ к 8080 хост-компьютера путем переадресации портов (например, 63.25.20.83:8080 ).

Я пробовал много решений с этой страницы, но это все еще не работает.

Обратите внимание: это было бы очень полезно, когда вы просто хотите использовать xdebug внутри контейнера php-fpm для
подключитесь к вашей IDE для отладки, поскольку вы, очевидно, не можете запустить IDE в контейнере.

Точно @colinmollenhour ! За исключением дополнительной проблемы. Вы можете пропинговать хост, но на самом деле вы не можете подключиться к портам хоста (например, удаленный отладчик, работающий на 9000).

Много старого и/или не совсем правильного материала в сети. Многие считают, что настройка IP-псевдонима и подключение его к интерфейсу lo должны работать, но это не так.

(тестирование с помощью netcat на хосте и telnet в док-контейнере, поэтому я хорошо разобрался).

@bitwombat проверьте брандмауэр вашего хоста на наличие правила порта 9000

@gregmartyn Это было именно так. Спасибо! Было бы первое, что я проверил в более простой настройке! Все слои обмана заставляли меня проверять более странные вещи.

Июль 2013 по 2017 год. Почти 4 года, как это еще не функция? Это явно не единичный случай использования.

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

Я по-прежнему считаю, что есть много допустимых вариантов использования, и добавление этой функции не нанесет никакого вреда стратегии Docker. Во всяком случае, вот несколько простое решение для разрешения адреса хоста докера из контейнера, которое, я думаю, должно работать довольно универсально:

ip route | awk '/^default via /{print $3}'

+1 за dockerhost

Очень нужно. +1 за dockerhost

+1 за dockerhost

+1 для докерхоста

+1 для докерхоста

+1 за любое решение, которое не является хакерским обходным путем. Здесь ничего не работает.

Согласованный. +1 за решение. Он нужен для разработки и тестирования проектов, использующих докер.

+1 для докерхоста

+1 для докерхоста

+1 для докерхоста

ничего себе .. 4 года и становится сильным. +1 для докерхоста?

+1 докерхост!!

+1 докерхост!!!

Это, наверное, заглушено. Возможно, мы должны сделать новый выпуск со ссылкой на этот.

:+1: для dockerhost... Сейчас настраиваю через env:

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)

Это делает вещи громоздкими.

Даже такая простая вещь, как использование docker-compose в контейнере с частным реестром, туннелируемым через ssh, не работает, потому что Docker так твердо настроен на то, чтобы не хотеть dockerhost.

ВНИМАНИЕ: этот вопрос закрыт, поэтому нет смысла добавлять к нему дополнительные комментарии :-)

Если вам нужна эта функция, вы можете легко добавить DNS-псевдоним dockerhost , используя --add-host и эквивалентные параметры.

Почему это недоступно по умолчанию? Потому что это работает только в тривиальных случаях. То есть:

  • как насчет контейнеров, которые _не_ имеют доступ к сети?
  • а как насчет контейнеров с _несколько_сетями?
  • как насчет контейнеров, работающих в кластере Swarm?

Если у вас есть хороший вариант использования (например, «Я хотел бы сделать XXX, и для этого я хотел бы иметь dockerhost ...»), а также четкие ответы на приведенные выше вопросы (и другие угловые случаи, которые могут возникнуть), не стесняйтесь открывать новый выпуск со ссылкой на этот!

Спасибо.

Проблема в том, что IP-адрес вашего хоста может быть динамическим и зависеть от того, в какой сети вы находитесь. Если вы разрабатываете подключение к хосту для отладки, это обязательно. Причина, по которой всем нужен dockerhost, не в том, что опции, которых нет, удобны или вообще полезны.
У Docker есть множество опций, которые не имеют отношения ко всем, чем это отличается? Почему бы не иметь возможность в докере включить dockerhost, если это необходимо, я думаю, это сделает 99% счастливыми.

@jpetazzo

как насчет контейнеров, у которых нет доступа к сети?

Тогда dockerhost не будет работать.

как насчет контейнеров с несколькими сетями?

Тогда dockerhost не будет работать.

как насчет контейнеров, работающих в кластере Swarm?

Какая разница?

Если вы разрабатываете какое-то программное обеспечение, включающее компоненты за пределами экосистемы докера (например, какое-то программное обеспечение, работающее внутри виртуальной машины Windows на хосте), то подключить его к докеру будет проблематично. Почему это должно быть болью?

Все перечисленные вами случаи - это не то, о чем говорят 226 комментариев в этой ветке, они говорят о базовом случае.

Редактировать: Извините, я удалил часть своего комментария. Я не хотел разглагольствовать. Это просто немного расстраивает, это очень нужная функция для некоторых пользователей докеров, и если вы разрабатываете программное обеспечение, для которого она требуется, еще больше разочаровывает необходимость взломать ее, казалось бы, без всякой причины.

@jpetazzo иногда «тривиальные» случаи составляют 80% случаев использования. Dockerhost был бы очень полезен для людей, использующих Docker в средах разработки или промежуточных средах , или действительно в любых средах, которые не полагаются на сеть с роем / несколькими хостами. Вот несколько примеров, где я хотел бы использовать Dockerhost:

1) Docker-Compose в Windows с приватным реестром. У нас есть собственный частный реестр Docker. Разработчики могут получить доступ к реестру через туннель SSH с переадресацией портов (т.е. на localhost:5000). Но когда Docker-Compose работает в собственном контейнере Docker, указать хост частного реестра невозможно. Если бы у нас был dockerhost , мы могли бы использовать docerhost:5000 в нашем файле docker-compose.yml, предоставляя ему доступ к переадресованному порту на хосте.

2) Любое приложение, которому необходимо обмениваться данными со службами, работающими на хосте. Например, веб-клиент SSH, работающий в контейнере докеров, можно использовать для установления SSH-соединения с хостом , если там был dockerhost . Существует бесчисленное множество примеров служб, работающих на хосте контейнера Docker, которые можно использовать при наличии dockerhost .

3) Обратное перенаправление портов. Мы можем запустить наш сервер SSH или OpenVPN в контейнере Docker, и он может предоставить клиентам доступ к службам, работающим на хосте , если есть dockerhost . Вы можете настроить переадресацию портов из контейнера в dockerhost.

Я хотел бы услышать любое техническое обоснование того, почему разработчики Moby отказываются слышать сообщество, когда дело касается dockerhost. Пока я слышу только политические/деловые причины.

Наткнулся на эту ветку, пытаясь найти способ подключить сетевой интерфейс macvlan к службе роя... Swarm кажется наполовину законченным решением, неспособность предоставлять службы напрямую внешнему миру вызывает у меня постоянное разочарование. Такое ощущение, что Docker потерял связь с реальными вариантами использования, перенесемся на 4 года вперед с момента запуска этого потока, и до сих пор нет нативной реализации, позволяющей контейнерам управлять собой.

Я относительно новичок в Docker. Все, что я читал в официальных документах, имеет смысл. _Docker на самом деле довольно простой инструмент._

На самом деле, единственное, что я потратил несколько часов, пытаясь выяснить, как подключиться к хосту из контейнера . Все остальное было легко определить. Я до сих пор не знаю, как это сделать. Многие «хаки» на этом форуме и на SO просто не работают. Нам нужен доступ к хосту, чтобы использовать устаревшее приложение, которое не настроено как «Dockerized» в течение многих месяцев.

Боюсь, Джош, этого никогда не случится. Разработчики дали это понять.
Что делает докер хуже, чем бесполезным для большого класса приложений,
к сожалению, докеру (или "моби") было наплевать на эти
разработчиков или этих приложений.

19 июня 2017 г., 01:08, «Джош Ведекинд» [email protected] написал:

Я относительно новичок в Docker. Все, что я прочитал из официальных документов
имеет смысл. Docker на самом деле довольно простой инструмент.

На самом деле, единственное, что я потратил несколько часов, пытаясь понять
как подключиться к хосту из контейнера. Все остальное
было легко определить. Я до сих пор не знаю, как это сделать. Многие из
«взломы» на этом форуме и на SO просто не работают. Нам нужно получить доступ к
хост для использования устаревшего приложения, которое не настроено как "Dockerized"
в течение многих месяцев.


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/1143#issuecomment-309311997 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AA-shyjglsJXawxHHWghQH0d1LlZeJqxks5sFbwXgaJpZM4Ayw00
.

Это действительно расстраивает, что вы можете справиться с любой ситуацией с помощью простого декларативного файла docker-compose, но вам нужно использовать тысячу трюков, чтобы подключиться к устаревшему приложению из вашего контейнера в вашей среде разработки.
@thaJeztah Это совсем не производит хорошего первого впечатления от докера.

К вашему сведению, мы отказались от Docker именно по этой причине. Я знаю, что разработчики Docker категорически против этого (и я понимаю, что это не такая тривиальная функция, как некоторые утверждают), но я просто хотел вмешаться: вы теряете реальных клиентов из-за упорного отказа даже рассмотреть Эта проблема. Как неохотный «эксперт» по Docker в моей компании, я теперь должен предостеречь людей, которые спрашивают меня об этом, говоря: «Docker великолепен… за исключением случаев , когда вам нужно взаимодействовать с чем-либо, работающим на локальном хосте».

Итак, еще раз, я уверен, что проблема приглушена, но если вы когда-нибудь оглянетесь на эту ветку, разработчики Docker, это причиняет настоящую боль и заставляет реальных клиентов Docker перестать использовать Docker. Я рекомендую пересмотреть ваш упорный отказ решить проблему; то, что это не соответствует вашему видению того, как Docker «должен» использоваться, не означает, что это бесполезная или ненужная функция.

Мало того, что они могут (теряют) потерять существующих клиентов. Мы могли бы перенести все в докер, если бы он оправдал обещания по разработке. Это настоящая антипропаганда использования докера в больших масштабах для всех процессов.

Сейчас я заставляю это работать, создавая сеть. Вот как выглядит мой файл docker-compose:

version: '2'
services:
  <container_name>:
    image: <image_name>
    networks:
      - dockernet

networks:
  dockernet:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.0.0/24
          gateway: 192.168.0.1

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

@deltabweb Будут ли запросы, поступающие в приложения на хост-компьютере, отображаться как трафик «localhost», или мне придется изменить приложения, чтобы они отвечали на 192.168.0.1?

Спасибо за вашу помощь.

@halfnibble
Я не просматривал документацию networks в деталях, но я понимаю, что новая сеть на вашем хост-компьютере создается, где:

  • IP-адрес «докерхоста» — 192.168.0.1.
  • IP первого контейнера 192.168.0.2
  • IP второго контейнера 192.168.0.3
  • и так далее ...

Начиная с этого момента, все должно работать так, как если бы у вас были физические машины, соединенные вместе в локальной сети:

  • машины могут соединяться друг с другом
  • и вы даже должны иметь возможность использовать ping 192.168.0.2 с хоста - это будет работать, только если ваш контейнер отвечает на эхо-запросы.

Итак, чтобы ответить на ваш вопрос, я думаю, что ваши приложения на хост-компьютере должны будут отвечать на 192.168.0.X (в зависимости от контейнера, пытающегося подключиться).

@deltabweb , как в облаке я могу получить доступ к хост-порту сервера? >>> В соединении отказано

@nooperpudd Просто чтобы быть уверенным: вы пытаетесь получить доступ к приложению, работающему на хосте, из контейнера, верно?
Я бы сначала проверил, разрешает ли приложение входящие подключения извне (0.0.0.0, а не только localhost). И, может быть, также убедитесь, что у вас нет брандмауэра, блокирующего соединение?

@nooperpudd , если вы используете Docker for mac , вы не можете использовать режим host , решение @deltabweb также не работает для меня (все мои серверы слушают 0.0.0.0 и брандмауэры моей хост-машины были отключены, но я каждый раз получаю Connection refused ). Примерно через 2 дня проб и ошибок единственным способом, который я нашел для решения этой проблемы, является сценарий ниже:

#!/bin/bash
export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)

# You should use DOCKERHOST env variable in your `docker-compose.yml` 
# and put it everywhere you want to connect to `localhost` of the host machine
docker-compose $@

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

Замечательным для меня наблюдением является то, что команда, которая выполняется при запуске контейнеров docker, не может подключиться к контейнеру через IP-адрес его хоста. Однако, когда эта команда не выполняет такие попытки подключения и успешно завершает выполнение, контейнер затем может связаться с самим собой через свой IP-адрес хоста.

Я сделал это наблюдение, когда пытался предоставить конечные точки экземпляров кластера базы данных NoSql клиентам за пределами кластера swarm. В конце концов, эти конечные точки должны быть настроены с использованием частных или общедоступных IP-адресов виртуальной машины, чтобы внешний клиент мог получить к ним доступ. Однако Cassandra разработана таким образом, что при запуске она пытается немедленно подключиться к IP-адресу хоста (установленному как переменная среды CASSANDRA_BROADCAST_ADDRESS — см. ниже) и поэтому терпит неудачу. С другой стороны, все узлы наборов реплик Mongodb сначала запускаются в чистом состоянии, а затем выполняется отдельная команда инициализации, чтобы первичный и вторичный узлы могли сформировать набор реплик.

Ниже вы видите подробный отчет об этом наблюдении для cassandra (я создаю их с помощью docker swarm, но та же проблема возникает в docker run -d (в режиме NAT, поэтому без параметра --net=host)

1) С одной стороны, контейнер, созданный

docker service create  --name cassandra-service
--publish mode=host,target=7000,published=7000,protocol=tcp 
-e CASSANDRA_SEEDS=host IP address  -e CASSANDRA_BROADCAST_ADDRESS=host IP address

терпит неудачу с сообщением, что он не может подключиться к адресу прослушивания: <host IP address>:7000

2) С другой стороны, контейнер, подключенный к оверлейной сети, созданной

docker service create  --network cassandra-net --name cassandra-service
-e CASSANDRA_SEEDS=cassandra-service  -e CASSANDRA_BROADCAST_ADDRESS=cassandra-service

запускается правильно, и в то же время я могу подключиться к IP-адресу хоста на любом порту, указанном в Dockerfile образа cassandra :2.0 :

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                         NAMES
07603a75a379        cassandra:2.0       "/docker-entrypoin..."   About a minute ago   Up About a minute   7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   cassandra-service-1.1.m243u97zku15w08m6puytdngs

$ docker exec -it 1e61ec16f8d0 bash
root<strong i="5">@1e61ec16f8d0</strong>:/# cqlsh 172.17.13.151
Connected to Test Cluster at 172.17.13.151:9160.
[cqlsh 4.1.1 | Cassandra 2.0.17 | CQL spec 3.1.1 | Thrift protocol 19.39.0]

Аналогично то же самое можно наблюдать и при создании второй ноды cassandra.

1) Если я создам второй контейнер cassandra на другом узле с помощью

docker service create  --network cassandra-net --name cassandra-service-2
-e CASSANDRA_SEEDS=172.17.13.151  -e CASSANDRA_BROADCAST_ADDRESS=cassandra-service-2

контейнер выходит из строя с исключением во время выполнения, что он не может сплетничать с семенем:

java.lang.RuntimeException: Unable to gossip with any seeds
        at org.apache.cassandra.gms.Gossiper.doShadowRound(Gossiper.java:1322)
        at org.apache.cassandra.service.StorageService.checkForEndpointCollision(StorageService.java:457)

2) С другой стороны, если я создаю контейнер cassandra через docker run -d , я могу получить доступ к начальному узлу через его IP-адрес хоста:

$ docker run -d cassandra:2.0
d87a79cc3de8cd7e4cf40284d1eca91ceb660581cc71082fe64a6b84a09fbd77
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                         NAMES
d87a79cc3de8        cassandra:2.0       "/docker-entrypoin..."   3 seconds ago       Up 2 seconds        7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   trusting_ardinghelli
$ docker exec -it d87a79cc3de8 bash
root<strong i="17">@d87a79cc3de8</strong>:/# cqlsh 172.17.13.151
Connected to Test Cluster at 172.17.13.151:9160.
[cqlsh 4.1.1 | Cassandra 2.0.17 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
Use HELP for help.
cqlsh>

В частности, для Cassandra вы решаете эту проблему, отключая автоматическую загрузку узлов Cassandra. Вы делаете это, устанавливая auto_bootstrap в false в /etc/cassandra/cassandra.yaml с помощью команды точки входа в Compose V3:

version: '3'
services:
  cassandra-1:
    image: cassandra:2.0
    entrypoint:
    - "sh"
    - "-c"
    - "echo auto_bootstrap: false >> /etc/cassandra/cassandra.yaml; /docker-entrypoint.sh cassandra -f"
    environment:
      CASSANDRA_BROADCAST_ADDRESS: 172.17.13.151
    volumes:
    - volume1:/var/lib/cassandra
    ports:
    - "7000:7000"
    - "7001"
    - "7199"
    - "9042:9042"
    - "9160:9160"

а затем вручную запустить узлы cassandra, выполнив docker exec -it <container id> nodetool rebuild .

Я мог бы использовать эту функцию в разработке, ну...

@jpetazzo Мы разрабатываем PHP-решения в командах на разных платформах. Нашему отладчику (xdebug) необходимо снова подключиться к IDE на хосте. В Windows и Linux это работает «из коробки», но на Mac наши разработчики должны изменить файл xdebug.ini, чтобы конкретно указать их локальный IP-адрес. Но Dockerfile находится под управлением исходного кода... постоянные конфликты в очереди и ругань, поскольку разработчики конфликтуют из-за редактирования этого файла. Да, есть обходные пути с поддержкой сценариев, но почему в докере для Windows и Mac есть docker.for.win.localhost и docker.for.mac.localhost? Это частично полезно, но нам все еще нужны скрипты, чтобы определить, на какой платформе мы работаем, чтобы правильно настроить это. Просто кажется, что это намного сложнее, чем должно быть. Пожалуйста, пересмотрите эту функцию. Docker может быть крутой кривой обучения, но подобные проблемы заставляют ваших пользователей недоверчиво искать в Google часами подряд.

Проверка страницы https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds помогла, нам помогло использование docker.for.mac.localhost :)

Хорошо это или плохо, но docker-compose по-прежнему остается самым простым из известных мне способов раскрутить Selenium Hub и безголовые узлы сетки Firefox/Chrome для тестирования веб-сервера, работающего на локальной машине разработки или в CI (запуск веб-сервер в док-контейнере слишком медленный, чтобы быть удобным для разработки). Это совсем не то, для чего был предназначен Docker, но Docker — лучший инструмент для этой работы, и в этом виноват сам Docker 😆 За исключением того, что единственная проблема заключается в том, чтобы легко определить IP-адрес хоста таким образом, который работает на любой ОС.

@rskuipers , можете ли вы объяснить, что именно вы сделали с docker.for.mac.localhost ? Я пытаюсь делать запросы внутри своих контейнеров для разрешения на хост-компьютер. Мои контейнеры работают на traefik, что означает, что я могу получить к ним доступ через domain.docker.localhost, но если я попытаюсь получить доступ к URL-адресу, начинающемуся с этого, внутри моего контейнера, он не будет разрешен.

В настоящее время я добавил это к своему docker-compose.yml , что добавляет строку к /etc/hosts , чтобы домен правильно разрешался:

extra_hosts: - "domain.docker.localhost:172.18.0.1"

IP-адрес — это IP-адрес хоста из моего контейнера, который я могу получить, используя ip route | awk '/^default via /{print $3}' . Но я бы не хотел жестко кодировать это, если это возможно...

@jzavrl Все, что я сделал, это использовал docker.for.mac.localhost , чтобы мои HTTP-запросы проходили через прокси-сервер, работающий на хосте. Я не использую никаких других слоев, кроме docker-compose .

Это именно то, что меня интересует. Какие именно изменения вам пришлось внести?

@jzavrl Нет: P это только что сработало.

Я не понимаю, что ты тогда сделал с docker.for.mac.localhost ?

@jzavrl Я использовал его вместо IP-адреса для подключения. Итак, docker.for.mac. локальный: 8888

Аааааа, теперь это начинает иметь смысл. Попробую это тогда. Привет @rskuipers.

просто используйте ip "en0" на вашем компьютере.

Например

ssh [email protected]

«192.168.1.100», возможно, от службы DHCP вашего маршрутизатора.

@acuthbert , спасибо за ваше предложение.
docker.for.win.localhost у меня работает в Docker для Windows. Пока есть надежда на Docker и Windows. 😣

есть небольшая техническая причина, почему это нельзя сделать и удовлетворить 90% людей в этой теме, крайние случаи и ситуации, когда это действительно не работает, люди, которые развиваются в этой ситуации, могли бы быть удовлетворены простым набором «прецедентов», которые объясняют, в каких сценариях это может не сработать.

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

@NdubisiOnuora , какое у тебя приложение? веб приложение?

У меня есть 2 консольных приложения (tcp-сервер в хосте и tcp-клиент в контейнере).
Поскольку они используют tcp, мне нужен именно IP ( docker.for.win.localhost не подходит, потому что это домен).

Например, какой ip:port я должен установить в tcp-клиенте, если я установлю ip:port 127.0.0.1:9595 в tcp-сервере?

Просто разрешить домен на IP-адрес?

@орф ,
Я хочу использовать этот код на С#:
IPAddress hostAddr = Dns.Resolve("docker.for.win.localhost").AddressList[0];
Но перед этим я пытаюсь пропинговать docker.for.win.localhost , но не вижу этого, ошибка: Ping request could not find host docker.for.win.localhost. Please check the name and try again.
Мой докерфайл:
FROM microsoft/windowsservercore
ADD . /
ENTRYPOINT powershell ping docker.for.win.localhost

На случай, если кто-то пропустил это, я считаю, что решение от 18.03 — это host.docker.internal , хотя по какой-то причине это работает только в Docker для Windows!? Почему не другие?

РЕДАКТИРОВАТЬ: Не видел, чтобы комментарии были свернуты Github... 🤦‍♂️

Работает на меня:
docker run --rm -it --add-host "docker.for.localhost:$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" alpine:latest ping docker.for.localhost

@lukasmrtvy Это работает для оболочки, но как насчет docker-compose.yml ?

Я создал контейнер для решения этой проблемы общим способом, работающим на всех платформах https://github.com/qoomon/docker-host .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги