
Estaba trabajando con contenedores Docker con --network host
set y me di cuenta de que si me vinculo a un puerto en un contenedor, aún puedo iniciar un segundo que se vincule al mismo puerto sin ningún mensaje de error.
netstat
Luego mostrará el PID del segundo contenedor como escuchando en lugar del PID del primero.
Pasos para reproducir:
[root@test]# cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="9.2 (Plow)"
...
[root@test]# docker --version
Docker version 23.0.6, build ef23cbc
[root@test]# docker run -d --rm --network host --name container01 debian nc -l -p 80
7bc250856c7ddde57eb48f57ba800391577c728ec856da24bf80a9df8e766c84
[root@test]# netstat -tulpen | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 10435480 2162661/nc
[root@test]# docker run -d --rm --network host --name container02 debian nc -l -p 80
10897d7dea695446db48bff9d3b338554a7cd0535f30625f06b6e5f959bf8df2
[root@test]# netstat -tulpen | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 10436217 2162708/nc
[root@test]# ps auxf
root 2162640 0.0 0.5 720496 10608 ? Sl 11:03 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 7bc250856c7ddde57eb48f57ba800391
root 2162661 0.0 0.0 3200 1116 ? Ss 11:03 0:00 \_ nc -l -p 80
root 2162686 0.0 0.5 720496 10028 ? Sl 11:03 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 10897d7dea695446db48bff9d3b33855
root 2162708 0.0 0.0 3200 1060 ? Ss 11:03 0:00 \_ nc -l -p 80
Las conexiones existentes con el primer contenedor siguen funcionando incluso después de que se inicia el segundo. Todas las nuevas conexiones irán al segundo.
Por supuesto, vincularse al mismo puerto directamente en el host no funciona y el contenedor tampoco puede vincularse a un puerto en el que el host ya está listado.
Entonces mi pregunta es: ¿En qué se diferencian exactamente los contenedores para que puedan superar un puerto ya existente?
Respuesta1
Es prácticamente la misma forma en que puede tener múltiples sesiones en un solo puerto desde el mismo cliente. Las conexiones utilizan unpar de enchufes(que incluye un puerto efímero único del lado del cliente) para identificarse. El host utiliza estos pares únicos para enviar tráfico a la identificación del proceso correcto, a veces incluso después de que el puerto del host haya sido vinculado por un proceso diferente. Deben permanecer activos hasta que el host cierre el puerto, finalice esas sesiones, finalice esa identificación de proceso, etc.
Existen algunas limitaciones sobre cómo el software puede permitir volver a vincularse a puertos según el sistema operativo y las opciones disponibles. Encontré algunos buenos detalles sobre eso y el proceso de enlace (en Linux) en las respuestas aquí:¿Pueden dos aplicaciones escuchar el mismo puerto?