Docker ofrece la capacidad de empaquetar y ejecutar una aplicación en un entorno poco aislado llamado contenedor.
Sé lo que podrías estar pensando: vamos, no otra publicación que explique qué es Docker, ¡está en todas partes estos días!

Pero no se preocupe, nos estamos saltando la introducción básica. El público objetivo de este artículo ya debe tener un conocimiento básico de lo que son Docker y Containers.
Pero, ¿se ha preguntado alguna vez cómo obtener una dirección IP de contenedor de Docker?
Explicación de la red Docker
Primero, entendamos cómo funciona la red Docker. Para eso nos vamos a centrar en la bridge
red predeterminada . Cuando usa Docker, si no especifica un controlador, este es el tipo de red que está usando.

La bridge
red funciona como una red privada interna al host, de modo que los contenedores en ella pueden comunicarse. El acceso externo se otorga exponiendo los puertos a los contenedores.
Las redes puente se utilizan cuando sus aplicaciones se ejecutan en contenedores independientes que necesitan comunicarse.
En la imagen de arriba db
y web
pueden comunicarse entre sí en una red puente creada por el usuario llamada mybridge
.
Si nunca ha agregado una red en Docker, debería ver algo similar a esto:
$ docker network ls NETWORK ID NAME DRIVER SCOPE c3cd46f397ce bridge bridge local ad4e4c24568e host host local 1c69593fc6ac none null local
Se bridge
muestra la red predeterminada , junto con host
y none
. Ignoraremos los otros dos y usaremos la bridge
red cuando lleguemos a los ejemplos.
Dirección IP del contenedor de Docker
De forma predeterminada, al contenedor se le asigna una dirección IP para cada red Docker a la que se conecta. Y cada red se crea con una máscara de subred predeterminada, usándola como grupo más adelante para revelar las direcciones IP.
Por lo general, Docker usa el 172.17. Subred 0.0 / 16 para redes de contenedores.
Ahora, para entenderlo mejor, ejecutaremos un caso de uso real.

Ejemplo de Docker
Para ilustrar esto, usaremos un entorno Hive y Hadoop, que contiene 5 contenedores Docker.
Mira el docker-compose.yml
archivo que estamos a punto de ejecutar:
version: "3" services: namenode: image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8 volumes: - namenode:/hadoop/dfs/name environment: - CLUSTER_NAME=test env_file: - ./hadoop-hive.env ports: - "50070:50070" datanode: image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8 volumes: - datanode:/hadoop/dfs/data env_file: - ./hadoop-hive.env environment: SERVICE_PRECONDITION: "namenode:50070" ports: - "50075:50075" hive-server: image: bde2020/hive:2.3.2-postgresql-metastore env_file: - ./hadoop-hive.env environment: HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore" SERVICE_PRECONDITION: "hive-metastore:9083" ports: - "10000:10000" hive-metastore: image: bde2020/hive:2.3.2-postgresql-metastore env_file: - ./hadoop-hive.env command: /opt/hive/bin/hive --service metastore environment: SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432" ports: - "9083:9083" hive-metastore-postgresql: image: bde2020/hive-metastore-postgresql:2.3.0 volumes: namenode: datanode:
Desde docker-hive GitHub
Nadie quiere leer un archivo de configuración ENORME , ¿verdad? Así que aquí tienes una foto:

