run - Docker 1.10 accede a un contenedor por su nombre de host desde una máquina host
dockers container download (5)
Tengo la versión 1.10 de Docker con servicio de DNS incorporado.
He creado dos contenedores de servicio en mi archivo de composición acoplable. Se pueden alcanzar entre sí por nombre de host y por IP, pero cuando me gustaría llegar a uno de ellos desde la máquina host, no funciona, funciona solo con IP pero no con hostname.
Entonces, ¿es posible acceder a un contenedor docker desde la máquina host por su nombre de host en el Docker 1.10, por favor?
Actualizar:
docker-compose.yml
version: ''2''
services:
service_a:
image: nginx
container_name: docker_a
ports:
- 8080:80
service_b:
image: nginx
container_name: docker_b
ports:
- 8081:80
entonces lo comienzo por comando: docker-compose up --force-recreate
cuando corro:
-
docker exec -i -t docker_a ping -c4 docker_b
- funciona -
docker exec -i -t docker_b ping -c4 docker_a
- funciona -
ping 172.19.0.2
- funciona (172.19.0.2
es la ip dedocker_b
) -
ping docker_a
- falla
El resultado de la docker network inspect test_default
es
[
{
"Name": "test_default",
"Id": "f6436ef4a2cd4c09ffdee82b0d0b47f96dd5aee3e1bde068376dd26f81e79712",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1/16"
}
]
},
"Containers": {
"a9f13f023761123115fcb2b454d3fd21666b8e1e0637f134026c44a7a84f1b0b": {
"Name": "docker_a",
"EndpointID": "a5c8e08feda96d0de8f7c6203f2707dd3f9f6c3a64666126055b16a3908fafed",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
},
"c6532af99f691659b452c1cbf1693731a75cdfab9ea50428d9c99dd09c3e9a40": {
"Name": "docker_b",
"EndpointID": "28a1877a0fdbaeb8d33a290e5a5768edc737d069d23ef9bbcc1d64cfe5fbe312",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {}
}
]
Como se responde aquí, hay una solución de software para esto, copiando la respuesta:
Hay una aplicación de código abierto que resuelve este problema, se llama DNS Proxy Server.
Es un servidor DNS que resuelve los nombres de host de los contenedores, si no pudo encontrar un nombre de host con ese nombre de host, resuélvalo también desde Internet
Iniciar el servidor 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
Se establecerá como su DNS predeterminado automáticamente (y se recuperará al original cuando se detenga)
Comience su contenedor para la prueba
docker-compose up
docker-compose.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
Ahora resuelve tus contenedores con nombres de host
del anfitrión
$ 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
de otro contenedor
$ docker exec -it redis ping elasticsearch.dev.intranet
PING elasticsearch.dev.intranet (172.21.0.2): 56 data bytes
También resuelve nombres de host de 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
Esto es lo que hago.
Escribí un script de Python llamado dnsthing , que escucha la API de eventos de Docker para los contenedores que se inician o se detienen. Mantiene un archivo de estilo hosts
con los nombres y direcciones de los contenedores. Los contenedores se denominan <container_name>.<network>.docker
, así que, por ejemplo, si ejecuto esto:
docker run --rm --name mysql -e MYSQL_ROOT_PASSWORD=secret mysql
Entiendo esto:
172.17.0.2 mysql.bridge.docker
Luego ejecuto un proceso dnsmasq
que apunta a este archivo hosts
. Específicamente, ejecuto una instancia de dnsmasq usando la siguiente configuración:
listen-address=172.31.255.253
bind-interfaces
addn-hosts=/run/dnsmasq/docker.hosts
local=/docker/
no-hosts
no-resolv
Y ejecuto el script dnsthing
así:
dnsthing -c "systemctl restart dnsmasq_docker" /
-H /run/dnsmasq/docker.hosts --verbose
Asi que:
-
dnsthing
actualiza/run/dnsmasq/docker.hosts
como contenedores stop / start - Después de una actualización,
dnsthing
ejecutasystemctl restart dnsmasq_docker
-
dnsmasq_docker
ejecutadnsmasq
usando la configuración anterior, enlazada a una interfaz de puente local con la dirección172.31.255.253
. El proceso dnsmasq "principal" en mi sistema, mantenido por NetworkManager, usa esta configuración de
/etc/NetworkManager/dnsmasq.d/dockerdns
:server=/docker/172.31.255.253
Eso le dice a dnsmasq que pase todas las solicitudes de hosts en el dominio
docker_dnsmasq
serviciodocker_dnsmasq
.
Obviamente, esto requiere un poco de configuración para poner todo junto, pero después de eso parece que simplemente funciona:
$ ping -c1 mysql.bridge.docker
PING mysql.bridge.docker (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.087 ms
--- mysql.bridge.docker ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.087/0.087/0.087/0.000 ms
La forma más sencilla de hacerlo es agregar entradas a su archivo de hosts
- para linux: agregue
127.0.0.1 docker_a docker_b
al archivo / etc / hosts - para mac: similar a Linux pero usa ip de la máquina virtual
docker-machine ip default
Para resolver específicamente este problema, creé una tool inyección de dominio "etc / hosts" simple que resuelve los nombres de los contenedores de Docker locales en el host. Solo corre:
docker run -d /
-v /var/run/docker.sock:/tmp/docker.sock /
-v /etc/hosts:/tmp/hosts /
--name docker-hoster /
dvdarias/docker-hoster
Podrá acceder a un contenedor utilizando el container name
del container name
, el container name
hostname
, la container id
y mediante los network aliases
que han declarado para cada red.
Los contenedores se registran automáticamente cuando se inician y se eliminan cuando están en pausa, muertos o detenidos.
Similar a @larsks, también escribí un script de Python pero lo implementé como servicio. Aquí está: https://github.com/nicolai-budico/dockerhosts
--hostsdir=/var/run/docker-hosts
dnsmasq con el parámetro --hostsdir=/var/run/docker-hosts
y actualiza el archivo /var/run/docker-hosts/hosts
cada vez que se cambia una lista de contenedores en ejecución. Una vez que se cambia el archivo /var/run/docker-hosts/hosts
, dnsmasq actualiza automáticamente su asignación y el contenedor queda disponible por nombre de host en un segundo.
$ 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
Hay instalar y desinstalar scripts. Lo único que necesita es permitir que su sistema interactúe con esta instancia de dnsmasq. Me registré en systemd-resolvió:
$ cat /etc/systemd/resolved.conf
[Resolve]
DNS=127.0.0.54
#FallbackDNS=
#Domains=
#LLMNR=yes
#MulticastDNS=yes
#DNSSEC=no
#Cache=yes
#DNSStubListener=udp