当docker-demon启动时,它会向iptables添加一些规则。
当通过iptables -F
删除所有规则时,我必须停止并重新启动docker demon以重新创建docker规则。
有没有办法让docker重新添加它的附加规则?
答案 0 :(得分:16)
最好的方法是重新启动docker服务,然后将Docker规则重新添加到iptables。 (基于deb的:sudo service docker restart
)
但是,如果您只想在不重新启动服务的情况下恢复这些规则,我保存了我的,以便您可以检查并调整它以适合您,然后使用sudo iptables-restore ./iptables-docker-ports.backup
编辑并将其保存到./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
答案 1 :(得分:8)
如果您在主机上运行Ubuntu,则可以在启动docker守护程序后使用iptables-save
实用程序将iptables规则保存到文件中。然后,一旦刷新旧规则,您只需使用iptables-restore
&恢复原始泊坞机规则即可。保存的规则文件。
如果您不想恢复所有旧的iptables规则,则可以更改已保存的规则文件以仅保留您需要的规则。
如果您正在运行其他操作系统,您可能会找到类似的替代方案。
答案 2 :(得分:3)
默认配置下的Docker在bridge
模式下运行时,确实会操纵iptables
(很多)unless you disable it(然后您必须配置自己的NAT规则)。
以下可能是与网络相关的默认配置,尽管配置/etc/docker/daemon.json
可能不存在(到目前为止you can't print effective configuration):
{
"userland-proxy": true,
"iptables": true,
"ip-forward": true,
"ip-masq": true,
"ipv6": false
}
Docker守护程序启动后,它将注入以下规则(在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
为了了解Docker的功能,此处为a list of Docker-generated iptables
rules,并附有简短说明。如果刷新iptables规则,则在Docker守护程序和某些容器正在运行时,您可能会中断对现有容器的访问(但可能不会破坏任何内容,更多信息请参见下文)。
在service docker restart
之后,所有默认规则都被注入防火墙(您可以通过运行iptables-save
或iptables -S
,iptables -S -t nat
来对其进行检查)。假设您要保持容器运行,并且仅生成缺少的NAT规则。
docker ps
向我们提供了正在运行的容器的列表:
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
然后从docker inspect
中获得端口映射
$ docker inspect -f '{{.NetworkSettings.Ports}}' 865569da8d36
map[80/tcp:[{0.0.0.0 4564} {0.0.0.0 32237}]]
现在我们只需要Docker容器的内部IP地址:
$ docker inspect -f '{{.NetworkSettings.IPAddress}}' 865569da8d36
172.17.0.2
现在使用一些bash / jq,我们可以generate the dynamic iptables rules:
$ 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
因此,问题的答案是:不,并非没有停止所有容器。但是可以手动添加规则(注意:此脚本不能涵盖所有Docker功能,例如,如果您要公开运行在Docker容器以外的其他网络中的某些服务)。
使用暴露的端口(-p
)启动Docker容器时:
docker run --rm -d -p 32237:80 -p 4564:80 nginx
Docker也旋转docker-proxy
。那是什么?
$ 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
Linux内核不允许路由回送流量,因此无法将netfilter NAT规则应用于源自127.0.0.0/8的数据包。 docker-proxy
is generally considered as an inelegant solution to such problems。
在没有Docker规则的情况下还原iptables时,容器端口可能仍可以通过docker-proxy
使用。但是,这可能会带来一些performance issues in networking,因为docker-proxy
不会像内核的netfilter一样快。