Docker 网络学习第四篇 -Namespace 通信实战
通过前三篇对网络基本概念的理解,本篇来具体实战如何搭建比较的完整的Namespace的网络环境,搭建过程主要是解决下列问题:
namespace在主机上的网络:包括和主机通信,namespace之间的通信;
namespace访问主机所在的局域网内其他机器;
namespace访问互联网;
不同主机之间的namespace通信;
另外还有如namespace 端口映射等问题,再后续篇章中遇到了再展开说明
本地通信
这里的本地通信是指在同一个主机内的不同namespace之间的通信,以及namespace和主机的通信,也就是要解决的第一个问题;其实此问题在Docker网络学习第一篇-Linux虚拟网络 有演示过,这里再回顾一遍。
要解决第一个问题,需要借助网桥和veth-pair 实现。
图1
具体演示步骤如下:
创建命名空间
创建网桥
创建veth-pair
将veth的一端放在网桥上
将veth另一端放在namespace
给网络设备配置ip地址
启动网络设备
图1的网络模型到此搭建完成,因为给bridge0 和 veth1 veth2 设置了同一网段网络地址,所以它们之间网络已经是互通的了。
图2
局域网内访问
在ns1 中现在已经能够ping 通 10.1.1.1(host)和 10.1.1.3(ns2)。假设当前主机的ip是172.31.131.149, 另外一台机器主机ip为172.31.131.150, 那么在ns1或ns2中如何能够访问172.31.131.150 呢?
ns1 无法直接访问150, 但是在ns1所在host 149 是可以访问150的,当ns1请求150时,先将请求从veth1设备通过vethb1发送到bridge0, bridge0再将请求转发给eth0(149的物理网卡),最终发送到150。
图3
依据上述文字描述和图示,将过程分为3步
第一步,将ns1中的请求发送到10.1.1.1
回顾系列第三篇所讲的路由知识(Docker网络学习第三篇-路由),要指定请求发给谁,就需要在ns1中添加一条路由规则(默认网关)
将bridge0 作为ns1 的默认网关。
第二步,将bridge0上的请求转给eth0
图4
学习了iptables(Docker网络学习第二篇-认识iptables)之后会了解请求在进出网络设备时会先经过iptables的各种链,请求从bridge0发出时,先经过prerouting, 因为目标地址不是本机所以不会进入INPUT链,此处需要加条规则,允许请求走FORWARD链。
这句命令的意思就是允许从设备bridge0进非bridge0出的请求通过;同时不要忘了加一条
加上这句话的意思是允许回包,假设请求成功到达150,那么150给出的响应会原路返回,eth0拿到响应后,同样会经过prerouting链,因为响应的目标地址不是本机(是ns1),所以需要走FORWARD链转给bridge0;
从Linux2.6.15的内核版本后,iptables开始支持状态跟踪(conntrack),该功能依赖于netfilter的内核模块nf_conntrack。iptables可以根据包的状态进行二次的过滤拦截和状态跟踪。它也是state/ctstate和nat的主要依赖模块。conntrack共可以为连接标记五种状态,分别如下:
NEW 新建连接请求的数据包
ESTABLISHED 该连接是某NEW状态连接的回包
RELATED ESTABLISHED连接的衍生连接
INVALID 无法识别或没有任何状态的数据包
UNTRACKED 它是管理员在raw表中,为连接设置NOTRACK规则后的状态
再回到请求,当请求从bridge0到prerouting再到forward, 然后到postrouting链处理,这一步需要将请求转发给设备eth0,进而访问150。具体命令如下:
把所有来自10.1.2.0/24网段的请求且出口不是bridge0的请求进行转发。(试了下不加! -o bridge0,暂时没看出影响,只是规则更加具体。 ) MASQUERADE,地址伪装,算是SNAT中的一种特例,可以实现自动化的SNAT。也可以手动指定snat的地址:
第三步,转出
eth0 因为已经和150 是联通的,这一步不需要在做任何配置。此时在ns1中ping 下150,ip netns exec ns1 ping 172.31.131.150
, 测试一下,如果有问题,检查下上述操作是否都正确,正常应该是OK的。
namespace访问互联网
当解决了第二个问题后,这个问题其实已经随之解决了。尝试运行ip netns exec ns1 ping www.baidu.com
发现确实是可以ping通的,这是因为在解决第二个问题时,已经将请求交给了eth0,不管是访问局域网还是访问互联网都已经是eth0的事情了。在我实验的环境中172.31.131.149 这台机器是可以连上互联网的,所以ns1自然也可以。(主机联网和解决第二个问题的过程是类似的)
不同主机之间的namespace通信;
要模拟不同主机之间的namespace通信,先在150上也新建个ns1、网桥bridge0以及veth1-vethb1、不同的是bridge0的ip 设为10.1.2.1, veth1 的ip设为10.1.2.2, 和149上的10.1.1.0/24作区分。
图5
现在红色线就是待实现的部分。下面演示下用vxlan实现,本文再原理上不作深究,后续篇章中还会具体学习。具体操作如下:
首先创建简单的点对点 VxLAN 环境, 在149和150建一条虚拟通道。
图6
在149上执行
在150上执行
在149上执行ping 10.0.0.3
, 显示结果已经可以ping通,说明vxlan虚拟通道已建立。
将vxlan1 添加到网桥中,ns1 请求到bridge0后,再将请求转到vxlan虚拟通道上。先把vxlan1的ip地址给移除(第一步添加ip只是为了确认通道是否建立,因为加到bridge0, ip地址也没用了。)
将vxlan1添加到网桥,分别在149和150上执行
为了方便测试,在150上添加一个ns2, ip设置为10.1.1.5(和149中的ns同网段)
图7
进入10.1.1.2 去访问10.1.1.5, 成功!
总结
本篇演示了namespace通信的一些简单场景,在实际的使用中还有很多方面需要考虑。
版权声明: 本文为 InfoQ 作者【Lazy】的原创文章。
原文链接:【http://xie.infoq.cn/article/f5b4b40447dc70bc707ec9ba6】。文章转载请联系作者。
评论