GOOGLE ADS

vendredi 29 avril 2022

Depuis l'intérieur d'un conteneur Docker, comment puis-je me connecter à l'hôte local de la machine ?

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.1dans 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-gatewayoption.

Sinon, lisez ci-dessous

TLDR

Utilisez --network="host"dans votre docker runcommande, puis 127.0.0.1dans 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 Docker

Docker 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é docker0par 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 docker0vous 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.1sur l' docker0interface réseau.

Démarrez maintenant un nouveau conteneur et obtenez un shell dessus : docker run --rm -it ubuntu:trusty bashet dans le type de conteneur ip addr show eth0pour 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.1est 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 -pou-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 conteneurs

mode 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.1adresse IP.

Pour ce faire, assurez-vous d'avoir bind-address = 172.17.42.1ou bind-address = 0.0.0.0dans 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_IPvariable d'environnement pour ouvrir la connexion à MySQL.

Remarque: si vous utilisez bind-address = 0.0.0.0votre 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.1votre 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.1adresse 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.1votre configuration MySQL et tout ce que vous avez à faire est de vous connecter à 127.0.0.1partir 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.1et non mysql -h localhost; sinon le client MySQL essaierait de se connecter en utilisant un socket unix.

Aucun commentaire:

Enregistrer un commentaire

Comment utiliseriez-vous .reduce() sur des arguments au lieu d'un tableau ou d'un objet spécifique&nbsp;?

Je veux définir une fonction.flatten qui aplatit plusieurs éléments en un seul tableau. Je sais que ce qui suit n'est pas possible, mais...