Configuración de red predeterminada de Docker en un solo host
El entorno utilizado en este artículo es el siguiente:
host: centos7
docker: instalado mediante yum install -y docker, el número de versión es 1.10. 3
imagen de la ventana acoplable:
# Versión: 0.0.1 DE ubuntu: último MANTENEDOR paul liu "pollux.liu@msn.com" EJECUTAR apt-get update EJECUTAR apt-get install -y net- tools EJECUTAR apt-get install -y iputils-ping CMD /bin/bash
Diagrama de escenario:
Mi host está conectado a un enrutador inalámbrico, marca al Internet a través de ADSL y la tarjeta de red eth0 es fija. La IP es 192.168.0.200 y la puerta de enlace es la IP del enrutador 192.168.0.1.
Instale Docker en el host y ejecute el contenedor.
Instale Docker mediante el siguiente comando,
yum install -y docker
Habilite Docker,
systemctl start docker
Luego ejecute el comando ifconfig o ip a en el host. Puede ver que además de la tarjeta de red original eth0 y loopback lo del host, hay un docker0 adicional.
La IP de docker0 es 172.17.0.1 y el segmento de red en el que se encuentra tiene como valor predeterminado la dirección de red privada de Clase B 172.17.0.0/16. Docker0 puede considerarse como una tarjeta de red virtual del host. De esta manera, el host equivale a configurar tarjetas de red duales. Las dos tarjetas de red pueden comunicarse entre sí, pero solo si ip_forward está habilitado.
Esta es la primera identidad de docker0.
Ejecute dos contenedores docker1 y docker2, y luego ejecute brctl show en el host para verlos.
Aquí puede ver la segunda identidad de docker0, un conmutador virtual. Cada vez que se ejecuta un contenedor, se generará un par de veth, un extremo está conectado a docker0 y el otro extremo está conectado a eth0 del contenedor. De esta forma, todos los contenedores conectados a docker0 forman una LAN. Como se muestra a continuación:
Cuando ejecuta ifconfig en la máquina host, también encontrará dos interfaces de red más, como veth.
Ejecute ip addr show veth6d9a691 en el host. Puede ver que el veth tiene una dirección mac. Esto también explica la identidad del conmutador virtual de docker0. El conmutador se comunica a través de la dirección mac y está conectado. al conmutador. El dispositivo debe tener una dirección mac.
Dado que docker0 también tiene una dirección mac, que es diferente de un conmutador de capa 2 puro, y está vinculado a la IP 172.17.0.1, el contenedor utiliza docker0 como puerta de enlace de forma predeterminada. Es decir, docker0 también tiene la función de enrutamiento, por lo que docker0 puede considerarse como un conmutador de capa 3, que puede realizar el reenvío de paquetes de capa 2 y el reenvío de enrutamiento de capa 3.
Ejecute route -n en el contenedor para ver la ruta de la siguiente manera:
Ejecute route -n en el host para ver la ruta de la siguiente manera:
En el host, visite esto El segmento de red 192.168.0.0 reenvía paquetes de datos a través de eth0. El acceso al segmento de red 172.17.0.0 reenvía paquetes de datos a través de docker0. Para otras redes públicas, los paquetes de datos se reenvían a través de eth0 a la puerta de enlace 192.168.0.1. y luego la puerta de enlace Para reenviar paquetes de datos, como navegar por Internet.
Ejecute ping sohu.com o ping 192.168.0.200 en el contenedor para hacer ping correctamente.
De forma predeterminada, no se requiere configuración adicional en un host, a través de docker0, los contenedores pueden comunicarse entre sí y pueden conectarse a la red externa a través del eth0 del host.
En términos sencillos, una Ethernet con un segmento de red de 172.17.0.0/16 se forma a través de docker0. Cuando el contenedor Docker inicia una solicitud, si es el mismo segmento de red, se reenviará al. máquina de destino a través de docker0 Si es diferente, el segmento de red se reenvía a otra tarjeta de red eth0 del host a través de docker0, y eth0 es responsable del siguiente paso del reenvío de paquetes de datos, como la dirección de red pública.
Analicemos más a fondo cómo se envía el mensaje al exterior.
Se envía un mensaje de solicitud de red pública dentro del contenedor a través de eth0 y se recibe en veth. En este momento, el mensaje ha llegado al host. Al consultar la tabla de enrutamiento del host (ruta -n), si se descubre que el mensaje debe enviarse a través del eth0 del host y fuera de la puerta de enlace predeterminada, entonces el mensaje se enviará. reenviado desde docker0 al eth0 del host, pero la premisa es que la función ip_forward debe habilitarse primero antes de que los paquetes de datos puedan transmitirse entre las tarjetas de red docker0 y eth0 del host.
Dado que la dirección de destino no pertenece al segmento de red donde se encuentra el host, coincidirá con las reglas en la cadena POSTROUTING de la tabla nat en iptables en la máquina.
Ejecute el comando iptables -L -n -t nat --line-numbers en el host para ver la tabla nat. Aquí solo miramos la cadena POSTROUTING:
Como. Como se indica en la primera línea, MQSQUERADE enmascara los paquetes de datos cuya dirección de origen es el segmento de red 172.17.0.0/16 antes de enviarlos. El kernel de Linux modificará la dirección de origen del paquete de datos a la dirección del host eth0 (es decir, 192.168.0.200) y luego reenviará el paquete. Al exterior, el mensaje se envía desde el host eth0.
Dado que todas las máquinas en la LAN son IP privadas, no pueden acceder directamente a Internet (los paquetes de datos se pueden enviar, pero no se pueden devolver). Si desea acceder a Internet, además de usar un enrutador de hardware, también puede usar enrutamiento de software, agregar reglas SNAT en la cadena POSTROUTING en la tabla nat de iptables.
Para probar, ejecute el comando iptables -t nat -D POSTROUTING 1 en el host. Luego ejecute el comando ping sohu.com en el contenedor y el ping no funcionará. Pero aún se puede hacer ping al host.
Ejecute el siguiente comando en el host para restaurar:
iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -o eth0 -j SNAT --to-source 192.168.0.200
o
iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -j MASQUERADE
Respecto a SNAT y MASQUERADE, este artículo ya existe Para obtener una descripción, puede consultar: Docker prequel linux iptables
Cree un nuevo Dockerfile para ejecutar el contenedor nginx:
# Versión: 0.0.1 DESDE paulliu/ubuntu_ip EJECUTE apt-get install -y nginx EXPOSE 80
Ejecute el comando de compilación en el host para compilar la imagen acoplable build -t paulliu/nginx
Ejecute el comando de inicio del contenedor en la ventana acoplable del host. run -d -p 80 - -name nginx1 paulliu/nginx nginx -g "daemon off;"
Ver la asignación de puertos del contenedor en el puerto acoplable del host nginx1 80
Ejecute el comando iptables -nat -L en el host host -n. Puede ver que las siguientes reglas DNAT se agregan a la cadena PREROUTING:
Es decir, cuando se inicia el contenedor, se usa -p 80 para asigne el host 192.168.0.200:32773 al contenedor 172.17.0.4:80.
Nota: La dirección IP obtenida cada vez que se inicia el contenedor Docker puede no ser la misma, y -p 80 selecciona aleatoriamente un número de puerto en el host para mapear, y el número de puerto cada vez que se iniciado puede no ser el mismo. Pero las reglas relevantes en iptables se cambian automáticamente.
Ejecute curl localhost:32773 en el host host o curl 192.168.0.200:32773 en otros hosts. Los resultados son los siguientes: