J'ai donc un Nginx qui s'exécute dans un conteneur docker, j'ai un mysql qui s'exécute sur localhost, je veux me connecter à MySql depuis mon Nginx. Le MySql s'exécute sur localhost et n'expose pas un port au monde extérieur, donc il est lié à localhost, pas lié à l'adresse IP de la machine.
Existe-t-il un moyen de se connecter à ce MySql ou à tout autre programme sur localhost à partir de ce conteneur docker ?
Cette question est différente de "Comment obtenir l'adresse IP de l'hôte Docker à partir d'un conteneur Docker" en raison du fait que l'adresse IP de l'hôte Docker peut être l'adresse IP publique ou l'adresse IP privée du réseau qui peut ou peut ne pas être accessible depuis le conteneur Docker (je veux dire une adresse IP publique si elle est hébergée chez AWS ou quelque chose comme ça). Même si vous avez l'adresse IP de l'hôte Docker, cela ne signifie pas que vous pouvez vous connecter à l'hôte Docker depuis le conteneur étant donné que l'adresse IP car votre réseau Docker peut être superposé, hôte, pont, macvlan, aucun, etc., ce qui limite l'accessibilité de cette adresse IP.
Solution du problème
Modifier:
Si vous utilisez Docker-for-mac ou Docker-for-Windows 18.03+, connectez-vous simplement à votre service mysql en utilisant l'hôte host.docker.internal
(au lieu de 127.0.0.1
dans votre chaîne de connexion).
Si vous utilisez Docker-for-Linux 20.10.0+, vous pouvez également utiliser l'hôte host.docker.internal
si vous avez démarré votre conteneur Docker avec l' --add-host host.docker.internal:host-gateway
option.
Sinon, lisez ci-dessous
TLDR
Utilisez --network="host"
dans votre docker run
commande, puis 127.0.0.1
dans votre conteneur docker pointera vers votre hôte docker.
Remarque : Ce mode ne fonctionne que sur Docker pour Linux, conformément à la documentation.
Remarque sur les modes de mise en réseau du conteneur DockerDocker propose différents modes de mise en réseau lors de l'exécution de conteneurs. Selon le mode que vous choisissez, vous vous connecterez différemment à votre base de données MySQL exécutée sur l'hôte Docker.
docker run --network="bridge" (par défaut)
Docker crée un pont nommé docker0
par défaut. L'hôte Docker et les conteneurs Docker ont tous deux une adresse IP sur ce pont.
sur l'hôte Docker, tapez sudo ip addr show docker0
vous aurez une sortie ressemblant à :
[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
Donc, ici, mon hôte docker a l'adresse IP 172.17.42.1
sur l' docker0
interface réseau.
Démarrez maintenant un nouveau conteneur et obtenez un shell dessus : docker run --rm -it ubuntu:trusty bash
et dans le type de conteneur ip addr show eth0
pour découvrir comment son interface réseau principale est configurée :
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
Ici, mon conteneur a l'adresse IP 172.17.1.192
. Regardez maintenant la table de routage :
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
Ainsi, l'adresse IP de l'hôte Docker 172.17.42.1
est définie comme route par défaut et est accessible depuis votre conteneur.
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"
Vous pouvez également exécuter un conteneur Docker avec les paramètres réseau définis surhost
. Un tel conteneur partagera la pile réseau avec l'hôte docker et du point de vue du conteneur, localhost
(ou 127.0.0.1
) fera référence à l'hôte docker.
Sachez que tout port ouvert dans votre conteneur Docker sera ouvert sur l'hôte Docker. Et ceci sans nécessiter l' option -p
ou-P
docker run
.
Configuration IP sur mon hôte docker :
[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
et depuis un conteneur docker en mode hôte :
[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
Comme vous pouvez le voir, l'hôte Docker et le conteneur Docker partagent exactement la même interface réseau et ont donc la même adresse IP.
Connexion à MySQL à partir de conteneursmode pont
Pour accéder à MySQL exécuté sur l'hôte docker à partir de conteneurs en mode pont, vous devez vous assurer que le service MySQL écoute les connexions sur l' 172.17.42.1
adresse IP.
Pour ce faire, assurez-vous d'avoir bind-address = 172.17.42.1
ou bind-address = 0.0.0.0
dans votre fichier de configuration MySQL (my.cnf).
Si vous avez besoin de définir une variable d'environnement avec l'adresse IP de la passerelle, vous pouvez exécuter le code suivant dans un conteneur:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
puis dans votre application, utilisez la DOCKER_HOST_IP
variable d'environnement pour ouvrir la connexion à MySQL.
Remarque: si vous utilisez bind-address = 0.0.0.0
votre serveur MySQL, il écoutera les connexions sur toutes les interfaces réseau. Cela signifie que votre serveur MySQL est accessible depuis Internet; assurez-vous de configurer les règles de pare-feu en conséquence.
Remarque 2 : si vous utilisez bind-address = 172.17.42.1
votre serveur MySQL, il n'écoutera pas les connexions établies avec 127.0.0.1
. Les processus s'exécutant sur l'hôte docker qui voudraient se connecter à MySQL devraient utiliser l' 172.17.42.1
adresse IP.
mode hôte
Pour accéder à MySQL en cours d'exécution sur l'hôte docker à partir de conteneurs en mode hôte, vous pouvez conserver bind-address = 127.0.0.1
votre configuration MySQL et tout ce que vous avez à faire est de vous connecter à 127.0.0.1
partir de vos conteneurs :
[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>
note: utilisez mysql -h 127.0.0.1
et non mysql -h localhost
; sinon le client MySQL essaierait de se connecter en utilisant un socket unix.
Aucun commentaire:
Enregistrer un commentaire