Edycja: Jeśli używasz Docker-for-mac lub Docker-for-Windows 18.03+, po prostu połącz się z usługą mysql za pomocą hosta host.docker.internal
(zamiast 127.0.0.1
w ciągu połączenia).
Począwszy od Docker 18.09.3, nie działa to w Docker-for-Linux. Fix został złożony w dniu 8 marca 2019 i mam nadzieję, że zostaną połączone z bazą kodu. Do tego czasu obejściem problemu jest użycie kontenera zgodnie z opisem w odpowiedzi qoomon .
2020-01: poczyniono pewne postępy . Jeśli wszystko pójdzie dobrze, powinno to wylądować w Docker 20.04
TLDR
Użyj --network="host"
w swoim docker run
poleceniu, a następnie 127.0.0.1
w kontenerze dokera wskaże hosta dokera.
Uwaga: Ten tryb działa tylko w systemie Docker dla systemu Linux, zgodnie z dokumentacją .
Uwaga na temat trybów pracy sieci kontenerów dokujących
Docker oferuje różne tryby sieci podczas uruchamiania kontenerów. W zależności od wybranego trybu połączenie z bazą danych MySQL działającą na hoście dokera będzie różne.
Uruchom okno dokowane --network = „most” (domyślnie)
Docker tworzy docker0
domyślnie nazwany most . Zarówno host dokera, jak i kontenery dokują mają adres IP na tym moście.
na hoście Docker wpisz sudo ip addr show docker0
wynik wyglądający następująco:
[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
Więc tutaj mój host dokera ma adres IP 172.17.42.1
w docker0
interfejsie sieciowym.
Teraz uruchom nowy kontener i uzyskaj na nim powłokę: docker run --rm -it ubuntu:trusty bash
i w obrębie typu kontenera, ip addr show eth0
aby dowiedzieć się, jak jest skonfigurowany jego główny interfejs sieciowy:
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
Tutaj mój kontener ma adres IP 172.17.1.192
. Teraz spójrz na tabelę routingu:
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
Dlatego adres IP hosta dokera 172.17.42.1
jest ustawiony jako domyślna trasa i jest dostępny z kontenera.
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
Uruchom okno dokowane --network = "host"
Alternatywnie możesz uruchomić kontener dokerów z ustawieniami sieci ustawionymi nahost
. Taki kontener będzie dzielić stos sieciowy z hostem dokera iz punktu widzenia kontenera localhost
(lub 127.0.0.1
) będzie odnosił się do hosta dokera.
Należy pamiętać, że każdy port otwarty w kontenerze dokera zostanie otwarty na hoście dokera. I to bez wymagania opcji -p
lub-P
docker run
.
Konfiguracja IP na moim hoście dokera:
[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
oraz z kontenera dokowanego w trybie hosta :
[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
Jak widać, zarówno host dokera, jak i kontener dokerów mają ten sam interfejs sieciowy i jako taki mają ten sam adres IP.
Łączenie się z MySQL z kontenerów
tryb pomostowy
Aby uzyskać dostęp do MySQL uruchomionego na hoście dokera z kontenerów w trybie mostu , musisz upewnić się, że usługa MySQL nasłuchuje połączeń na 172.17.42.1
adresie IP.
Aby to zrobić, upewnij się, że masz albo bind-address = 172.17.42.1
czy bind-address = 0.0.0.0
w pliku konfiguracyjnym MySQL (my.cnf).
Jeśli musisz ustawić zmienną środowiskową z adresem IP bramy, możesz uruchomić następujący kod w kontenerze:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
następnie w aplikacji użyj DOCKER_HOST_IP
zmiennej środowiskowej, aby otworzyć połączenie z MySQL.
Uwaga: jeśli używasz bind-address = 0.0.0.0
serwera MySQL, nasłuchuje połączeń na wszystkich interfejsach sieciowych. Oznacza to, że do twojego serwera MySQL można uzyskać dostęp z Internetu; upewnij się, że odpowiednio skonfigurowałeś reguły zapory.
Uwaga 2: jeśli korzystasz bind-address = 172.17.42.1
z serwera MySQL, nie będziesz nasłuchiwał nawiązywania połączeń 127.0.0.1
. Procesy uruchomione na hoście dokera, które chciałyby połączyć się z MySQL, musiałyby korzystać z 172.17.42.1
adresu IP.
tryb hosta
Aby uzyskać dostęp do MySQL uruchomionego na hoście dokera z kontenerów w trybie hosta , możesz zachować bind-address = 127.0.0.1
konfigurację MySQL, a wszystko, co musisz zrobić, to połączyć się 127.0.0.1
z kontenerów:
[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>
Uwaga: używaj mysql -h 127.0.0.1
i nie mysql -h localhost
; w przeciwnym razie klient MySQL próbowałby połączyć się przy użyciu gniazda unix.