Taigi aš turiu Nginx veikia viduje docker konteinerio, Aš turiu mysql veikia localhost, Noriu prisijungti prie MySql iš mano Nginx. MySql veikia localhost ir neatskleidžia prievado išoriniam pasauliui, todėl jis yra susietas su localhost, o ne su mašinos ip adresu.
Ar yra koks nors būdas prisijungti prie šios MySql ar bet kurios kitos programos, esančios localhost, iš šio docker konteinerio?
Šis klausimas skiriasi nuo klausimo "Kaip gauti "docker" prieglobos kompiuterio IP adresą iš "docker" konteinerio vidaus" dėl to, kad "docker" prieglobos kompiuterio IP adresas gali būti viešasis IP arba privatus tinklo IP, kuris gali būti pasiekiamas arba nepasiekiamas iš "docker" konteinerio (turiu omenyje viešąjį IP, jei jis yra AWS ar pan.). Net jei turite "Docker Host" IP adresą, tai nereiškia, kad galite prisijungti prie "Docker Host" iš konteinerio, kuriame yra šis IP adresas, nes jūsų "Docker" tinklas gali būti perdangos, kompiuterio, tilto, "Macvlan", jokio ir t. t., o tai riboja šio IP adreso pasiekiamumą.
Redaguoti: Jei naudojate Docker-for-mac arba Docker-for-Windows 18.03+, tiesiog prisijunkite prie savo mysql paslaugos naudodami host host.docker.internal
.
Nuo "Docker 18.09.3" tai neveikia "Docker-for-Linux ". 2019 m. kovo 8 d. buvo pateikta pataisa, kuri, tikimės, bus įtraukta į kodo bazę. Iki to laiko galima apeiti šią problemą naudojant konteinerį, kaip aprašyta qoomon'o atsakyme.
Naudokite --network="host"
savo docker run
komandoje, tada 127.0.0.0.1
jūsų "docker" konteineryje nurodys į jūsų "docker" kompiuterį.
Pastaba: šis režimas veikia tik "Docker for Linux" pagal dokumentaciją.
Vykdant konteinerius "Docker" siūlo skirtingus tinklo režimus. Priklausomai nuo pasirinkto režimo, prie MySQL duomenų bazės, veikiančios dockerio prieglobstyje, jungtumėtės skirtingai.
Pagal numatytuosius nustatymus "Docker" sukuria tiltą, pavadintą docker0
. Tiek "docker" kompiuterio kompiuteris, tiek "docker" konteineriai turi šio tilto IP adresą.
"Docker" prieglobstyje įveskite sudo ip addr show docker0
ir gausite išvestį, atrodančią taip:
[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
Taigi, čia mano "docker" kompiuterio tinklo sąsajoje docker0
yra IP adresas 172.17.42.1
.
Dabar paleiskite naują konteinerį ir įjunkite jame apvalkalą: Įveskite docker run --rm -it ubuntu:trusty bash
ir konteinerio viduje įveskite ip addr show eth0
, kad sužinotumėte, kaip nustatyta jo pagrindinė tinklo sąsaja:
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
Čia mano konteineris turi IP adresą 172.17.1.192
. Dabar pažvelkite į maršrutizavimo lentelę:
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
Taigi, "docker" prieglobsčio IP adresas 172.17.42.1
yra nustatytas kaip numatytasis maršrutas ir yra pasiekiamas iš jūsų konteinerio.
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
Arba galite paleisti "docker" konteinerį su [tinklo nustatymai nustatyti į host
] (http://docs.docker.com/engine/reference/run/#network-host). Toks konteineris dalysis tinklo steką su "docker host" kompiuteriu ir konteinerio požiūriu localhost
(arba 127.0.0.0.1
) reikš "docker host" kompiuterį.
Turėkite omenyje, kad bet koks jūsų "docker" konteineryje atidarytas prievadas bus atidarytas ir "docker" prieglobstyje. Ir tai nereikalaujant `-p
arba -P
docker run
parinkties.
IP konfigūracija mano "docker" prieglobstyje:
[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
ir iš "docker" konteinerio globėjo režimu:
[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
Kaip matote, tiek "docker host", tiek "docker" konteineris naudojasi ta pačia tinklo sąsaja ir turi tą patį IP adresą.
Norėdami pasiekti "MySQL", veikiančią "docker" prieglobstyje, iš konteinerių tilto režimu, turite įsitikinti, kad "MySQL" paslauga klausosi prisijungimų IP adresu 172.17.42.1
.
Tam įsitikinkite, kad "MySQL" konfigūracijos faile (my.cnf) įrašėte bind-address = 172.17.42.1
arba bind-address = 0.0.0.0
.
Jei reikia nustatyti aplinkos kintamąjį su vartų IP adresu, galite paleisti šį kodą konteineryje :
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
tada savo programoje naudokite DOCKER_HOST_IP
aplinkos kintamąjį, kad atidarytumėte ryšį su "MySQL".
Pastaba: jei naudosite bind-address = 0.0.0.0.0
, jūsų "MySQL" serveris klausysis prisijungimų visose tinklo sąsajose. Tai reiškia, kad jūsų "MySQL" serveris gali būti pasiekiamas iš interneto; būtinai atitinkamai nustatykite ugniasienės taisykles.
2 pastaba: jei naudosite bind-address = 172.17.42.1
, jūsų "MySQL" serveris neklausys prisijungimų prie 127.0.0.0.1
. Procesai, veikiantys dockerio prieglobstyje ir norintys prisijungti prie MySQL, turės naudoti 172.17.42.1
IP adresą.
Norėdami pasiekti "MySQL", veikiančią "docker" prieglobstyje, iš konteinerių, veikiančių šeimininko režimu, "MySQL" konfigūracijoje galite palikti bind-address = 127.0.0.0.1
ir viskas, ką jums reikia padaryti, tai prisijungti prie 127.0.0.0.1
iš savo konteinerių:
[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>
Pastaba: Naudokite mysql -h 127.0.0.0.1
, o ne mysql -h localhost
; priešingu atveju "MySQL" klientas bandys prisijungti naudodamas unix lizdą.
Tai dirbo man NGINX/PHP-FPM kamino neliečiant jokio kodo ar tinklo, kur app's tiesiog tikisi, kad bus galima prisijungti prie localhost
.
Prijungti mysqld.sock
iš kompiuterio į konteinerio vidų.
Suraskite mysql.sock failo vietą kompiuteryje, kuriame veikia mysql:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'
Prijunkite šį failą ten, kur jo tikimasi "Docker" programoje:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock
Galimos mysqld.sock vietos:
/tmp/mysqld.sock
/var/run/mysqld/mysqld.sock
/var/lib/mysql/mysql.sock
/Applications/MAMP/tmp/mysql/mysql.sock # if running via MAMP
Nesutinku su Thomasleveil atsakymu.
Jei mysql susiesite su 172.17.42.1, neleisite kitoms programoms, naudojančioms kompiuterio duomenų bazę, jos pasiekti. Tai veiks tik tuo atveju, jei visi jūsų duomenų bazės naudotojai yra dockerizuoti.
Jei mysql susiesite su 0.0.0.0.0, db bus atvira išoriniam pasauliui, o tai ne tik labai blogai, bet ir prieštarauja pirminio klausimo autoriaus siekiamam tikslui. Jis aiškiai sako "MySql veikia localhost ir neatskleidžia prievado išoriniam pasauliui, todėl ji susieta su localhost"
Atsakydamas į ivant komentarą
" "Kodėl nesusieti mysql ir su docker0?"
Tai neįmanoma. Mysql/mariadb dokumentacijoje aiškiai sakoma, kad neįmanoma susieti su keliomis sąsajomis. Galima susieti tik su 0, 1 arba visomis sąsajomis.
Apibendrinant galima teigti, kad NENURODŽIAU jokio būdo, kaip iš "Docker" konteinerio pasiekti kompiuterio (tik "localhost") duomenų bazę. Tai tikrai atrodo kaip labai labai dažnas modelis, bet aš nežinau, kaip tai padaryti.