docker和iptables
【摘要】 我们先建1个自定义桥接网络,然后运行2个容器,连接到自定义桥接网络inetwork(而不是默认桥接网络、1个容器也可以连接到多个桥接网络),观察一下iptables的相关规则。默认桥接网络叫bridge,自定义的叫inetwork接口名称默认的是docker0,自定义的是br-xxxbr-b5a3f4778f2a: flags=4099<UP,BROADCAST,MULTICAST> mt...
我们先建1个自定义桥接网络,然后运行2个容器,连接到自定义桥接网络inetwork(而不是默认桥接网络、1个容器也可以连接到多个桥接网络),观察一下iptables的相关规则。
默认桥接网络叫bridge,自定义的叫inetwork
接口名称默认的是docker0,自定义的是br-xxx
br-b5a3f4778f2a: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.19.0.1 netmask 255.255.0.0 broadcast 172.19.255.255
ether 02:42:a2:d5:85:76 txqueuelen 0 (Ethernet)
RX packets 29 bytes 1695 (1.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 42 bytes 3724 (3.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:5eff:fe8d:a3d2 prefixlen 64 scopeid 0x20<link>
ether 02:42:5e:8d:a3:d2 txqueuelen 0 (Ethernet)
RX packets 29 bytes 1695 (1.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 42 bytes 3724 (3.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
来看iptables的NAT规则:
POSTROUTING是SNAT 让容器内去访问外部网络的
PREROUTING是DNAT 让外部网络来的访问转换/映射到容器内
[root@ecs-d589 ~]# iptables -t nat -S
#Policy
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
#建立一个自定义链
-N DOCKER
#下面这条自用的,与docker无关
-A PREROUTING -d 10.0.0.27/32 -i eth0 -p tcp -m tcp --dport 24 -j DNAT --to-destination 10.0.0.97:22
#使用-m addrtype模块,目的是本地网络的,用DOCKER链处理,只是做了框架,无实质处理
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
#下面2个规则是说,来自于容器内2个桥接网络内的数据包,要出去的,都做SNAT(源地址转换为出口网卡的IP)
#要出去,就是由! -o指定,即出口网卡接口不是br-xx和docker0
-A POSTROUTING -s 172.19.0.0/16 ! -o br-b5a3f4778f2a -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -o eth0 -j MASQUERADE #这条自用的,与docker无关
#
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
#自定义链DOCKER的规则 无实际处理
-A DOCKER -i br-b5a3f4778f2a -j RETURN
-A DOCKER -i docker0 -j RETURN
我们启动2个容器
docker run -d -i -p 1234:1234 --name daemon1 --network inetwork ubuntu:14.04 nc -l 1234
docker run -d -i -p 1235:1235 --name daemon2 --network inetwork ubuntu:14.04 nc -l 1235
再看一下规则
[root@ecs-d589 ~]# iptables -t nat -S
#不变的规则去掉了一些
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.19.0.0/16 ! -o br-b5a3f4778f2a -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
#下面2条难以理解,原因就是source和dest一样,不过不理解不影响我们继续
-A POSTROUTING -s 172.19.0.2/32 -d 172.19.0.2/32 -p tcp -m tcp --dport 1234 -j MASQUERADE
-A POSTROUTING -s 172.19.0.3/32 -d 172.19.0.3/32 -p tcp -m tcp --dport 1235 -j MASQUERADE
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i br-b5a3f4778f2a -j RETURN
-A DOCKER -i docker0 -j RETURN
#做DNAT,将外来的数据包访问1234端口的,转到对应的容器内
-A DOCKER ! -i br-b5a3f4778f2a -p tcp -m tcp --dport 1234 -j DNAT --to-destination 172.19.0.2:1234
-A DOCKER ! -i br-b5a3f4778f2a -p tcp -m tcp --dport 1235 -j DNAT --to-destination 172.19.0.3:1235
[root@ecs-d589 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
169.254.169.254 10.0.0.254 255.255.255.255 UGH 100 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.19.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-b5a3f4778f2a
对于每一个映射的端口,都会启动一个docker-proxy进程来处理访问容器的流量。下图可以做个参考
docker port 可以查看容器的端口映射情况
启动docker后会添加iptables规则,停止docker服务后一些基本规则不会删除。重启机器后会还原为最初的样子
再看一下filter表,启动docker后
[root@ecs-d589 ~]# iptables -S
-P INPUT ACCEPT
-P FORWARD DROP #默认是DROP!!!
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1 #STAGE1里会再跳转STAGE2
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER #只是框架 无实际规则
#好像就状态跟踪conntrack有点用处
-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 FORWARD -o br-b5a3f4778f2a -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-b5a3f4778f2a -j DOCKER
-A FORWARD -i br-b5a3f4778f2a ! -o br-b5a3f4778f2a -j ACCEPT
-A FORWARD -i br-b5a3f4778f2a -o br-b5a3f4778f2a -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-b5a3f4778f2a ! -o br-b5a3f4778f2a -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 -o br-b5a3f4778f2a -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
启动2个容器后
#添加了2条规则 外面网络来的到容器的访问,到达主机,PREROUTING后,路由,会走FORWARD,而不是INPUT本地处理
-A DOCKER -d 172.19.0.2/32 ! -i br-b5a3f4778f2a -o br-b5a3f4778f2a -p tcp -m tcp --dport 1234 -j ACCEPT
-A DOCKER -d 172.19.0.3/32 ! -i br-b5a3f4778f2a -o br-b5a3f4778f2a -p tcp -m tcp --dport 1235 -j ACCEPT
docker不会动mangle表
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)