Docker localhost in container linux

What does localhost means inside a Docker container?

Say, if I use this command inside a docker container.

What would the localhost here refer to? The host machine’s IP or the docker container’s own IP?

2 Answers 2

From inside a container, localhost always refers to the current container. It never refers to another container, and it never refers to anything else running on your physical system that’s not in the same container. It’s not usually useful to make outbound connections to localhost or configure localhost as your database host.

From a shell on your host system, localhost could refer to daemons running on your system outside Docker, or to ports you’ve published with docker run -p options.

From a different system, localhost refers to the system it’s called from.

In terms of IP addresses, localhost is always 127.0.0.1, and that IP address is special and is always localhost and behaves the same way as above.

If you want to make a connection to a container.

. from another container, the best way is to make sure they’re on the same Docker network (you started them from the same Docker Compose YAML file; you did a docker network create and then did docker run —net . on the same network) and use Docker’s internal DNS service to refer to them by the container’s —name or its name in the Docker Compose YAML file and the port number inside the container. Even if the target has a published port with a docker run -p option or Docker Compose ports: setting, use the second (container-internal) port number.

. from outside Docker space, make sure you started the container with a docker run -p or Docker Compose ports: option, and connect to the host’s IP address or DNS name using the first port number from that option.

. from a terminal window or browser on the same physical host, not in a container, in this case and in this case only, localhost will work consistently.

Except:

If you started a container with —net host , localhost refers to the physical host, and you’re in the «terminal window on the same physical host» scenario.

If you’ve gone out of your way to have multiple servers in the same container, you can use localhost to communicate between them.

Источник

Изнутри контейнера Docker, как подключиться к localhost машины?

Итак, у меня есть Nginx, работающий внутри контейнера docker, у меня есть mysql, работающий на localhost, я хочу подключиться к MySql из моего Nginx. MySql работает на localhost и не подвергает порт внешнему миру, поэтому его привязка к localhost, не привязанная к ip-адресу машины.

есть ли способ подключиться к этому MySql или любой другой программе на localhost из этого контейнера docker?

15 ответов

Edit: если вы используете Докер-для-mac или Docker-for-Windows 18.03+, просто подключитесь к своей службе mysql, используя хост host.docker.internal .

начиная с Docker 18.04, это не работает на Docker-for-Linux.

использовать —network=»host» в своем , потом 127.0.0.1 в вашем контейнере docker будет указывать на ваш хост docker.

обратите внимание на docker контейнерные сетевые режимы

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

docker run —network= «мост» (по умолчанию)

Docker создает мост с именем docker0 по умолчанию. И хост docker, и контейнеры docker имеют IP-адрес на этом мосту.

на Докер хост, типа sudo ip addr show docker0 у вас будет выход, похожий на:

Итак, здесь мой хост docker имеет IP-адрес 172.17.42.1 на docker0 сетевой интерфейс.

теперь запустите новый контейнер и получите оболочку на нем: docker run —rm -it ubuntu:trusty bash и в пределах контейнерного типа ip addr show eth0 чтобы узнать, как настроен его основной сетевой интерфейс:

Читайте также:  Windows не запускается после установки видеодрайвера

здесь мой контейнер имеет IP-адрес 172.17.1.192 . Теперь посмотрите на таблицу маршрутизации:

Итак, IP Адрес хоста docker 172.17.42.1 устанавливается в качестве маршрута по умолчанию и доступен из контейнера.

docker run —network= «host»

в качестве альтернативы вы можете запустить контейнер docker с настройки сети установлено значение host . Такой контейнер будет делиться сетевым стеком с хостом docker и с точки зрения контейнера, localhost (или 127.0.0.1 ) будет ссылаться на хост docker.

имейте в виду, что любой порт открыт в ваш контейнер docker будет открыт на хосте docker. И это не требуя -p или -P docker run опции.

конфигурация IP на моем хосте docker:

