exposicion - mapeo de puertos docker
¿Cómo asigno una asignación de puerto a un contenedor Docker existente? (12)
No estoy seguro de haber entendido mal algo aquí, pero parece que solo es posible establecer asignaciones de puertos creando un nuevo contenedor a partir de una imagen. ¿Hay alguna forma de asignar un mapeo de puertos a un contenedor Docker existente?
Al revés, si no se siente cómodo con la configuración de profundidad de Docker, IPtables sería su amigo.
iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT}
iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT}
iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}
Esto es solo un truco, no una forma recomendada. Esto funciona con mi escenario porque no pude detener el contenedor, espero que también te ayude.
Como complemento de la response de
También puede usar $ docker run -P CONTAINER
para asignar puertos al azar mientras crea su contenedor, ¡pero tenga cuidado con la seguridad!
-P
eq to--publish-all
: "--publish-all
todos los puertos expuestos a puertos aleatorios",
luego ejecute la docker inspect CONTAINER
a la asignación de puertos de aletas como se muestra en la siguiente imagen:
Lea más acerca de la docker run -P
acoplable docker run -P
en la docker run -P
acoplable
Editar hostconfig.json parece no funcionar ahora. Solo termina con ese puerto expuesto pero no publicado en el host. Comprometer y recrear contenedores no es el mejor enfoque para mí. ¿Nadie mencionó la docker network
?
La mejor solución sería usar proxy invertido dentro de la misma red.
Cree una nueva red si su contenedor anterior no está en ninguno de los nombrados.
docker network create my_network
Únete a tu contenedor existente a la red creada.
docker network connect my_network my_existing_container
Inicie un servicio de proxy invertido (por ejemplo, nginx) publicando los puertos que necesita, uniéndose a la misma red
docker run -d --name nginx --network my_network -p 9000:9000 nginx
Opcionalmente elimine el default.conf en nginx
docker exec nginx rm /etc/nginx/conf.d/default.conf
Crear una nueva configuración nginx
server { listen 9000; location / { proxy_pass http://my_existing_container:9000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection ''upgrade''; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
Copie la configuración al contenedor nginx.
docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf
Reinicie nginx
docker restart nginx
Ventajas : para publicar nuevos puertos, puede detener / actualizar / volver a crear de forma segura el contenedor nginx como desee sin tocar el contenedor empresarial. Si necesita cero tiempos de inactividad para nginx, es posible agregar más servicios de proxy invertido que se unan a la misma red. Además, un contenedor puede unir más de una red.
Editar:
Para revertir los servicios proxy no http, el archivo de configuración es un poco diferente. Aquí hay un ejemplo simple:
upstream my_service {
server my_existing_container:9000;
}
server {
listen 9000;
proxy_pass my_service;
}
En el ejemplo de Fujimoto Youichi, test01
es un contenedor, mientras que test02
es una imagen.
Antes de docker run
, puede eliminar el contenedor original y luego volver a asignar el mismo nombre al contenedor:
$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01
(Utilizando -P
para exponer los puertos a puertos aleatorios en lugar de asignar manualmente).
No estoy seguro si puede aplicar la asignación de puertos a un contenedor en ejecución. Puede aplicar el reenvío de puertos mientras ejecuta un contenedor que es diferente a crear un nuevo contenedor.
$ docker run -p <public_port>:<private_port> -d <image>
comenzará a correr el contenedor. Este tutorial explica la redirección de puertos.
No puedo creer cuántas respuestas incorrectas en una página. Si lo haces "docker Run" generará una nueva imagen.
Si quieres cambiar una imagen actual haz lo siguiente.
docker ps -a
toma la identificación del contenedor y ve a
cd /var/lib/docker/containers/<conainerID><and then some:)>
detener el contenedor
''docker stop <NAME>''
cambiar los archivos
vi config.v2.json
"Config": {
....
"ExposedPorts": {
"80/tcp": {},
"8888/tcp": {}
},
....
},
"NetworkSettings": {
....
"Ports": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
y cambiar archivo
vi hostconfig.json
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
"8888/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}
]
}
reinicie su ventana acoplable y debería funcionar
Para usuarios de Windows y Mac, ahora hay otra manera bastante fácil y amigable de cambiar el puerto de mapeo:
descarga el kitematic
Vaya a la página de configuración del contenedor, en la pestaña de puertos, puede modificar directamente el puerto publicado allí.
volver a empezar el contenedor
Puede cambiar la asignación de puertos editando directamente el archivo /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
en /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
Puede determinar el [hash_of_the_container] mediante el comando de docker inspect <container_name>
la ventana docker inspect <container_name>
y el valor del campo "Id" es el hash.
1) stop the container
2) change the file
3) restart your docker engine (to flush/clear config caches)
4) start the container
Por lo tanto, no es necesario crear una imagen con este enfoque. También puede cambiar la bandera de reinicio aquí.
PS Puede visitar https://docs.docker.com/engine/admin/ para obtener información sobre cómo reiniciar correctamente el motor de la ventana acoplable según la máquina host. sudo systemctl restart docker
para reiniciar mi motor docker que se ejecuta en Ubuntu 16.04
Si por "existente" quiere decir "en ejecución", no es posible (actualmente) agregar una asignación de puerto.
Sin embargo, puede agregar dinámicamente una nueva interfaz de red con, por ejemplo, Pipework , si necesita exponer un servicio en un contenedor en ejecución sin detenerlo / reiniciarlo.
Si simplemente desea cambiar el puerto del contenedor en ejecución, haga lo siguiente:
- detener el contenedor existente
sudo docker stop NAME
- ahora reinicie con el nuevo mapeo de puertos
sudo docker run -d -p 81:80 NOMBRE
donde como
"-d" para el fondo / deamon la ventana acoplable
"-p" permite la asignación de puertos
"81" puerto externo (expuesto) que utiliza para acceder con su navegador
Puerto de escucha de contenedor acoplable interno "80"
También estoy interesado en este problema.
Como se mencionó en @Thasmo , los reenvíos de puertos se pueden especificar SOLAMENTE con el comando de docker run
@Thasmo docker run
.
Otros comandos, el docker start
no tiene la opción -p
y el docker port
solo muestra los reenvíos actuales.
Para agregar reenvíos de puertos, siempre sigo estos pasos,
stop correr contenedor
docker stop test01
commit el contenedor
docker commit test01 test02
NOTA: Lo anterior,
test02
es una nueva imagen que estoy construyendo desde el contenedortest01
.volver a run desde la imagen comprometida
docker run -p 8080:8080 -td test02
Donde el primer 8080 es el puerto local y el segundo 8080 es el puerto de contenedor.
Usamos herramientas útiles como ssh para lograr esto fácilmente.
Estaba usando el host de ubuntu y la imagen de docker basada en ubuntu.
- Dentro de la ventana acoplable se ha instalado openssh-client.
- El docker exterior (host) tiene el servidor openssh-server instalado.
cuando se necesita un nuevo puerto para ser mapeado,
dentro de la ventana acoplable ejecuta el siguiente comando
ssh -R8888:localhost:8888 <username>@172.17.0.1
172.17.0.1 era la ip de la interfaz de la ventana acoplable (puede obtener esto ejecutando ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "
en el host).
aquí tuve el puerto 8888 local asignado de nuevo a los hosts 8888. Puedes cambiar el puerto según sea necesario.
Si necesita un puerto más, puede matar el ssh y agregar una línea más de -R con el nuevo puerto.
He probado esto con netcat.