Si hallas algún error con tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al proyecto final.
Solución:
No puede hacer esto a través de Docker, pero puede acceder al puerto no expuesto del contenedor desde la máquina host.
Si tiene un contenedor con algo ejecutándose en su puerto 8000, puede ejecutar
wget http://container_ip:8000
Para obtener la dirección IP del contenedor, ejecute los 2 comandos:
docker ps
docker inspect container_name | grep IPAddress
Internamente, Docker paga para llamar a iptables cuando ejecuta una imagen, por lo que tal vez funcione alguna variación de esto.
Para exponer el puerto 8000 del contenedor en el puerto 8001 de su host local:
iptables -t nat -A DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000
Una forma de resolver esto es configurar otro contenedor con la asignación de puertos que desea y comparar la salida del iptables-guardar comando (sin embargo, tuve que eliminar algunas de las otras opciones que obligan al tráfico a pasar por el proxy acoplable).
NOTA: esto es subvertir la ventana acoplable, por lo que debe hacerse con la conciencia de que puede crear humo azul.
O
Otra alternativa es mirar la opción (¿nueva? ¿publicada en 0.6.6?) -P, que usará puertos de host aleatorios y luego los conectará.
O
Con 0.6.5, ¿podría usar la función LINK para abrir un nuevo contenedor que se comunique con el existente, con alguna retransmisión adicional a las banderas -p de ese contenedor? (Todavía no he usado LINK).
O
Con la ventana acoplable 0.11? puedes usar docker run --net host ..
para adjuntar su contenedor directamente a las interfaces de red del host (es decir, net no tiene espacio de nombres) y, por lo tanto, todos los puertos que abre en el contenedor están expuestos.
Esto es lo que haría:
- Confirme el contenedor vivo.
- Vuelva a ejecutar el contenedor con la nueva imagen, con los puertos abiertos (recomiendo montar un volumen compartido y abrir también el puerto ssh)
sudo docker ps
sudo docker commit
sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t /bin/bash
Si bien no puede exponer un nuevo puerto de un existente contenedor, puede iniciar un nuevo contenedor en la misma red de Docker y hacer que reenvíe el tráfico al contenedor original.
# docker run
--rm
-p $PORT:1234
verb/socat
TCP-LISTEN:1234,fork
TCP-CONNECT:$TARGET_CONTAINER_IP:$TARGET_CONTAINER_PORT
Ejemplo resuelto
Inicie un servicio web que escuche en el puerto 80, pero no no exponer su puerto interno 80 (¡ups!):
# docker run -ti mkodockx/docker-pastebin # Forgot to expose PORT 80!
Encuentre su IP de red Docker:
# docker inspect 63256f72142a | grep IPAddress
"IPAddress": "172.17.0.2",
Lanzar verb/socat
con el puerto 8080 expuesto, y haz que reenvíe el tráfico TCP al puerto 80 de esa IP:
# docker run --rm -p 8080:1234 verb/socat TCP-LISTEN:1234,fork TCP-CONNECT:172.17.0.2:80
Ahora puede acceder a pastebin en http://localhost:8080/, y sus solicitudes van a socat:1234
que lo reenvía a pastebin:80
y la respuesta recorre el mismo camino a la inversa.