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


Answers

Для MacOS и Windows

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

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

Поддержка Linux в ожидании https://github.com/docker/for-linux/issues/264

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

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

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

Докер для Mac с 17.06 по 17.11

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

Докер для 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 .

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

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

Question

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

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




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

Хорошо, ваш сервер localhost имеет интерфейс docker0 для док-станции с ip-адресом 172.17.0.1 . Ваш контейнер запущен с сетевыми настройками по умолчанию --net = "bridge" .

  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 для локальной маршрутизации (по умолчанию FALSE ).




Вот мое решение: оно работает для моего дела

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

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

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

  • создать sh-скрипт: run_docker.sh

    #!bin/bash

    HOSTIP=`ip -4 addr show scope global dev eth0 | grep inet | awk '{print \$2}' | cut -d / -f 1`


      docker run -it -d --name web-app \
                  --add-host=local:${HOSTIP} \
                  -p 8080:8080 \
                  -e DATABASE_HOST=${HOSTIP} \
                  -e DATABASE_PORT=3306 \
                  -e DATABASE_NAME=demo \
                  -e DATABASE_USER=root \
                  -e DATABASE_PASSWORD=root \
                  sopheamak/springboot_docker_mysql

  
  • работать с докер-композитором

    version: '2.1'
    
    

    services:
    tomcatwar: extra_hosts: - "local:10.1.2.232" image: sopheamak/springboot_docker_mysql
    ports: - 8080:8080 environment: - DATABASE_HOST=local - DATABASE_USER=root - DATABASE_PASSWORD=root - DATABASE_NAME=demo - DATABASE_PORT=3306




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

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

Найдите местоположение файла mysql.sock на хосте, на котором запущен mysql:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

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

Возможные расположения mysqld.sock:
/tmp/mysqld.sock /var/run/mysqld/mysqld.sock /var/lib/mysql/mysql.sock




Edit: Я закончил разработку прототипов концепции GitHub. Выезд: https://github.com/sivabudh/system-in-a-box

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

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

Что такое режим сетевой сети? См. https://docs.docker.com/engine/reference/run/#/network-settings

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

Как?

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

docker run --network="host" -id <Docker image ID>

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

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

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




Самое простое решение для Mac OSX

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

$ ifconfig | grep 'inet 192'| awk '{ print $2}'

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

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




Related