и из контейнера докера в хоста режим:

как вы можете видеть, как хост docker и контейнер docker имеют один и тот же сетевой интерфейс и как таковой имеют один и тот же IP-адрес.

подключение к MySQL из контейнеров

режим моста

для доступа к MySQL, работающему на хосте docker из контейнеров в режим моста, вам нужно убедиться, что служба MySQL прослушивает соединения на 172.17.42.1 IP-адрес.

чтобы сделать это, убедитесь, что у вас есть либо bind-address = 172.17.42.1 или bind-address = 0.0.0.0 в вашем конфигурационном файле MySQL (my.cnf).

Если вам нужно установить переменную среды с IP-адресом шлюза, вы можете запустить следующее код в контейнере:

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

Примечание: если вы используете bind-address = 0.0.0.0 ваш сервер MySQL будет прослушивать соединения на всех сетевых интерфейсах. Это означает, что ваш сервер MySQL может быть достигнут из интернета ; убедитесь, что настроили правила брандмауэра соответственно.

примечание 2: если вы используете bind-address = 172.17.42.1 ваш сервер MySQL не будет слушать для подключения к 127.0.0.1 . Процессы, запущенные на хосте docker, которые хотели бы подключиться к MySQL, должны были бы использовать 172.17.42.1 IP-адрес.

режим хоста

для доступа к MySQL, работающему на хосте docker из контейнеров в режим хоста, вы можете сохранить bind-address = 127.0.0.1 в вашей конфигурации MySQL и все, что вам нужно сделать, это подключиться к 127.0.0.1 из ваших контейнеров:

Примечание: используйте mysql -h 127.0.0.1 и не mysql -h localhost ; в противном случае клиент MySQL попытался бы подключиться с помощью сокета unix.

для macOS и Windows

Docker v 18.03 и выше (с 21 марта 2018 года)

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

MacOS с более ранними версиями Docker

Докер для Mac v 17.12-v 18.02

то же, что и выше, но используйте docker.for.mac.host.internal вместо.

Докер для Mac v 17.06 — V 17.11

то же, что и выше, но используйте docker.for.mac.localhost вместо.

Docker для Mac 17.05 и ниже

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

sudo ifconfig lo0 alias 123.123.123.123/24

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

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

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

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

Я делаю Хак, подобный вышеуказанным сообщениям, чтобы получить локальный IP-адрес для сопоставления с псевдонимом (DNS) в контейнере. Основная проблема заключается в том, чтобы получить динамически с помощью простого скрипта, который работает как в Linux и OSX IP-адрес хоста. Я сделал этот скрипт, который работает в обеих средах (даже в Linux с «$LANG» != «en_*» настроить):

Итак, используя Docker Compose, полная конфигурация будет:

скрипт запуска (docker-run.sh):

докер-сочинять.в формате YML:

затем измените http://localhost до http://dockerhost в коде.

для более руководство о том, как настроить DOCKERHOST скрипт, взгляните на этот пост с объяснением как это работает.

это сработало для меня в стеке nginx / PHP-FPM, не касаясь кода или сети, где приложение просто ожидает возможности подключения к localhost

Mount mysqld.sock от хоста к внутри контейнера.

найдите местоположение mysql.файл носка на хосте с mysql:
netstat -ln | awk ‘/mysql(.*)?\.sock/ < print >‘

Читайте также:  Mac os не удалось отключить диск 69888

установите этот файл туда, где он ожидается в докере:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

возможные местоположения mysqld.носок:

решение для Windows 10

вы можете использовать DNS-имя хоста docker.for.win.localhost , для разрешения на внутренний IP. (Предупреждение некоторые источники упомянуты windows но он должен быть!—2—>)

обзор
Мне нужно было сделать что-то подобное, то есть подключиться из моего контейнера Docker к моему localhost, на котором был запущен Azure Storage Emulator и CosmosDB Emulator .

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

