Docker最近推出了
docker network
的功能,允许用户自己创建网络。刚好手头合租了一台服务器想试试。
这台服务器有4个公网ip(173.208.194.202,203,205,206/29)。我单独占了个173.208.194.205。我期待的效果是:这个docker network内创建的容器,默认会publish到173.208.194.205(即外界连.205:port也能访问到映射的容器);并且容器内对外connect时,默认的localaddr也是.205。
创建网络并设置默认publish IP
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="173.208.194.205" htfy_net
这里的host_binding_ipv4在 https://docs.docker.com/engine/userguide/networking/work-with-networks/#linking-containers-in-user-defined-networks 的文档有提到,指的是会把默认的
-p host_port:container_port
转化成-p173.208.194.205:host_port:container_port
。
让我们看看效果,首先知道
htfy_net
的子网是172.18.0.0/16
,然后创建一个容器172.18.0.3,-p 80:80 --network htfy_net
,然后iptables -L -t nat
看看怎么回事:Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL (1)
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL (2)
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.18.0.0/16 0.0.0.0/0 (3)
MASQUERADE tcp -- 172.18.0.3 172.18.0.3 tcp dpt:80 (4)
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 173.208.194.205 tcp dpt:80 to:172.18.0.3:80 (5)
截至目前为止,外界发往173.208.194.205:80的包,会经过(1), (5)改写成到172.18.0.3的包。看起来很正常。但不幸的是,对外connect的包,在(3)的作用下会被MASQUERADE到网卡第一个IP(173.208.194.202)上,这很明显不是我们想要的。
设置默认LocalAddr
在上网查找方案时,发现了 https://github.com/docker/docker/issues/8519 ,不过似乎开发者没有明白这位同学的意图。既然这样就只有手动修改了。把MASQUERADE改成硬点IP的手动nat
iptables -t nat -R POSTROUTING 4 -s 172.18.0.0/16 -d 0.0.0.0/0 -j SNAT --to-source 173.208.194.205
之后的效果:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL (1)
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL (2)
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 172.18.0.0/16 0.0.0.0/0 to:173.208.194.205 (3')
MASQUERADE tcp -- 172.18.0.3 172.18.0.3 tcp dpt:80 (4)
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 173.208.194.205 tcp dpt:80 to:172.18.0.3:80 (5)
对外的包经过3’规则被改成了source=173.208.194.205,这样以后
docker run --network htfy_net
的所有容器都能绑定到这个.205的IP了,实现了IP隔离.
No comments:
Post a Comment