Accéder au conteneur docker depuis l'hôte en utilisant le nom du conteneur

je suis en train de développer un service et d'Y utiliser docker compose pour faire tourner des services comme postgres, redis, elasticsearch. J'ai une application web qui est basée sur RubyOnRails et écrit et lit de tous ces services.

Voici mon docker-compose.yml

version: '2'

services:
  redis:
    image: redis:2.8
    networks:
      - frontapp

  elasticsearch:
    image: elasticsearch:2.2
    networks:
      - frontapp

  postgres:  
    image: postgres:9.5
    environment:
      POSTGRES_USER: elephant
      POSTGRES_PASSWORD: smarty_pants
      POSTGRES_DB: elephant
    volumes:
      - /var/lib/postgresql/data
    networks:
      - frontapp

networks:
  frontapp:
    driver: bridge

Et je peux faire un ping conteneurs à l'intérieur de ce réseau

$ docker-compose run redis /bin/bash
root@777501e06c03:/data# ping postgres
PING postgres (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: icmp_seq=0 ttl=64 time=0.346 ms
64 bytes from 172.20.0.2: icmp_seq=1 ttl=64 time=0.047 ms
...

So far So good. Maintenant je veux lancer l'application ruby on rails sur ma machine hôte mais être capable d'accéder à l'instance de postgres avec des url comme postgresql://username:password@postgres/database actuellement ce n'est pas possible

$ ping postgres
ping: unknown host postgres

je peux voir mon réseau dans le panneau

$ docker network ls
NETWORK ID          NAME                DRIVER
ac394b85ce09        bridge              bridge              
0189d7e86b33        elephant_default    bridge              
7e00c70bde3b        elephant_frontapp   bridge              
a648554a72fa        host                host                
4ad9f0f41b36        none                null 

Et je peux voir une interface

$ ifconfig 
br-0189d7e86b33 Link encap:Ethernet  HWaddr 02:42:76:72:bb:c2  
          inet addr:172.18.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:76ff:fe72:bbc2/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:36 errors:0 dropped:0 overruns:0 frame:0
          TX packets:60 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2000 (2.0 KB)  TX bytes:8792 (8.7 KB)

br-7e00c70bde3b Link encap:Ethernet  HWaddr 02:42:e7:d1:fe:29  
          inet addr:172.20.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:e7ff:fed1:fe29/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1584 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1597 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:407137 (407.1 KB)  TX bytes:292299 (292.2 KB)
...

mais je ne sais pas ce que je dois faire ensuite. J'ai essayé de jouer un peu avec /etc/resolv.conf principalement nameserver directive, mais cela n'a eu aucun effet.

j'apprécierais toute aide de suggestions sur la façon de configurer cette configuration correctement.

UPDATE

Après en parcourant des ressources Internet, j'ai réussi à attribuer des adresses IP statiques à des boîtes. Pour l'instant, il me suffit de poursuivre le développement. Voici mon docker-compose.yml

version: '2'

services:
  redis:
    image: redis:2.8
    networks:
      frontapp:
        ipv4_address: 172.25.0.11

  elasticsearch:
    image: elasticsearch:2.2
    networks:
      frontapp:
        ipv4_address: 172.25.0.12

  postgres:  
    image: postgres:9.5
    environment:
      POSTGRES_USER: elephant
      POSTGRES_PASSWORD: smarty_pants
      POSTGRES_DB: elephant
    volumes:
      - /var/lib/postgresql/data
    networks:
      frontapp:
        ipv4_address: 172.25.0.10

networks:
  frontapp:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.25.0.0/16
          gateway: 172.25.0.1
27
demandé sur Max 2016-05-15 21:38:35

5 réponses

il y a une application opensource qui résout ce problème, elle s'appelle DNS Proxy Server

c'est un serveur DNS qui résout des noms d'hôtes de conteneurs, si ne pouvait pas trouver un nom d'hôte qui correspond alors le résoudre à partir d'internet aussi bien

démarrer le serveur DNS

$ docker run --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/resolv.conf:/etc/resolv.conf \
defreitas/dns-proxy-server

il se définira comme votre DNS par défaut automatiquement (et récupérera à l'original quand s'arrête)

démarrer votre container pour test

docker-compose up

menu fixe-composer.yml

version: '2'
services:
  redis:
    container_name: redis
    image: redis:2.8
    hostname: redis.dev.intranet
    network_mode: bridge # that way he can solve others containers names even inside, solve elasticsearch, for example
  elasticsearch:
    container_name: elasticsearch
    image: elasticsearch:2.2
    hostname: elasticsearch.dev.intranet

maintenant, résolvez vos noms d'hôtes containers

host

$ nslookup redis.dev.intranet
Server:     172.17.0.2
Address:    172.17.0.2#53

Non-authoritative answer:
Name:   redis.dev.intranet
Address: 172.21.0.3

à partir d'un autre conteneur

$ docker exec -it redis ping elasticsearch.dev.intranet
PING elasticsearch.dev.intranet (172.21.0.2): 56 data bytes

ainsi il résout les noms d'hôtes internet

$ nslookup google.com
Server:     172.17.0.2
Address:    172.17.0.2#53

Non-authoritative answer:
Name:   google.com
Address: 216.58.202.78
13
répondu deFreitas 2018-09-26 14:13:42

nom d'hôte du conteneur docker ne peut pas être vu de l'extérieur. Ce que vous pouvez faire est d'assigner un nom au conteneur et d'accéder au conteneur à travers le nom. Si vous liez 2 conteneurs, par exemple container1 et container2, alors docker s'occupe d'écrire L'IP et le nom d'hôte de container2 dans le container1. Cependant, dans votre cas, votre application est en cours d'exécution dans la machine hostmachine.

ou

Vous connaissez l'adresse IP du conteneur. Ainsi, dans le fichier/etc / hosts de votre machine hôte, vous pouvez Ajouter $ IP $ hostanameof container

2
répondu Aditya C S 2016-05-15 19:16:32

si vous n'utilisez que votre configuration docker-composer localement, vous pouvez mapper les ports de vos conteneurs vers votre hôte avec

elasticsearch:
  image: elasticsearch:2.2
  ports:
    - 9300:9300
    - 9200:9200

puis utilisez localhost: 9300 (ou 9200 selon le protocole) à partir de votre application web pour accéder à Elasticsearch.

une solution plus complexe est d'exécuter votre propre dns qui résout les noms de conteneur. Je pense que cette solution est beaucoup plus proche de ce que vous me demandez. J'ai utilisé des skydns pour exécuter des kubernetes. localement.

Il y a quelques options là-bas. Jetez un oeil à https://github.com/gliderlabs/registrator et https://github.com/jderusse/docker-dns-gen. Je n'ai pas essayer, mais vous pourriez potentiellement carte le port dns à votre hôte de la même façon qu'avec l'élastique ports dans l'exemple précédent, puis ajouter localhost pour votre resolv.conf pour être en mesure de résoudre vos noms de conteneur à partir de votre hôte.

2
répondu Johan 2016-10-14 09:36:27

il y a deux solutions (sauf /etc/hosts) décrit ici et ici

j'ai écrit ma propre solution en Python et je l'ai implémentée en tant que service pour fournir une correspondance entre le nom d'hôte du conteneur et son IP. Elle est ici: https://github.com/nicolai-budico/dockerhosts

il lance dnsmasq avec paramètre --hostsdir=/var/run/docker-hosts et met à jour le fichier /var/run/docker-hosts/hosts chaque fois qu'une liste des conteneurs en cours d'exécution a été changée. Une fois le fichier/var/run/docker-hosts/hosts est changée, DN-MSQ met automatiquement à jour sa cartographie et le conteneur devient disponible par nom d'hôte dans une seconde.

$ docker run -d --hostname=myapp.local.com --rm -it ubuntu:17.10
9af0b6a89feee747151007214b4e24b8ec7c9b2858badff6d584110bed45b740

$ nslookup myapp.local.com
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   myapp.local.com
Address: 172.17.0.2

il y a des scripts d'installation et de désinstallation. Il vous suffit de permettre à votre système d'interagir avec cette instance dnsmasq. Je me suis inscrit dans systemd-résolu:

$ cat /etc/systemd/resolved.conf

[Resolve]
DNS=127.0.0.54
#FallbackDNS=
#Domains=
#LLMNR=yes
#MulticastDNS=yes
#DNSSEC=no
#Cache=yes
#DNSStubListener=udp
2
répondu Nicolai 2017-12-08 14:47:33

Aditya a raison. Dans votre cas, le plus simple est de coder votre nom d'hôte / adresse IP en/etc/hosts

Le problème avec cette approche, cependant, est que vous ne contrôlez pas l'adresse IP privée de votre postgres machine. L'adresse IP changera chaque fois que vous démarrez un nouveau conteneur, et vous devrez donc mettre à jour votre fichier /etc/hosts.

Si c'est un problème, je vous recommande de lire cet article de blog qui explique comment appliquer un conteneur obtenir un adresse IP spécifique:

https://xand.es/2016/05/09/docker-with-known-ip/

1
répondu Christophe Schmitz 2016-05-16 03:56:40