Conceptos básicos de la red de Docker

DockerDockerBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploraremos los conceptos básicos de la red de Docker. Las redes de Docker permiten que los contenedores se comuniquen entre sí y con el mundo exterior. Cubriremos varios tipos de redes, la creación de redes personalizadas, la conexión de contenedores y la gestión de configuraciones de red. Esta experiencia práctica te proporcionará una base sólida en los conceptos y prácticas de la red de Docker.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/RemoteAccessandNetworkingGroup(["Remote Access and Networking"]) docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/NetworkOperationsGroup(["Network Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ContainerOperationsGroup -.-> docker/port("List Container Ports") docker/NetworkOperationsGroup -.-> docker/network("Manage Networks") linux/RemoteAccessandNetworkingGroup -.-> linux/ip("IP Managing") subgraph Lab Skills docker/run -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} docker/exec -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} docker/inspect -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} docker/port -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} docker/network -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} linux/ip -.-> lab-389048{{"Conceptos básicos de la red de Docker"}} end

Comprender los tipos de red de Docker

Docker proporciona varios controladores de red integrados. Comencemos examinando las redes predeterminadas en su sistema.

En su terminal, ejecute el siguiente comando para listar todas las redes de Docker disponibles:

docker network ls

Este comando lista todas las redes que Docker ha creado en su sistema. Debería ver una salida similar a esta:

NETWORK ID     NAME      DRIVER    SCOPE
79dce413aafd   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Desglosemos los tipos de red predeterminados:

  1. bridge: Este es el controlador de red predeterminado. Cuando inicia un contenedor sin especificar una red, se conecta automáticamente a la red bridge. Los contenedores en la misma red bridge pueden comunicarse entre sí utilizando sus direcciones IP.

  2. host: Este controlador elimina el aislamiento de red entre el contenedor y el host de Docker. El contenedor comparte el espacio de nombres de red del host, lo que significa que utiliza directamente la dirección IP y el espacio de puertos del host. Esto puede ser útil para optimizar el rendimiento en ciertos escenarios.

  3. none: Este controlador deshabilita toda la conectividad de red para un contenedor. Los contenedores que utilizan este tipo de red no tendrán acceso a redes externas ni a otros contenedores. Es útil cuando desea aislar completamente un contenedor.

La columna SCOPE indica si la red está limitada a un solo host (local) o puede abarcar múltiples hosts en un enjambre de Docker (swarm).

Inspeccionar la red bridge predeterminada

Ahora que hemos visto la lista de redes, echemos un vistazo más detallado a la red bridge predeterminada. Esta red es creada automáticamente por Docker y es utilizada por los contenedores a menos que se especifique lo contrario.

Ejecute el siguiente comando para inspeccionar la red bridge:

docker network inspect bridge

Este comando proporciona información detallada sobre la red bridge, incluyendo su subred, puerta de enlace y contenedores conectados. Verá una salida similar a esta (truncada por brevedad):

[
  {
    "Name": "bridge",
    "Id": "79dce413aafdd7934fa3c1d0cc97decb823891ce406442b7d51be6126ef06a5e",
    "Created": "2024-08-22T09:58:39.747333789+08:00",
    "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": {}
  }
]

Desglosemos alguna información clave de esta salida:

  • Subnet: La subred utilizada por los contenedores en esta red es 172.17.0.0/16. Esto significa que los contenedores se les asignarán direcciones IP dentro de este rango.
  • Gateway: La puerta de enlace de esta red es 172.17.0.1. Esta es la dirección IP que los contenedores utilizan para comunicarse con redes fuera de su propia red.
  • Containers: Este campo está vacío porque aún no hemos iniciado ningún contenedor.
  • Options: Estas son varias opciones de configuración para la red bridge. Por ejemplo, enable_icc establecido en "true" significa que la comunicación entre contenedores está permitida en esta red.

Comprender esta información es crucial cuando se solucionan problemas de red o cuando es necesario configurar los contenedores para que se comuniquen con rangos de IP específicos.

Crear una red bridge personalizada

Si bien la red bridge predeterminada es adecuada para muchos casos de uso, crear redes personalizadas permite un mejor aislamiento y control. Las redes personalizadas son especialmente útiles cuando se desea agrupar contenedores relacionados o cuando es necesario controlar qué contenedores pueden comunicarse entre sí.

Creemos una red bridge personalizada llamada my-network:

docker network create --driver bridge my-network

Este comando crea una nueva red bridge. La opción --driver bridge es en realidad opcional aquí porque bridge es el controlador predeterminado, pero se incluye para mayor claridad.

Ahora, verificaremos que nuestra nueva red se haya creado:

docker network ls

Debería ver my-network en la lista de redes:

NETWORK ID     NAME         DRIVER    SCOPE
1191cb61c989   bridge       bridge    local
91199fc6ad2e   host         host      local
47ac4e684a72   my-network   bridge    local
1078d2c781b6   none         null      local

Nuestra nueva red my-network aparece en la lista, lo que confirma que se creó con éxito. Esta red ahora está disponible para que los contenedores se conecten a ella.

Conectar contenedores a redes

Ahora que tenemos nuestra red personalizada, creemos dos contenedores y conectémoslos a ella. Usaremos la imagen nginx para este ejemplo, que proporciona un servidor web ligero.

Ejecute los siguientes comandos para crear dos contenedores:

docker run -d --name container1 --network my-network nginx
docker run -d --name container2 --network my-network nginx

Desglosemos estos comandos:

  • -d: Esta bandera ejecuta el contenedor en modo desatendido, lo que significa que se ejecuta en segundo plano.
  • --name: Esto asigna un nombre a nuestro contenedor, lo que facilita su referencia más adelante.
  • --network: Esto especifica a qué red se debe conectar el contenedor.
  • nginx: Este es el nombre de la imagen que estamos usando para crear nuestros contenedores.

Estos comandos crean dos contenedores desatendidos (-d) llamados container1 y container2, ambos conectados a nuestra red my-network.

Verifiquemos que los contenedores estén en ejecución y conectados a nuestra red:

docker ps

Este comando lista todos los contenedores en ejecución. Debería ver ambos contenedores enumerados en la salida:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
1234567890ab   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    80/tcp    container2
abcdef123456   nginx     "/docker-entrypoint.…"   20 seconds ago   Up 19 seconds   80/tcp    container1

Esta salida muestra que ambos contenedores están ejecutando la imagen de Nginx y están exponiendo el puerto 80 dentro del contenedor.

Probar la comunicación entre contenedores

Uno de los principales beneficios de la red de Docker es que los contenedores en la misma red pueden comunicarse entre sí utilizando sus nombres de contenedor como nombres de host. Esto facilita la configuración de la comunicación entre servicios sin necesidad de conocer sus direcciones IP.

Probemos esto utilizando container1 para enviar una solicitud a container2:

docker exec container1 curl -s container2

Desglosemos este comando:

  • docker exec: Esto le dice a Docker que ejecute un comando dentro de un contenedor en ejecución.
  • container1: Este es el nombre del contenedor en el que queremos ejecutar el comando.
  • curl -s container2: Este es el comando que estamos ejecutando dentro del contenedor. Envía una solicitud GET a container2 y la bandera -s hace que curl funcione en modo silencioso.

Este comando ejecuta el comando curl dentro de container1, enviando una solicitud a container2. Debería ver el HTML de la página de bienvenida predeterminada de Nginx en la salida:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    <style>
      html {
        color-scheme: light dark;
      }
      body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>
      If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.
    </p>

    <p>
      For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br />
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.
    </p>

    <p><em>Thank you for using nginx.</em></p>
  </body>
</html>

Esta respuesta exitosa demuestra que container1 puede comunicarse con container2 utilizando su nombre de contenedor. El servidor DNS integrado de Docker resuelve el nombre del contenedor a su dirección IP dentro de la red.

Exponer puertos de contenedores

Por defecto, los contenedores en una red personalizada pueden comunicarse entre sí, pero no son accesibles desde fuera del host de Docker. Para hacer que un contenedor sea accesible desde el host o redes externas, necesitamos exponer sus puertos.

Creemos un nuevo contenedor con un puerto expuesto:

docker run -d --name exposed-container -p 8080:80 --network my-network nginx

Desglosemos este comando:

  • -d: Ejecuta el contenedor en modo desatendido.
  • --name exposed-container: Nombrar al contenedor "exposed-container".
  • -p 8080:80: Mapea el puerto 80 dentro del contenedor al puerto 8080 en el host.
  • --network my-network: Conecta el contenedor a nuestra red personalizada.
  • nginx: Utiliza la imagen de Nginx.

Este comando crea un nuevo contenedor llamado exposed-container, mapea el puerto 80 del contenedor al puerto 8080 del host y lo conecta a nuestra red my-network.

Ahora, puedes acceder al servidor Nginx de este contenedor desde tu máquina host abriendo un navegador web y navegando a http://localhost:8080, o utilizando curl:

curl localhost:8080

Deberías ver el mismo HTML de la página de bienvenida de Nginx que antes. Sin embargo, esta vez estamos accediendo al contenedor directamente desde el host, no desde otro contenedor.

Usar la red del host

Para escenarios en los que desees que un contenedor comparta la pila de red del host, puedes utilizar el controlador de red host. Esto elimina el aislamiento de red entre el contenedor y el host, lo cual puede ser útil para ciertas aplicaciones, pero debe usarse con cuidado debido a los posibles conflictos de puertos.

Creemos un contenedor utilizando la red del host:

docker run -d --name host-networked --network host nginx

Este comando crea un nuevo contenedor llamado host-networked utilizando la red del host. Ten en cuenta que no puedes usar -p con la red del host, ya que el contenedor ya está utilizando las interfaces de red del host.

Para verificar que el contenedor está utilizando la red del host, podemos inspeccionar sus configuraciones de red:

docker inspect --format '{{.HostConfig.NetworkMode}}' host-networked

Este comando inspecciona el contenedor y formatea la salida para mostrar solo el NetworkMode. Debería mostrar host, lo que confirma que el contenedor está utilizando la red del host.

Al utilizar la red del host, el contenedor comparte la dirección IP del host y puede acceder directamente a todas las interfaces de red del host. Esto puede ser útil para maximizar el rendimiento, pero también significa que cualquier puerto que el contenedor utilice se abrirá directamente en el host, lo que podría provocar conflictos si no se tiene cuidado.

Resumen

En este laboratorio, exploramos los fundamentos de la red de Docker. Cubrimos varios tipos de redes, la creación de redes personalizadas, la conexión de contenedores, la prueba de la comunicación entre contenedores, la exposición de puertos de contenedores y el uso de la red del host. Estos conceptos forman la base de la red de Docker y son esenciales para diseñar y gestionar aplicaciones contenerizadas.

Aprendimos cómo:

  • Listar e inspeccionar las redes de Docker
  • Crear redes puente personalizadas
  • Conectar contenedores a redes
  • Probar la comunicación entre contenedores
  • Exponer puertos de contenedores al host
  • Usar la red del host para contenedores

Comprender estos conceptos de red te ayudará a diseñar aplicaciones contenerizadas más robustas y seguras. A medida que sigas trabajando con Docker, encontrarás escenarios de red más avanzados, pero los principios que hemos cubierto aquí servirán como una base sólida para tu viaje hacia la orquestación de contenedores y la arquitectura de microservicios.

Recuerda, la red de Docker es una herramienta poderosa que te permite crear entornos aislados para tus aplicaciones mientras todavía permite una comunicación controlada entre contenedores y con el mundo exterior. Practica estos conceptos y explora temas más avanzados para convertirte en un experto en la gestión de redes de Docker.