Accéder à la base de données hôte à partir d'un conteneur Docker

131

Si j'ai une base de données mysql en cours d'exécution sur une machine hôte et que cet hôte exécute également un conteneur docker: Comment accéder à la base de données mysql à partir du conteneur docker qui s'exécute sur l'hôte?.

Par exemple, existe-t-il un moyen de publier un port d'hôtes dans le conteneur (l'inverse de ce que fait docker run -p)?

Ryan Anderson
la source
1
Si le serveur MySQL écoute sur un port, le conteneur ne pourrait-il pas simplement se connecter à l'hôte sur ce port comme n'importe quelle autre connexion Internet?
jwodder

Réponses:

87

Il y a plusieurs discussions de longue date sur la façon de le faire de manière cohérente, bien comprise et portable. Pas de résolution complète mais je vais vous connecter aux discussions ci-dessous.

Dans tous les cas, vous voudrez souvent essayer d'utiliser l'option --add-host pour docker run pour ajouter l'adresse IP de l'hôte dans le fichier / etc / host du conteneur. À partir de là, il est facile de se connecter à l'hôte sur n'importe quel port requis:

Ajout d'entrées à un fichier d'hôtes de conteneur

Vous pouvez ajouter d'autres hôtes dans le fichier / etc / hosts d'un conteneur en utilisant un ou plusieurs indicateurs --add-host. Cet exemple ajoute une adresse statique pour un hôte nommé docker:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

Remarque: Parfois, vous devez vous connecter à l'hôte Docker, ce qui signifie obtenir l'adresse IP de l'hôte. Vous pouvez utiliser les commandes shell suivantes pour simplifier ce processus:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

Documentation:

https://docs.docker.com/engine/reference/commandline/run/

Discussions sur l'accès à l'hôte à partir du conteneur:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023

John Petrone
la source
Fonctionnera-t-il également derrière un proxy inverse NGINX?
kta le
89

À partir de la documentation du 18.03:

Je souhaite me connecter d'un conteneur à un service sur l'hôte

L'hôte a une adresse IP changeante (ou aucune si vous n'avez pas d'accès au réseau). À partir du 18.03, nous vous recommandons de vous connecter au nom DNS spécial host.docker.internal, qui correspond à l'adresse IP interne utilisée par l'hôte.

La passerelle est également accessible en tant que gateway.docker.internal.

EXEMPLE: voici ce que j'utilise pour ma chaîne de connexion MySQL dans mon conteneur pour accéder à l'instance MySQL sur mon hôte:

mysql://host.docker.internal:3306/my_awesome_database
Kevin Chen
la source
31
Juste comme indice: cela ne fonctionne que pour Mac et Win jusqu'à présent
flp
vous avez sauvé ma journée :)
amjad
4
Vote positif. Pas seulement à cause de la réponse, mais parce que vous devriez COMMENT l'utiliser avec un exemple.
granadaCoder
J'ai presque passé 2 heures pour y parvenir, merci beaucoup.
Ashish Bainade
Toujours pas de support linux comme l'a écrit @flp, pour les curieux. Voici le problème de github .
GAltelino
24

Utilisez host.docker.internal à partir de Docker 18.03.

Igor De Oliveira Sá
la source
2
Comment ? pouvez-vous donner un exemple de son utilisation?
danfromisrael
Pourquoi ne pas exécuter un mysql dockerisé?
Igor De Oliveira Sá
ne fonctionne pas pour moi àDocker version 18.03.0-ce, build 0520e24
scythargon
@ IgorDeOliveiraSá imaginez le scénario suivant, sur l'environnement de développement, vous avez une base de données qui écoute 127.0.0.1:3306 sur l'environnement de production, vous avez une base de données qui écoute 127.0.0.1:3306, localement c'est la base de données locale, la production c'est un proxy vers le cloud, vous devez soit dockerise mysql localement et pour la production, trouvez une autre solution, ou vous pouvez simplement vous connecter de docker à port, cela fonctionnera dans les deux cas
Drachenfels
1
docker.for.mac.localhost fonctionne pour moi sur18.03.1-ce-mac65
cdignam
21

D'autres réponses n'ont pas bien fonctionné pour moi. Mon conteneur n'a pas pu résoudre l' adresse IP de l'hôte à l'aide de host.docker.internal . Il y a deux façons

  1. Partage du réseau hôte --net = hôte:

    docker run -it --net=host  myimage
    
  2. En utilisant l'adresse IP de docker, qui est généralement 172.17.0.1 . Vous pouvez le vérifier en appelant la commande ifconfig et en saisissant inet addr de l'interface docker

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

Une fois que vous avez cette adresse IP, vous pouvez la passer comme argument à docker run puis à l'application ou comme je le fais, mapper l'emplacement de jdbc.properties via le volume au répertoire sur la machine hôte, afin que vous puissiez gérer le fichier en externe .

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

REMARQUE: votre base de données peut ne pas autoriser les connexions externes. Dans le cas de postgresql, vous devez éditer 2 fichiers, comme décrit ici et ici :

  1. Modifiez postgresql.conf pour écouter sur toutes les adresses. Par défaut, il pointera vers localhost.

    listen_addresses = '*'
    
  2. Modifiez pg_hba.conf pour autoriser les connexions à partir de toutes les adresses. Ajoutez sur la dernière ligne:

    host     all             all             0.0.0.0/0               md5
    

IMPORTANT: la dernière étape de mise à jour de l'accès à la base de données n'est pas recommandée pour une utilisation en production, sauf si vous êtes vraiment sûr de ce que vous faites.

gmode
la source
--net = host a travaillé pour moi sur un environnement CI, merci beaucoup!
Samy