首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker:如何重新创建Docker附加iptables规则?

问Docker:如何重新创建Docker附加iptables规则?
EN

Stack Overflow用户
提问于 2014-09-19 00:31:52
回答 3查看 47.7K关注 0票数 43

当docker-demon启动时,它会向iptables添加一些规则。当通过iptables -F删除所有规则时,我必须停止并重启docker后台程序以重新创建docker规则。

有没有办法让docker重新添加它的附加规则?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-01 08:53:35

最好的方法是重新启动docker服务,然后它会将docker规则重新添加到iptables中。(基于deb的:sudo service docker restart)

但是,如果您只想在不重新启动服务的情况下恢复这些规则,我保存了我的规则,以便您可以检查和调整它以适合您,然后使用sudo iptables-restore ./iptables-docker-ports.backup加载

编辑此文件并将其保存到./iptables-docker-ports.backup

代码语言:javascript
复制
# 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
票数 42
EN

Stack Overflow用户

发布于 2014-09-19 02:23:43

如果您在主机上运行Ubuntu,则可以在启动docker守护进程后使用iptables-save实用程序将iptables规则保存到一个文件中。然后,一旦刷新了旧规则,就可以使用iptables-restore恢复原始的docker规则&保存的规则文件。

如果不想恢复所有旧的iptables规则,可以修改已保存的规则文件,使其只保留所需的规则。

如果您运行的是另一个操作系统,您可能会找到一个类似的替代方案。

票数 10
EN

Stack Overflow用户

发布于 2020-05-22 16:20:08

默认配置的Docker在bridge模式下运行时,确实会操纵iptables (很多) unless you disable it (然后您必须配置自己的NAT规则)。

默认的网络相关配置可能如下所示,尽管配置/etc/docker/daemon.json可能不存在(从现在的you can't print effective configuration开始):

代码语言:javascript
复制
{
"userland-proxy": true,
"iptables": true,
"ip-forward": true,
"ip-masq": true,
"ipv6": false
}

Docker守护进程启动后,会注入以下规则(在filter中):

代码语言:javascript
复制
-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为我们提供了运行容器的列表:

代码语言:javascript
复制
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,我们可以得到端口映射

代码语言:javascript
复制
$ docker inspect -f '{{.NetworkSettings.Ports}}' 865569da8d36
map[80/tcp:[{0.0.0.0 4564} {0.0.0.0 32237}]]

现在我们只需要Docker容器的内部IP地址:

代码语言:javascript
复制
$ docker inspect -f '{{.NetworkSettings.IPAddress}}' 865569da8d36
172.17.0.2

现在使用一些bash/jq,我们可以generate the dynamic iptables rules

代码语言:javascript
复制
$ 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容器时:

代码语言:javascript
复制
docker run --rm -d -p 32237:80 -p 4564:80 nginx

Docker也推出了docker-proxy。那是什么?

代码语言:javascript
复制
$ 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那样快。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25917941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档