¡Mucho mejor! Ahora comencemos esos contenedores:
docker-compose up -d
Podemos ver 5 contenedores:
$ docker ps --format \ "table {{.ID}}\t{{.Status}}\t{{.Names}}" CONTAINER ID STATUS NAMES 158741ba0339 Up 1 minutes dockerhive_hive-metastore-postgresql 607b00c25f29 Up 1 minutes dockerhive_namenode 2a2247e49046 Up 1 minutes dockerhive_hive-metastore 7f653d83f5d0 Up 1 minutes (healthy) dockerhive_hive-server 75000c343eb7 Up 1 minutes (healthy) dockerhive_datanode
A continuación, revisemos nuestras redes Docker:
$ docker network ls NETWORK ID NAME DRIVER SCOPE c3cd46f397ce bridge bridge local 9f6bc3c15568 docker-hive_default bridge local ad4e4c24568e host host local 1c69593fc6ac none null local
Espera un minuto ... ¡hay una nueva red llamada docker-hive_default
!
De forma predeterminada, docker compose configura una única red para su aplicación. Y la red de su aplicación recibe un nombre basado en el "nombre del proyecto", que se origina en el nombre del directorio en el que vive.
Entonces, dado que nuestro directorio tiene un nombre docker-hive
, esto explica la nueva red.
A continuación, algunos ejemplos sobre cómo obtener la dirección IP de Docker.
Cómo obtener una dirección IP de contenedor de Docker: ejemplos
Y ahora que tengo su atención, vamos a desvelar el misterio.

1. Uso de Docker Inspect
Docker inspect es una excelente manera de recuperar información de bajo nivel sobre objetos Docker. Puede seleccionar cualquier campo del JSON devuelto de una manera bastante sencilla.
Entonces, ¿lo usaremos para obtener la dirección IP del dockerhive_datanode
?
$ docker inspect -f \ '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ 75000c343eb7 172.18.0.5
¿No dijiste que Docker usa el 172.17. ¿ Subred 0.0 / 16 para redes de contenedores? ¿Por qué la dirección IP devuelta: 172.18.0.5 está fuera de ella?

Para responder a eso tenemos que mirar nuestra configuración de red:
$ docker network inspect -f \ '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 9f6bc3c15568 172.18.0.0/16
Ejecutamos este ejemplo en una VM de Compute Engine y, en esta prueba, se asignó una subred diferente a la red de Docker : 172.18.0.0/16 . ¡Eso lo explica!
Además, también podemos buscar todas las direcciones IP dentro de la docker-hive_default
red.
Por lo tanto, no necesitamos buscar la IP de cada contenedor individualmente:
$ docker network inspect -f \ '{{json .Containers}}' 9f6bc3c15568 | \ jq '.[] | .Name + ":" + .IPv4Address' "dockerhive_hive-metastore-postgresql:172.18.0.6/16" "dockerhive_hive-metastore:172.18.0.2/16" "dockerhive_namenode:172.18.0.3/16" "dockerhive_datanode:172.18.0.5/16" "dockerhive_hive-server:172.18.0.4/16"

Si no se dio cuenta, usamos jq help para analizar el Containers
objeto del mapa.
2. Usando Docker exec
En el siguiente ejemplo trabajaremos con dockerhive_namenode
.
$ docker exec dockerhive_namenode cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.3 607b00c25f29
3. Dentro del contenedor Docker
$ docker exec -it dockerhive_namenode /bin/bash # running inside the dockerhive_namenode container ip -4 -o address 7: eth0 inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
Incluso podemos encontrar direcciones IP de otros contenedores que se encuentran dentro de un contenedor en la misma red:
Nodo de datos
# running inside the dockerhive_namenode container ping dockerhive_datanode PING dockerhive_datanode (172.18.0.5): 56 data bytes 64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.092 ms
Mestastore de colmena
# running inside the dockerhive_namenode container ping dockerhive_hive-metastore PING dockerhive_hive-metastore_1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.087 ms
Servidor de colmena
# running inside the container ping dockerhive_hive-server PING dockerhive_hive-server (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.172 ms
Envolver
Todos los ejemplos se ejecutaron en una VM de Compute Engine de distribución de Linux. Si los ejecuta en entornos macOS o Windows, los comandos de muestra pueden cambiar un poco.
También tenga en cuenta que esas direcciones IP en los ejemplos dados son internas a la docker-hive_default
red de muestra . Entonces, si tiene un caso de uso para conectarse a esos contenedores externamente, necesitará usar la IP externa de la máquina host (asumiendo que está exponiendo los puertos de los contenedores correctamente).
O si está utilizando kubernetes, por ejemplo, para administrar sus contenedores Docker, deje que maneje las direcciones IP para usted kubernetes-expose-external-ip-address?.
* Ilustraciones de icons8.com por Murat Kalkavan.