Kako se lahko znotraj vsebnika Docker povežem z lokalnim gostiteljem računalnika?
Torej imam Nginx teče znotraj docker posodo, Imam mysql teče na localhost, Želim se povezati z MySql iz mojega Nginx. MySql teče na lokalnem gostitelju in ne izpostavlja vrat zunanjemu svetu, zato je vezan na lokalni gostitelj in ne na naslov IP računalnika.
Ali obstaja kakršen koli način za povezavo s tem MySql ali katerim koli drugim programom na lokalnem gostitelju iz tega vsebnika docker?
To vprašanje se razlikuje od vprašanja "Kako dobiti naslov IP gostitelja dockerja znotraj vsebnika dockerja" zaradi dejstva, da je naslov IP gostitelja dockerja lahko javni IP ali zasebni IP v omrežju, ki je lahko dosegljiv iz vsebnika dockerja ali ne (mislim na javni IP, če gostuje v AWS ali kaj podobnega). Tudi če imate naslov IP gostitelja dockerja, to še ne pomeni, da se lahko na ta naslov IP povežete z gostiteljem dockerja znotraj vsebnika, saj je vaše omrežje dockerja lahko prekrivno, gostiteljsko, mostovno, macvlan, ni ga itd., kar omejuje dosegljivost tega naslova IP.
Urejanje: Če uporabljate Docker-for-mac ali Docker-for-Windows 18.03+, se povežite s storitvijo mysql z gostiteljem
host.docker.internal
.Od različice Docker 18.09.3 to ne deluje v storitvi Docker-for-Linux. Popravek je bil predložen 8. marca 2019 in upamo, da bo vključen v zbirko kode. Do takrat lahko to obidemo z uporabo vsebnika, kot je opisano v qoomonovem odgovoru.
TLDR
V ukazu
docker run
uporabite--network="host"
, potem bo127.0.0.1
v vašem vsebniku docker kazalo na vaš gostitelj docker.Opomba: Ta način deluje samo v programu Docker za Linux v skladu z dokumentacijo.
Opomba o omrežnih načinih vsebnika Docker
Docker ponuja različne načine omrežnega delovanja pri izvajanju vsebnikov. Glede na izbrani način se boste različno povezali s podatkovno zbirko MySQL, ki teče na gostitelju dockerja.
docker run --network="bridge" (privzeto)
Docker privzeto ustvari most z imenom
docker0
. Tako gostitelj docker kot vsebniki docker imajo naslov IP na tem mostu.če na gostitelju Docker vnesete
sudo ip addr show docker0
, boste dobili izpis, ki bo videti takole:Moj gostitelj docker ima torej naslov IP
172.17.42.1
na omrežnem vmesnikudocker0
.Zdaj zaženite nov zabojnik in v njem odprite lupino: V zabojniku vtipkajte
ip addr show eth0
in ugotovite, kako je nastavljen njegov glavni omrežni vmesnik:Tu ima moj vsebnik naslov IP
172.17.1.192
. Zdaj si oglejte usmerjevalno tabelo:Torej je naslov IP gostitelja dockerja
172.17.42.1
nastavljen kot privzeta pot in je dostopen iz vašega vsebnika.docker run --network="host"
Alternativno lahko zaženete vsebnik docker z [nastavitvami omrežja, nastavljenimi na
host
] (http://docs.docker.com/engine/reference/run/#network-host). Tak zabojnik si bo delil omrežni niz z gostiteljem dockerja in z vidika zabojnika se bolocalhost
(ali127.0.0.1
) nanašal na gostitelja dockerja.Zavedajte se, da bodo vsa vrata, odprta v vsebniku docker, odprta tudi v gostitelju docker. In to brez uporabe možnosti
p
ali-P
docker run
.Konfiguracija IP na mojem gostitelju docker:
in iz vsebnika docker v načinu host:
Kot lahko vidite, imata tako gostitelj docker kot vsebnik docker isti omrežni vmesnik in zato tudi isti naslov IP.
Povezovanje s strežnikom MySQL iz vsebnikov
način mostu
Za dostop do MySQL, ki teče na gostitelju docker, iz zabojnikov v načinu most morate zagotoviti, da storitev MySQL posluša povezave na IP naslovu
172.17.42.1
.To storite tako, da v konfiguracijski datoteki MySQL (my.cnf) določite
bind-address = 172.17.42.1
alibind-address = 0.0.0.0
.Če morate nastaviti okoljsko spremenljivko z naslovom IP prehoda, lahko v vsebniku zaženete naslednjo kodo :
nato v svoji aplikaciji uporabite okoljsko spremenljivko
DOCKER_HOST_IP
za odprtje povezave s sistemom MySQL.Note: če uporabite
bind-address = 0.0.0.0
, bo strežnik MySQL poslušal za povezave na vseh omrežnih vmesnikih. To pomeni, da je vaš strežnik MySQL lahko dosegljiv iz interneta; poskrbite, da ustrezno nastavite pravila požarnega zidu.Opomba 2: če uporabite
bind-address = 172.17.42.1
, vaš strežnik MySQL ne bo poslušal povezav, vzpostavljenih na127.0.0.1
. Procesi, ki tečejo na gostitelju dockerja in bi se želeli povezati z MySQL, bi morali uporabiti naslov IP172.17.42.1
.način gostitelja
Če želite do MySQL, ki teče na gostitelju docker, dostopati iz zabojnikov v načinu gostitelja, lahko v konfiguraciji MySQL ohranite
bind-address = 127.0.0.1
in vse, kar morate storiti, je, da se iz svojih zabojnikov povežete na127.0.0.1
:opomba: Uporabite
mysql -h 127.0.0.1
in nemysql -h localhost
; sicer bi se odjemalec MySQL poskušal povezati prek vtičnice Unix.To mi je delovalo na kupu NGINX/PHP-FPM, ne da bi se dotaknil kakršne koli kode ali omrežja, kjer aplikacija pričakuje, da se bo lahko povezala z
localhost
.Namestite
mysqld.sock
z gostitelja v vsebnik.Poiščite lokacijo datoteke mysql.sock na gostitelju, kjer teče mysql:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'
Namestite to datoteko na mesto, ki ga pričakuje docker:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock
Možne lokacije datoteke mysqld.sock:
Ne strinjam se z odgovorom Thomasleveila.
Če bo mysql vezan na 172.17.42.1, bo drugim programom, ki uporabljajo podatkovno zbirko v gostitelju, preprečil dostop do nje. To bo delovalo le, če so vsi uporabniki vaše zbirke podatkov povezani z dockerjem.
Če bo mysql vezan na 0.0.0.0.0, bo odprl db zunanjemu svetu, kar ni samo zelo slabo, ampak tudi v nasprotju s tem, kar želi narediti avtor prvotnega vprašanja. Izrecno pravi "MySql teče na localhostu in ne izpostavlja vrat zunanjemu svetu, zato je vezan na localhost"
Odgovor na komentar ivanta
To ni mogoče. V dokumentaciji za mysql/mariadb je izrecno navedeno, da vezava na več vmesnikov ni mogoča. Povezati se lahko samo na 0, 1 ali vse vmesnike.
Za zaključek naj povem, da NISEM našel nobenega načina, da bi iz vsebnika docker dosegel podatkovno zbirko (samo lokalni gostitelj) v gostitelju. To se vsekakor zdi zelo zelo pogost vzorec, vendar ne vem, kako to storiti.