Solución:
la mejor manera es reiniciar el servicio de la ventana acoplable, luego volverá a agregar las reglas de la ventana acoplable a iptables. (en basado en deb: sudo service docker restart
)
sin embargo, si solo desea restaurar esas reglas sin reiniciar su servicio, guardé el mío para que pueda inspeccionarlo y ajustarlo para que funcione para usted, luego cargue usando sudo iptables-restore ./iptables-docker-ports.backup
editar y guardar esto en ./iptables-docker-ports.backup
# Generated by iptables-save v1.4.21 on Thu Apr 30 20:48:42 2015
*nat
:PREROUTING ACCEPT [18:1080]
:INPUT ACCEPT [18:1080]
:OUTPUT ACCEPT [22:1550]
:POSTROUTING ACCEPT [22:1550]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.1/32 -d 172.17.0.1/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 3001 -j DNAT --to-destination 172.17.0.1:80
COMMIT
# Completed on Thu Apr 30 20:48:42 2015
# Generated by iptables-save v1.4.21 on Thu Apr 30 20:48:42 2015
*filter
:INPUT ACCEPT [495:53218]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [480:89217]
:DOCKER - [0:0]
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.1/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Thu Apr 30 20:48:42 2015
Si está ejecutando Ubuntu en el host, puede usar el iptables-save
utilidad para guardar las reglas de iptables en un archivo después de iniciar el demonio de la ventana acoplable. Luego, una vez que elimine las reglas anteriores, simplemente puede restaurar las reglas originales de la ventana acoplable usando iptables-restore
& el archivo de reglas guardado.
Si no desea restaurar todas las reglas antiguas de iptables, puede modificar el archivo de reglas guardado para conservar solo las que necesita.
Si está ejecutando otro sistema operativo, puede encontrar una alternativa similar.
Docker en la configuración predeterminada, cuando se ejecuta en bridge
modo, manipula iptables
(mucho) a menos que lo desactive (entonces tendría que configurar sus propias reglas NAT).
La configuración predeterminada relacionada con la red probablemente sea la siguiente, aunque la configuración /etc/docker/daemon.json
podría no existir (y a partir de ahora no puede imprimir la configuración efectiva):
{
"userland-proxy": true,
"iptables": true,
"ip-forward": true,
"ip-masq": true,
"ipv6": false
}
Una vez que se inicia el demonio de Docker, inyecta las siguientes reglas (en filter
):
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
Para comprender lo que hace Docker, aquí hay una lista de iptables
reglas con una breve explicación. Si elimina las reglas de iptables, mientras el demonio de Docker y algunos contenedores se están ejecutando, puede romper el acceso a los contenedores existentes (pero probablemente no romperá nada, más sobre esto a continuación).
Después service docker restart
todas las reglas predeterminadas se inyectan en el firewall (puede verificarlo ejecutando iptables-save
o iptables -S
, iptables -S -t nat
). Suponiendo que desea mantener sus contenedores en funcionamiento y solo generar reglas NAT faltantes.
docker ps
nos da una lista de contenedores en ejecución:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
865569da8d36 nginx "nginx -g 'daemon of…" 17 hours ago Up 17 hours 0.0.0.0:4564->80/tcp, 0.0.0.0:32237->80/tcp jovial_sammet
Y de docker inspect
podemos obtener el mapeo de puertos
$ docker inspect -f '{{.NetworkSettings.Ports}}' 865569da8d36
map[80/tcp:[{0.0.0.0 4564} {0.0.0.0 32237}]]
ahora solo necesitamos la dirección IP interna del contenedor Docker:
$ docker inspect -f '{{.NetworkSettings.IPAddress}}' 865569da8d36
172.17.0.2
Ahora, usando bash / jq podemos generar las reglas dinámicas de iptables:
$ bash docker_iptables --noop
iptables -A DOCKER -d 172.17.0.2
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 4564 -j DNAT --to-destination 172.17.0.2:80
iptables -A DOCKER -d 172.17.0.2
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 32237 -j DNAT --to-destination 172.17.0.2:80
Entonces, la respuesta a la pregunta es: No, no sin detener todos los contenedores. Pero las reglas se pueden volver a agregar manualmente (NOTA: este script no cubre todas las funciones de Docker, por ejemplo, si está exponiendo algún servicio que se ejecuta en otra red que no sea el contenedor de Docker).
Cuando inicia el contenedor Docker con puertos expuestos (-p
):
docker run --rm -d -p 32237:80 -p 4564:80 nginx
Docker también gira docker-proxy
. ¿Que es eso?
$ netstat -tulpn | grep docker-proxy
tcp 0 0 0.0.0.0:32237 0.0.0.0:* LISTEN 20487/docker-proxy
tcp 0 0 0.0.0.0:4564 0.0.0.0:* LISTEN 20479/docker-proxy
El kernel de Linux no permite el enrutamiento del tráfico de bucle de retorno y, por lo tanto, no es posible aplicar las reglas de NAT de netfilter a los paquetes que se originan en 127.0.0.0/8. docker-proxy
se considera generalmente como una solución poco elegante a tales problemas.
Cuando restaura iptables sin las reglas de Docker, es posible que los puertos del contenedor aún estén disponibles a través de docker-proxy
. Sin embargo, esto puede traer algunos problemas de rendimiento en redes, como docker-proxy
no será tan rápido como el filtro de red del kernel.