J'ai un conteneur docker exécutant jenkins. Dans le cadre du processus de génération, j'ai besoin d'accéder à un serveur Web exécuté localement sur la machine hôte. Existe-t-il un moyen d'exposer le serveur Web hôte (qui peut être configuré pour s'exécuter sur un port) au conteneur jenkins?
EDIT: J'exécute Docker nativement sur une machine Linux.
METTRE À JOUR:
En plus de la réponse @larsks ci-dessous, pour obtenir l'adresse IP de l'adresse IP hôte de la machine hôte, je fais ce qui suit:
ip addr show docker0 | grep -Po 'inet \K[\d.]+'
docker
docker-container
Tri Nguyen
la source
la source
curl: (7) Failed to connect to 172.17.1.78 port 7000: No route to host
Réponses:
Lorsque vous exécutez Docker en mode natif sur Linux, vous pouvez accéder aux services hôtes à l'aide de l'adresse IP de l'
docker0
interface. De l'intérieur du conteneur, ce sera votre itinéraire par défaut.Par exemple, sur mon système:
Et à l'intérieur d'un conteneur:
Il est assez facile d'extraire cette adresse IP à l'aide d'un simple script shell:
Vous devrez peut-être modifier les
iptables
règles de votre hôte pour autoriser les connexions à partir des conteneurs Docker. Quelque chose comme ça fera l'affaire: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 selon les autres règles qui la précèdent.
vous ne pourrez accéder qu'aux services hôtes qui (a) écoutent
INADDR_ANY
(aka 0.0.0.0) ou qui écoutent explicitement sur l'docker0
interface.la source
docker.for.mac.localhost
au lieu delocalhost
ou127.0.0.1
. Voici le doc .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 se résoudra en adresse IP interne utilisée par l'hôte.Prise en charge 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
Identique à ci-dessus mais à utiliser à la
docker.for.mac.host.internal
place.Docker pour Mac v 17.06 à v 17.11
Identique à ci-dessus mais à utiliser à la
docker.for.mac.localhost
place.Docker pour Mac 17.05 et versions antérieures
Pour accéder à la machine hôte à partir du conteneur Docker, vous devez attacher un alias IP à votre interface réseau. Vous pouvez lier l'adresse IP de votre choix, assurez-vous simplement de ne pas l'utiliser pour autre chose.
sudo ifconfig lo0 alias 123.123.123.123/24
Assurez-vous ensuite que votre serveur écoute l'IP mentionnée ci-dessus ou
0.0.0.0
. S'il écoute sur localhost,127.0.0.1
il n'acceptera pas la connexion.Il vous suffit ensuite de pointer votre conteneur Docker vers cette IP et vous pourrez accéder à la machine hôte!
Pour tester, vous pouvez exécuter quelque chose comme
curl -X GET 123.123.123.123:3000
à l'intérieur du conteneur.L'alias se réinitialise à 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
la source
docker.for.mac.localhost
qui se résoudra en adresse IP interne utilisée par l'hôte! ... Je l'ai testé et ça fonctionne! :)ip route show | awk '/default/ {print $3}'
donner une IP et endocker.for.mac.localhost
est une autre.host.docker.internal
docs.docker.com/docker-for-mac/networking/…host.docker.internal
dans le conteneur docker et la configuration127.0.0.1 host.docker.internal
dans le fichier hosts .Utilisez
--net="host"
dans votredocker run
commande, puislocalhost
dans votre conteneur Docker pointera vers votre hôte Docker.la source
network_mode: "host"
Solution avec docker-compose: pour accéder au service basé sur l'hôte, vous pouvez utiliser le
network_mode
paramètre https://docs.docker.com/compose/compose-file/#network_modeEDIT 2020-04-27: recommandé pour une utilisation uniquement dans un environnement de développement local.
la source
Actuellement, le moyen le plus simple de le faire sur Mac et Windows utilise l'hôte
host.docker.internal
, qui se résout en l'adresse IP de la machine hôte. Malheureusement, cela ne fonctionne pas encore sur Linux (en avril 2018).la source
J'ai créé un conteneur Docker pour faire exactement cela https://github.com/qoomon/docker-host
Vous pouvez ensuite simplement utiliser le nom de conteneur DNS pour accéder au système hôte, par exemple
curl http://dockerhost:9200
la source
Nous avons constaté qu'une solution plus simple à toutes ces ordures de réseautage consiste à simplement utiliser la socket de domaine pour le service. Si vous essayez de vous connecter à l'hôte de toute façon, montez simplement la prise en tant que volume et vous êtes sur la bonne voie. Pour postgresql, c'était aussi simple que:
Ensuite, nous venons de configurer notre connexion à la base de données pour utiliser le socket au lieu du réseau. Littéralement aussi simple que cela.
la source
J'ai exploré les différentes solutions et je trouve que c'est la solution la moins hacky:
extra_hosts
directive.Le seul inconvénient est que si vous avez plusieurs réseaux ou projets faisant cela, vous devez vous assurer que leur plage d'adresses IP n'entre pas en conflit.
Voici un exemple de Docker Compose:
Vous pouvez ensuite accéder aux ports de l'hôte depuis l'intérieur du conteneur en utilisant le nom d'hôte "dockerhost".
la source
Pour les systèmes Linux, vous pouvez
20.04
désormais - à partir de la version principale - communiquer également avec l'hôte viahost.docker.internal
. Cela ne fonctionnera pas automatiquement , mais vous devez fournir l'indicateur d'exécution suivant:Voir
la source
Vous pouvez accéder au serveur Web local qui s'exécute sur votre machine hôte de deux manières.
Approche 1 avec IP publique
Utilisez l'adresse IP publique de la machine hôte pour accéder au serveur Web dans le conteneur Docker Jenkins.
Approche 2 avec le réseau hôte
Utilisez "--net host" pour ajouter le conteneur Docker Jenkins sur la pile réseau de l'hôte. Les conteneurs qui sont déployés sur la pile de l'hôte ont un accès complet à l'interface hôte. Vous pouvez accéder au serveur Web local dans le conteneur Docker avec une adresse IP privée de la machine hôte.
Démarrez un conteneur avec le réseau hôte
Eg: docker run --net host -it ubuntu
et exécutez-leifconfig
pour répertorier toutes les adresses IP réseau disponibles accessibles à partir du conteneur Docker.Par exemple: J'ai démarré un serveur nginx sur ma machine hôte locale et je peux accéder aux URL du site Web nginx à partir du conteneur Docker Ubuntu.
docker run --net host -it ubuntu
Accès au serveur Web Nginx (exécuté sur la machine hôte locale) à partir du conteneur Docker Ubuntu avec l'adresse IP du réseau privé.
la source
Pour
docker-compose
utiliser la mise en réseau de ponts pour créer un réseau privé entre les conteneurs, la solution acceptéedocker0
ne fonctionne pas car l'interface de sortie des conteneurs ne l'est pas,docker0
mais c'est plutôt un identifiant d'interface généré de manière aléatoire, tel que:Malheureusement, cet identifiant aléatoire n'est pas prévisible et changera à chaque fois que la composition doit recréer le réseau (par exemple lors d'un redémarrage de l'hôte). Ma solution consiste à créer le réseau privé dans un sous-réseau connu et à configurer
iptables
pour accepter cette plage:Composez l'extrait de fichier:
Vous pouvez modifier le sous-réseau si votre environnement l'exige. J'ai arbitrairement sélectionné
192.168.32.0/20
en utilisantdocker network inspect
pour voir ce qui était créé par défaut.Configurer
iptables
sur l'hôte pour autoriser le sous-réseau privé comme source:C'est le plus simple possible
iptables
règle . Vous pouvez souhaiter ajouter d'autres restrictions, par exemple par port de destination. N'oubliez pas de conserver vos règles iptables lorsque vous êtes satisfait qu'ils fonctionnent.Cette approche a l'avantage d'être répétable et donc automatisable. J'utilise le
template
module ansible pour déployer mon fichier de composition avec substitution de variables, puis j'utilise les modulesiptables
etshell
pour configurer et conserver les règles de pare-feu, respectivement.la source
iptables -A INPUT -i docker0 -j ACCEPT
, mais cela ne m'a pas aidé, alors que laiptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
suggestion ici a résolu mon problème.C'est une vieille question et a eu beaucoup de réponses, mais aucune de ces réponses ne correspondait assez bien à mon contexte. Dans mon cas, les conteneurs sont très légers et ne contiennent aucun des outils de mise en réseau nécessaires pour extraire l'adresse IP de l'hôte à l'intérieur du conteneur.
De plus, en utilisant le
--net="host"
approche est une approche très approximative qui n'est pas applicable lorsque l'on veut avoir une configuration de réseau bien isolée avec plusieurs conteneurs.Donc, mon approche consiste à extraire l'adresse des hôtes du côté de l'hôte, puis à la transmettre au conteneur avec le
--add-host
paramètre:ou, enregistrez l'adresse IP de l'hôte dans une variable d'environnement et utilisez la variable plus tard:
Et puis le
docker-host
est ajouté au fichier hosts du conteneur, et vous pouvez l'utiliser dans vos chaînes de connexion à la base de données ou vos URL d'API.la source
Lorsque vous avez deux images docker "déjà" créées et que vous souhaitez mettre deux conteneurs pour communiquer l'un avec l'autre.
Pour cela, vous pouvez facilement exécuter chaque conteneur avec son propre nom et utiliser l'indicateur --link pour permettre la communication entre eux. Cependant, vous n'obtenez pas cela lors de la construction du docker.
Lorsque vous êtes dans un scénario comme moi et que c'est votre
Ça casse quand vous essayez de
et vous êtes bloqué sur "curl / wget" ne renvoyant aucune "route vers l'hôte".
La raison en est la sécurité qui est mise en place par docker qui, par défaut, interdit la communication d'un conteneur vers l'hôte ou d'autres conteneurs exécutés sur votre hôte. C'était assez surprenant pour moi, je dois dire, que vous vous attendriez à ce que l'écosystème de machines docker fonctionnant sur une machine locale puisse parfaitement accéder les uns aux autres sans trop d'obstacles.
L'explication est décrite en détail dans la documentation suivante.
http://www.dedoimedo.com/computers/docker-networking.html
Deux solutions rapides sont données pour vous aider à vous déplacer en réduisant la sécurité du réseau.
J'espère que ces informations vous aideront.
la source
--link
est maintenant obsolètePour moi (Windows 10, Docker Engine v19.03.8), c'était un mélange de https://stackoverflow.com/a/43541732/7924573 et https://stackoverflow.com/a/50866007/7924573 .
par exemple: LOGGER_URL = " http: //host.docker.internal: 8085 / log "
version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge
ou alternativement: utilisez--net="bridge"
si vous n'utilisez pas docker-compose (similaire à https://stackoverflow.com/a/48806927/7924573 )Comme indiqué dans les réponses précédentes: Cela ne doit être utilisé que dans un environnement de développement local .
Pour plus d'informations, consultez: https://docs.docker.com/compose/compose-file/#network_mode et https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds
la source