docker集装箱中的基于端口的路由
我有一个docker应用程序容器( node:latest
形象),它有两个networking接口:
- eth1:这是一个默认的接口,是来自服务的所有容器之间的桥接networking。 (由
pipework
pipe理,但我不能在这个层面上改变任何东西) - eth0:这是一个普通的
docker0
接口,除eth1
以外的所有地方都可以访问。
这里是默认的路由表:
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.25.88.254 0.0.0.0 UG 0 0 0 eth1 10.25.88.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
正如你所看到的,有必要将eth1
作为默认接口,但是这会导致我一个问题:我的应用程序需要ssh
访问一些其他远程服务器,这些服务器不能通过eth1
访问,但eth0
有访问权限。 所以我需要改变这个请求的路线。 我的第一个解决scheme是:
route add -net 10.20.33.0/24 gw 172.17.42.1
这种方法工作正常,我将获得访问范围10.20.33.0/24
地址。 但它会阻止从主机访问应用程序本身。 应用程序在端口80上运行,添加此路由后,来自10.20.33.0/24
范围内的主机的所有请求10.20.33.0/24
将失败。
所以我想这条路线是如此全球化,并影响所有input/输出请求的IP范围。 我search了一个方法,只是路由输出ssh请求遍及stackoverflow,迄今为止,这是我有:
# Initialize route table echo 1 p.ssh > /etc/iproute2/rt_tables ip route add table p.ssh default via 172.17.42.1 # Mark Packet with matching D.Port iptables -A PREROUTING -t mangle -p tcp --dport 22 -j MARK --set-mark 1 iptables -A POSTROUTING -t nat -o eth0 -p tcp --dport 22 -j SNAT --to 172.17.42.1 #IP Route ip rule add fwmark 1 table p.ssh ip route flush cache #IP Stack #This is the missing part from the guide echo 1 > /proc/sys/net/ipv4/ip_forward for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $f ; done echo 0 > /proc/sys/net/ipv4/route/flush
但它不工作。 我试过用iptables
logging标记的软件包,所以也许我可以在这个过程中发现任何问题,但是syslog
没有在容器中运行,所以我安装了apt-get install rsyslog
并添加了这个规则:
iptables -A PREROUTING -t mangle -p tcp --dport 22 -j LOG --log-level 4 --log-prefix "fwmark 1: "
但是它也没有logging任何东西。
几天后,我能够解决这个问题。 我使用tcpdump
来查找stream量是否通过eth0
接口进行路由:
tcpdump -i eth0 port ssh
而事实certificate,第一个问题是从iptables
打标命令。 所以不是在PREROUTING
链上标记请求,而是在OUTPUT
链上标记它们,如下所示:
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 1
现在我能够看到在eth0
上的SSH请求,但仍然无法连接。 事实certificate,这个请求需要被伪装成正常工作:
iptables --table nat --append POSTROUTING -o eth0 -p tcp --dport 22 -j MASQUERADE
最后的脚本现在是这样的:
REMOTE_HOSTS=10.20.33.0/24 HOSTS_ADDR=172.17.42.1 # Add table echo 1 p.ssh >> /etc/iproute2/rt_tables # Add route ip rule add fwmark 1 table p.ssh ip route add $REMOTE_HOSTS via $HOSTS_ADDR dev eth0 table p.ssh # Sets mark correctly iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 1 iptables --table nat --append POSTROUTING -o eth0 -p tcp --dport 22 -j MASQUERADE #IP Stack echo 1 > /proc/sys/net/ipv4/ip_forward # Default in debian/ubuntu for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $f ; done