Premisa:
Estoy tratando de unirmereciente aprendiendosobre interfaces y puertos de red e intentar vincular ese nuevo aprendizaje con Docker.
Un resumen rápido de las cosas que aprendí relevantes para esta pregunta:
- Cada computadora puede tener múltiples direcciones IP, una para cada interfaz de red.
- Las direcciones IP se asignan a interfaces, no a computadoras, etc.
- Un socket es un puerto IP+.
- DHCP es a menudo/probablemente lo que asigna una dirección IP a una interfaz.
Como ocurre con muchos aspectos del trabajo con software, primero hago las cosas según el "ritual" que aprendo, porque "así es como se hace". Luego, con el tiempo y la experiencia, empiezo a reflexionar y a investigar los porqués. Por eso me gustaría vincular este nuevo aprendizaje con Docker.
El "ritual" que aprendí es que si una aplicación en contenedor está escuchando en un socket TCP, es necesario "exponer" el puerto de ese socket para que el tráfico que llega a una de las interfaces del host en ese puerto sea "reenviado" al envase.
Por ejemplo, docker run -d -p 81:80 httpd
configura las cosas de modo que si apunto mi navegador web a 127.0.0.81, ese tráfico HTTP/TCP/IP se "reenvía" alhttpdpuerto de contenedores 80.
Entonces, cuando apunto mi navegador web a 127.0.0.1:81, veo el mensaje "¡Funciona!" de Apache. mensaje.
Pero también: si apunto mi navegador web a 127.0.0.2:81 o 127.0.0.dieciséis:81, luego también veo el mensaje "¡Funciona!" de Apache. mensaje.
Como aprendí de las publicaciones vinculadas, DHCP asignó a la interfaz de mi NIC la dirección IP 10.0.0.17, y si apunto mi navegador web a 10.0.0.17:81, aquí nuevamente veo el mensaje "¡Funciona!" de Apache. mensaje.
También funciona si apunto el navegador web de otra PC en la misma red a 10.0.0.17:81.
Pregunta:
mi primariapreguntaes: ¿para cuál de las interfaces de la PC host (direcciones IP) se reenvían los puertos del host al contenedor cuando lo hace docker run
con el -p
argumento? Según la observación señalada, la respuesta parece ser "todas las interfaces": ¿es ese el caso?
Sin embargo, en términos más generales: ¿cuál es la relación entre las interfaces y los puertos entre una PC host y un contenedor Docker?
lo que he probado
Intenté leer el docker run
texto de ayuda, pero su texto -p
no está en un nivel en el que pueda relacionarlo con las preguntas que estoy haciendo:
-p, --publish list Publica los puertos de un contenedor en el host
Intenté ejecutar mirando ifconfig
en el contexto de mi PC y la ejecuciónhttpdenvase.
ifconfig
en la PC anfitriona:
$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:caff:fe23:f0f4 prefixlen 64 scopeid 0x20<link>
ether 02:42:ca:23:f0:f4 txqueuelen 0 (Ethernet)
RX packets 3079 bytes 322688 (322.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6429 bytes 15942682 (15.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 17975 bytes 1557651 (1.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 17975 bytes 1557651 (1.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.17 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::5f8c:c301:a6a3:6e35 prefixlen 64 scopeid 0x20<link>
ether f8:59:71:01:89:cf txqueuelen 1000 (Ethernet)
RX packets 1672559 bytes 2237440808 (2.2 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 726083 bytes 113598143 (113.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig
en la marchahttpdcontenedor (lo instalé con apt-get
):
# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 1326 bytes 8916833 (8.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1134 bytes 76866 (75.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Poniendo esta pregunta en el contexto del ifconfig
resultado anterior, ¿cuál es la relación entre esas interfaces en la PC host y las interfaces en el contenedor acoplable?
Deaquí, tengo entendido que DHCP asignó 10.0.0.17 a la NIC en mi PC host. ¿Pero de dónde viene el 172.17.0.3?
Respuesta1
[NB: Parece que tiene tres preguntas aquí, al menos una de las cuales es demasiado amplia para tener una respuesta clara y aceptable. En general, SuperUser funciona mejor si solo hace una pregunta estrechamente definida por publicación de preguntas.]
Mi pregunta principal es: ¿para cuál de las interfaces de la PC host (direcciones IP) se reenvían los puertos del host al contenedor cuando ejecuta la ventana acoplable con el argumento -p? Según la observación señalada, la respuesta parece ser "todas las interfaces": ¿es ese el caso?
Sí.
Sin embargo, en términos más generales: ¿cuál es la relación entre las interfaces y los puertos entre una PC host y un contenedor Docker?
Esto es demasiado amplio para responder bien sin indicarle la documentación de redes de Docker. Docker contiene muchas opciones de red diferentes que cambian las relaciones entre interfaces y puertos entre las PC host y los contenedores Docker. Es muy flexible.
¿Pero de dónde viene el 172.17.0.3?
El modo de red predeterminado de Docker,puente de red, crea un puente de software (como un conmutador Ethernet virtual) en el host y conecta los contenedores a través de interfaces de red virtuales. Como una pequeña LAN Ethernet virtual, todo dentro del host. Luego utiliza NAT (muy parecido a lo que usaría un enrutador de puerta de enlace doméstico) para permitir que sus contenedores lleguen a la red más allá del host. La NAT utiliza la subred 172.17.0.0/16 como subred privada.
Docker usa esa subred porque es parte del espacio de direcciones privadas RFC 1918, al igual que 192.168.0.0/16, 10.0.0.0/8 y el resto de 172.dieciséis.0.0/12.
Parece que Docker configura mediante programación los contenedores con direcciones estáticas en esa subred (DHCP complicaría innecesariamente las cosas).