это также работает для подключения из моего контейнера Docker в SQL Server и IIS , оба работают локально на моем хосте с настройки порта по умолчанию.

для тех, кто в Windows, предполагая, что вы используете сетевой драйвер моста, вы захотите специально привязать MySQL к ip-адресу сетевого интерфейса hyper-V.

Это делается через файл конфигурации под обычно скрытым C:\ProgramData\MySQL папка.

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

Edit: я закончил прототипирование концепции на GitHub. Проверьте: https://github.com/sivabudh/system-in-a-box

во-первых, мой ответ ориентирован на 2 группы людей: те, кто использует Mac, и те, кто использует Linux.

на хоста сетевой режим не работает на Mac. Вы должны использовать псевдоним IP, см.:https://stackoverflow.com/a/43541681/2713729

во-вторых, для тех из вас, кто использует Linux (мой прямой опыт был с Ubuntu 14.04 LTS, и я скоро обновлюсь до 16.04 LTS в производстве),да, вы можете заставить службу работать внутри контейнера Docker подключиться к localhost службы, работающие на хосте Docker (например. ваш ноутбук.)

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

docker run —network=»host» -id

когда вы делаете ifconfig (вам понадобится apt-get install net-tools контейнер для ifconfig для вызова) внутри вашего контейнера вы увидите, что сетевые интерфейсы такие же, как и на хосте Docker (например. ваш ноутбук.)

важно отметить, что я пользователь Mac, но я запускаю Ubuntu под Parallels, поэтому использование Mac не является недостатком. 😉

и вот как вы подключаете контейнер NGINX к MySQL, работающему на localhost .

решение для Linux (ядро >=3.6).

Ok, ваш сервер localhost имеет интерфейс docker по умолчанию docker0 С ip-адресом 172.17.0.1. Ваш контейнер запущен с сетевыми настройками по умолчанию —net= «мост».

  1. включить route_localnet для интерфейса docker0:
    $ sysctl -w net.ipv4.conf.docker0.route_localnet=1
  2. добавить правила в iptables:
    $ iptables -t nat -I PREROUTING -i docker0 -d 172.17.0.1 -p tcp —dport 3306 -j DNAT —to 127.0.0.1:3306
    $ iptables -t filter -I INPUT -i docker0 -d 127.0.0.1 -p tcp —dport 3306 -j ACCEPT
  3. создать пользователя mysql с доступом из «%», что означает-от любого, за исключением localhost:
    CREATE USER ‘user’@’%’ IDENTIFIED BY ‘password’;
  4. измените в своем скрипте адрес mysql-сервера на 172.17.0.1

route_localnet — BOOLEAN: не рассматривайте адреса замыкания на себя в качестве марсианского источника или назначения при маршрутизации. Это позволяет использовать 127/8 для локальной маршрутизации (по умолчанию Ложные).

вот мое решение : это работает для моего случая

установите локальный сервер mysql в открытый доступ по комментарию #bind-address = 127.0.0.1 в /etc/mysql / mysql.conf.d

перезапустить сервер mysql sudo /etc/init.d/mysql restart

выполните следующую команду, чтобы открыть корневой доступ пользователя к любому хосту mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO ‘root’@’%’ IDENTIFIED BY ‘root’ WITH GRANT OPTION; FLUSH PRIVILEGES;

создать сценарий sh : run_docker.sh

запуск с докер-композитор

Я не согласен с ответом от Thomasleveil.

привязка mysql к 172.17.42.1 предотвратит другие программы, использующие базу данных на хосте, чтобы достичь ее. Это будет работать, только если все пользователи базы данных dockerized.

привязка mysql к 0.0.0.0 откроет БД для внешнего мира, что не только очень плохо, но и противоречит тому, что хочет сделать автор исходного вопроса. Он явно говорит: «MySql работает на localhost, а не подвергая порт внешнему миру, поэтому его привязывают к localhost»

чтобы ответить на комментарий от ivant

