Изменить: Если вы используете Docker-для-Mac или Docker-для-Windows 18.03+, просто подключитесь к службе MySQL с помощью хоста host.docker.internal
(вместо 127.0.0.1
в строке подключения).
Начиная с Docker 18.09.3, это не работает в Docker-для-Linux. Исправление было представлено на 8 марта, 2019 и мы надеемся , будут объединены в базу кода. До тех пор, обходной путь должен использовать контейнер, как описано в ответе Qoomon .
2020-01: некоторый прогресс был достигнут. Если все идет хорошо, это должно приземлиться в Docker 20.04
TLDR
Используйте --network="host"
в вашей docker run
команде, тогда 127.0.0.1
в вашем док-контейнере будет указывать на ваш докер хост.
Примечание. Этот режим работает только в Docker для Linux согласно документации .
Обратите внимание на режимы работы с сетью Docker-контейнеров
Docker предлагает различные сетевые режимы при запуске контейнеров. В зависимости от выбранного вами режима, вы будете подключаться к базе данных MySQL, работающей на хосте докера, по-разному.
Docker run --network = "bridge" (по умолчанию)
Docker создает мост с именем docker0
по умолчанию. И хост-докер, и контейнеры-докеры имеют IP-адрес на этом мосту.
на хосте Docker напечатайте, у sudo ip addr show docker0
вас будет вывод, похожий на:
[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::5484:7aff:fefe:9799/64 scope link
valid_lft forever preferred_lft forever
Итак, у моего докера есть IP-адрес 172.17.42.1
на docker0
сетевом интерфейсе.
Теперь запустите новый контейнер и создайте для него оболочку: docker run --rm -it ubuntu:trusty bash
и внутри типа контейнера, ip addr show eth0
чтобы узнать, как настроен его основной сетевой интерфейс:
root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
inet 172.17.1.192/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
valid_lft forever preferred_lft forever
Здесь мой контейнер имеет IP-адрес 172.17.1.192
. Теперь посмотрите на таблицу маршрутизации:
root@e77f6a1b3740:/# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.42.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 * 255.255.0.0 U 0 0 0 eth0
Таким образом, IP-адрес узла докера 172.17.42.1
устанавливается в качестве маршрута по умолчанию и доступен из вашего контейнера.
root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms
Docker run --network = "host"
В качестве альтернативы вы можете запустить Docker-контейнер с сетевыми настройками, установленными вhost
. Такой контейнер будет совместно использовать сетевой стек с хостом докера и с точки зрения контейнера localhost
(или 127.0.0.1
) будет ссылаться на хост докера.
Помните, что любой порт, открытый в вашем контейнере докера, будет открыт на хосте докера. И это без необходимости -p
или -P
docker run
вариант .
Конфигурация IP на моем хосте докера:
[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
и из док-контейнера в режиме хоста :
[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
Как вы можете видеть, и хост-докер, и контейнер-докер используют один и тот же сетевой интерфейс и имеют одинаковый IP-адрес.
Подключение к MySQL из контейнеров
режим моста
Чтобы получить доступ к MySQL, работающему на хосте докера, из контейнеров в режиме моста , необходимо убедиться, что служба MySQL прослушивает соединения по 172.17.42.1
IP-адресу.
Для этого убедитесь, что у вас есть либо один, bind-address = 172.17.42.1
либо bind-address = 0.0.0.0
ваш конфигурационный файл MySQL (my.cnf).
Если вам нужно установить переменную среды с IP-адресом шлюза, вы можете запустить следующий код в контейнере:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
затем в вашем приложении используйте DOCKER_HOST_IP
переменную окружения, чтобы открыть соединение с MySQL.
Примечание: если вы используете bind-address = 0.0.0.0
сервер MySQL, вы будете прослушивать соединения на всех сетевых интерфейсах. Это означает, что ваш сервер MySQL может быть доступен из Интернета; убедитесь, что настроили правила брандмауэра соответственно.
Примечание 2: если вы используете bind-address = 172.17.42.1
ваш сервер MySQL, он не будет прослушивать сделанные подключения 127.0.0.1
. Процессы, работающие на док-хосте, который хочет подключиться к MySQL, должны будут использовать 172.17.42.1
IP-адрес.
режим хоста
Чтобы получить доступ к MySQL, работающему на хосте докера, из контейнеров в режиме хоста , вы можете сохранить bind-address = 127.0.0.1
свою конфигурацию MySQL, и все, что вам нужно сделать, это подключиться к ним 127.0.0.1
из ваших контейнеров:
[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
примечание: используйте mysql -h 127.0.0.1
и не используйте mysql -h localhost
; в противном случае клиент MySQL будет пытаться подключиться через сокет unix.