Comment accéder au port hôte du conteneur docker

J’ai un conteneur de docker exécutant jenkins. Dans le cadre du processus de génération, je dois accéder à un serveur Web exécuté localement sur la machine hôte. Le serveur Web hôte (qui peut être configuré pour fonctionner sur un port) peut-il être exposé au conteneur jenkins?

EDIT: J’exécute docker en mode natif sur une machine Linux.

METTRE À JOUR:

En plus de la réponse de @larsks ci-dessous, pour obtenir l’adresse IP de l’IP hôte de la machine hôte, procédez comme suit:

ip addr show docker0 | grep -Po 'inet \K[\d.]+' 

Lorsque vous exécutez Docker en mode natif sous Linux, vous pouvez accéder aux services hôte à l’aide de l’adresse IP de l’interface docker0 . De l’intérieur du conteneur, ce sera votre route par défaut.

Par exemple, sur mon système:

 $ ip addr show docker0 7: docker0:  mtu 1500 qdisc noqueue state DOWN group default link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link valid_lft forever preferred_lft forever 

Et à l’intérieur d’un conteneur:

 # ip route show default via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 src 172.17.0.4 

Il est assez facile d’extraire cette adresse IP en utilisant un simple script shell:

 #!/bin/sh hostip=$(ip route show | awk '/default/ {print $3}') echo $hostip 

Vous devrez peut-être modifier les règles iptables sur votre hôte pour autoriser les connexions à partir des conteneurs Docker. Quelque chose comme ça fera l’affaire:

 # iptables -A INPUT -i docker0 -j ACCEPT 

Cela permettrait d’accéder à tous les ports de l’hôte à partir des conteneurs Docker. Notez que:

  • Les règles iptables sont ordonnées, et cette règle peut ou non faire la bonne chose en fonction des autres règles qui lui sont soumises.

  • vous ne pourrez accéder qu’aux services hôte (a) écoutant INADDR_ANY (alias 0.0.0.0) ou écoutant explicitement l’interface docker0 .

Pour macOS et Windows

Docker v 18.03 et supérieur (depuis le 21 mars 2018)

Utilisez votre adresse IP interne ou connectez-vous au nom DNS spécial host.docker.internal qui sera résolu en l’adresse IP interne utilisée par l’hôte.

Prise en charge de Linux en attente https://github.com/docker/for-linux/issues/264

MacOS avec les versions antérieures de Docker

Docker pour Mac v 17.12 à v 18.02

Comme ci-dessus, mais utilisez plutôt docker.for.mac.host.internal .

Docker pour Mac v 17.06 à 17.11

Comme ci-dessus, mais utilisez plutôt docker.for.mac.localhost .

Docker pour Mac 17.05 et inférieur

Pour accéder à la machine hôte à partir du conteneur Docker, vous devez joindre un alias IP à votre interface réseau. Vous pouvez lier n’importe quelle adresse IP que vous voulez, assurez-vous simplement de ne pas l’utiliser avec autre chose.

sudo ifconfig lo0 alias 123.123.123.123/24

Assurez-vous ensuite que votre serveur écoute l’IP mentionné ci-dessus ou 0.0.0.0 . S’il écoute sur localhost 127.0.0.1 il n’acceptera pas la connexion.

Ensuite, pointez simplement votre conteneur Docker sur cette adresse IP et vous pourrez accéder à la machine hôte!

Pour tester, vous pouvez lancer quelque chose comme curl -X GET 123.123.123.123:3000 à l’intérieur du conteneur.

L’alias sera réinitialisé à chaque redémarrage, créez donc un script de démarrage si nécessaire.

Solution et plus de documentation ici: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

Utilisez --net="host" dans votre commande docker run , puis localhost dans votre conteneur docker pointera sur votre hôte docker.

Actuellement, le moyen le plus simple de le faire sous Mac et Windows consiste à utiliser l’hôte host.docker.internal , qui résout l’adresse IP de l’ordinateur hôte. Malheureusement, il ne fonctionne pas encore sur Linux (en avril 2018).

Solution avec docker-compose: pour accéder au service basé sur l’hôte, vous pouvez utiliser le paramètre network_mode https://docs.docker.com/compose/compose-file/#network_mode

 version: '3' services: jenkins: network_mode: host 

J’ai créé un conteneur Docker pour faire exactement cela https://github.com/qoomon/docker-host

Vous pouvez ensuite simplement utiliser le nom du conteneur dns pour accéder au système hôte, par exemple curl http://dockerhost:9200

Lorsque vous avez déjà créé deux images de docker et que vous souhaitez mettre deux conteneurs en communication l’un avec l’autre.

Pour cela, vous pouvez facilement exécuter chaque conteneur avec son propre –name et utiliser l’indicateur –link pour permettre la communication entre eux. Vous ne l’obtenez pas pendant la construction de docker cependant.

Lorsque vous êtes dans un scénario comme moi et que c’est votre

 docker build -t "centos7/someApp" someApp/ 

Cela se brise lorsque vous essayez de

 curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz 

et vous êtes bloqué sur “curl / wget” ne retournant pas “route to host”.

La raison en est que la sécurité est définie par docker qui, par défaut, interdit la communication entre un conteneur et l’hôte ou d’autres conteneurs exécutés sur votre hôte. Cela a été assez surprenant pour moi, je dois le dire, vous pouvez vous attendre à ce que l’écosystème des dockers fonctionnant sur une machine locale soit parfaitement accessible sans trop de difficultés.

L’explication de ceci est décrite en détail dans la documentation suivante.

http://www.dedoimedo.com/computers/docker-networking.html

Deux solutions rapides vous aident à vous déplacer en réduisant la sécurité du réseau.

L’alternative la plus simple consiste simplement à désactiver le pare-feu – ou à tout autoriser. Cela signifie que vous devez exécuter la commande nécessaire, qui peut être systemctl stop firewalld, iptables -F ou équivalent.

J’espère que cette information vous aide.