» Почему бы не привязать mysql к docker0?»

Это невозможно. Документация mysql/mariadb явно говорит, что невозможно привязать к нескольким интерфейсам. Можно выполнить привязку только к 0, 1 или ко всем интерфейсам.

Читайте также:  Todoist ��� mac os

В заключение, я не нашел никакого способа добраться до базы данных (только localhost) на хосте из контейнер докера. Это определенно кажется очень распространенной моделью, но я не знаю, как это сделать.

простейшее решение для Mac OSX

просто используйте IP-адрес вашего Mac. На Mac запустите это, чтобы получить IP-адрес и использовать его из контейнера:

пока сервер, работающий локально на вашем Mac или в другом контейнере docker, прослушивает 0.0.0.0, контейнер docker сможет связаться с этим адресом.

Если вы просто хотите получить доступ к другому контейнеру docker, который прослушивает 0.0.0.0, вы можете использовать 172.17.0.1

группы и пространства имен играют важную роль в экосистеме контейнеров.

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

вот базовые понимания подход решения можно следуй,

Использовать Сетевое Пространство Имен

когда контейнер порождает образ, определяется и создается сетевой интерфейс. Это дает контейнеру уникальный IP-адрес и интерфейс.

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

если процесс прослушивает порты, они будут слушать на интерфейс хоста и сопоставлен с контейнером.

использовать пространство имен PID Изменение пространства имен Pid позволяет контейнеру взаимодействовать с другим процессом за пределами его обычной области.

этот контейнер будет работать в собственном пространстве имен.

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

Совместное Использование Пространства Имен

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

первый контейнер-сервер nginx. Это создаст новое пространство имен network и process. Этот контейнер будет привязан к порту 80 вновь созданного сетевого интерфейса.

еще один контейнер может теперь повторно используйте это пространство имен,

кроме того, этот контейнер может видеть интерфейс с процессами в общем контейнере.

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

вы можете получить ip-адрес хоста, используя alpine image

Это было бы более последовательно, поскольку вы всегда используете alpine для запуска команды.

подобно ответу Мариано, вы можете использовать ту же команду для установки переменной среды

Для Компьютера Windows :-

выполните следующую команду, чтобы выставить порт docker случайным образом во время сборки

в приведенном выше списке контейнеров вы можете увидеть порт, назначенный как 32768. Попробуйте получить доступ

вы можете увидеть страницу mediawiki

можно использовать сайту ngrok чтобы создать безопасный туннель к вашей машине localhost, а затем подвергнуть этот туннель контейнеру docker.

сайту ngrok свободно использовать как в 05/22/2017.

2) скачать клиент ngrok и следуйте инструкциям по установке

3) ЗАРЕГИСТРИРОВАТЬСЯ для учетной записи, и они обеспечат аутентификацию знак. Регистрация требуется, потому что ngrok дает вам туннель tcp-порта только после регистрации. Для регистрации не требуется никаких затрат или кредитной карты.

4) в вашем терминале do ngrok tcp 3306 . 3306 — это порт, который mysql работает на моем локальном, вы можете сделать это с любым другим портом.

5) Вы получите адрес из шага 4 например: tcp://0.tcp.ngrok.io:10117 . Это туннельное соединение с вашей локальной машиной. 0.tcp.ngrok.io отображается на ваш localhost и порт 10117 is сопоставлено с вашим локальным портом 3306 . Теперь вы можете получить доступ к порту localhost 3306 из любого места, используя этот адрес, включая любой контейнер docker, работающий на этом компьютере. В контейнере docker(где бы он ни находился), предполагая, что у вас уже установлен клиент mysql, сделайте следующее:

mysql —host 0.tcp.ngrok.io —port 10117 -u root

вы сможете войти в свой root учетная запись вашей локальной машины изнутри контейнера docker!

я написал об этом решении подробнее подробности здесь

Источник

Оцените статью