¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Networking y Service Discovery (Docker avanzado)
Contenido perteneciente al curso Docker avanzado.
Network
Docker crea una interfaz de red propia con el nombre de docker0. Esta red tiene un rango típico: 174.17.0.1/24
Al principio, solo se podía manejar esta red. Eso generaba problemas de seguridad (confiabilidad y aislamiento).
Esto se mejoró con el avance de Docker
Con el comando docker network ls podemos ver las redes que tenemos configuradas por defecto:
- host representa la red del propio equipo y haría referencia a
eth0/enp0s3, etc. Un contenedor con esta red tendrá una IP local (192.168.0.12) - bridge representa la red
docker0y a ella se conectan todos los contenedores por defecto. Vincula los contenedores con nuestro equipo. - none significa que el contenedor no se incluye en ninguna red y si verificamos esto con el comando ifconfig dentro del contenedor veríamos que solo tiene la interfaz de loopback lo.
Podemos obtener más información de las redes con inspect:
docker network inspect bridge
Ejemplo de salida:
[
{
"Name": "bridge",
"Id": "66ed3ed28d43f355bd4d79e01e58d571154d5a16cc33e5c2a0d7836cc4ee039e",
"Created": "2023-10-13T18:45:27.937713085Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
Si queremos aislar un contenedor o un grupo de contenedores, simplemente tenemos que crear una red:
docker network create --driver bridge red_aislada
y asociársela a los contenedores que queramos:
docker run --net=red_aislada -itd --name=container3 busybox
Podemos indicar que un contenedor tenga acceso a distintas redes.
Existe un comando para conectar un contenedor a cierta red:
docker network connect red_aislada contenedor
Y para desconectarlo:
docker network disconnect red_aislada contenedor
Para crear un sandbox sería útil la opción de desconectar de la red.
Overlay Network
Cuando necesitamos manejar una infraestructura compleja y grande puede ser necesario usar varios hosts en conjunto como si solo fuera uno.
Para ello necesitamos poder generar redes suprahost o superpuestas. Son redes para conectar nodos.
Para ese fin Docker hace uso de la librería VXLAN
Es imprescindible disponer de un servicio de almacenamiento key-value como Consul , Etcd , o ZooKeeper
El servicio se instala en un nodo, y en el resto se instala Docker.
Service Discovery
Un service discovery es un proceso de detección automática de dispositivos y servicios en una red.
Es un estándar de red que logra la detección de redes mediante la identificación de recursos.
Tradicionalmente, la detección de servicios ayuda a reducir los esfuerzos de configuración de los usuarios a los que se les presentan recursos compatibles, como una impresora o un servidor habilitado para Bluetooth
Más recientemente, el concepto se ha ampliado a los recursos de red o de contenedores distribuidos como “servicios”, que se descubren y a los que se accede.
Cuando trabajamos con Docker Compose, ya vemos esta característica ya que los contenedores pueden verse y podemos acceder a ellos desde el nombre de host.
El service provider tiene el service discovery. Al aparecer un nuevo servicio, se guarda en el service registry.
Service Discovery con Spring Boot
Ejemplos de implementación de un Service Discovery usando Eureka Service Discovery en Spring Boot:
Ejercicios
Ejercicio 1
Crear un contenedor con el comando docker run de cualquier imagen. Podemos usar por ejemplo la imagen busybox
docker run -d --name container1 busybox sleep infinity
1. ¿Qué redes tiene disponibles el container?
docker inspect container1
Salida:
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "66ed3ed28d43f355bd4d79e01e58d571154d5a16cc33e5c2a0d7836cc4ee039e",
"EndpointID": "2d5086c60d536dd9848015a736884bfb8d78e08ee8086eb2f094cd1989a6ce6f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
Tiene disponible la red bridge.
2. ¿Mostrar solo las IPs del containter con el comando inspect?
docker inspect --format={{.NetworkSettings.IPAddress}} container1
3. ¿Qué otros contenedores hay en esa misma red?
docker network inspect bridge
Podemos verlo en la sección “Containers”:
"Containers": {
"422af392e56a5c8dde4941fdce10e8b9618c17b8a2040f78f764cd88421032e5": {
"Name": "container1",
"EndpointID": "2d5086c60d536dd9848015a736884bfb8d78e08ee8086eb2f094cd1989a6ce6f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
Ejercicio 2
1. Crear una red de tipo bridge llamada net1 para la subred 172.60.0.0/16
docker network create --driver=bridge --subnet=172.60.0.0/16 net1
2. Vincular el contenedor del ejercicio1 con esta nueva red
docker network connect net1 container1
3. Lista las IPs del contenedor1
Podemos verlas en la sección “Networks” al hacer:
docker inspect container1
Salida:
(...)
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "66ed3ed28d43f355bd4d79e01e58d571154d5a16cc33e5c2a0d7836cc4ee039e",
"EndpointID": "2d5086c60d536dd9848015a736884bfb8d78e08ee8086eb2f094cd1989a6ce6f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
},
"net1": {
"IPAMConfig": {},
"Links": null,
"Aliases": [
"422af392e56a"
],
"NetworkID": "7e2ba91752dfc88d29ceec5a0783c445ad9802c97cbc41a88c89445020c91f66",
"EndpointID": "f0e49b9bea8dfd49163e7a29e0657b7a191a1f9ecdc27fa9471e5b8c8ff380da",
"Gateway": "172.60.0.1",
"IPAddress": "172.60.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:3c:00:02",
"DriverOpts": {}
}
(...)
También podríamos entrar en el contenedor y hacer un ifconfig:
docker exec -it container1 ifconfig
4. Crea un container2 que se vincule solo a la red net1
docker run -d --name container2 --network=net1 busybox sleep infinity
5. Verifica que desde container1 tenemos acceso a container2 y viceversa. Para ello puedes usar docker exec para ejecutar el comando ping entre los contenedores
Ping desde el container1 a container2:
docker exec -it container1 ping -c 3 container2 PING container2 (172.60.0.3): 56 data bytes 64 bytes from 172.60.0.3: seq=0 ttl=64 time=0.205 ms 64 bytes from 172.60.0.3: seq=1 ttl=64 time=0.081 ms 64 bytes from 172.60.0.3: seq=2 ttl=64 time=0.410 ms --- container2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.081/0.232/0.410 ms
Ping desde el container2 a container1:
docker exec -it container2 ping -c 3 container1 PING container1 (172.60.0.2): 56 data bytes 64 bytes from 172.60.0.2: seq=0 ttl=64 time=0.178 ms 64 bytes from 172.60.0.2: seq=1 ttl=64 time=0.454 ms 64 bytes from 172.60.0.2: seq=2 ttl=64 time=0.163 ms --- container1 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.163/0.265/0.454 ms
6. Desconecta todas las redes del container1
docker network disconnect bridge container1 docker network disconnect net1 container1
7. Lista las IPs del container1
Mediante:
docker inspect --format={{.NetworkSettings.IPA
ddress}} container1
No obtenemos ningún resultado.
Si ejecutamos ifconfig en el contenedor:
docker exec -it container1 ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:750 (750.0 B) TX bytes:750 (750.0 B)
8. Prueba a hace un ping al container2 y a google.es
Ping a container2 desde container1:
docker exec -it container1 ping -c 3 container2 ping: bad address 'container2'
Ping a google.es desde container1:
docker exec -it container1 ping -c 3 google.es ping: bad address 'google.es'
