Docker网络学习第四篇-Namespace通信实战

作者: 耳朵里有风

通过前三篇对网络基本概念的理解,本篇来具体实战如何搭建比较的完整的Namespace的网络环境,搭建过程主要是解决下列问题:

  • namespace在主机上的网络:包括和主机通信,namespace之间的通信;
  • namespace访问主机所在的局域网内其他机器;
  • namespace访问互联网;
  • 不同主机之间的namespace通信;

另外还有如namespace 端口映射等问题,再后续篇章中遇到了再展开说明

本地通信

这里的本地通信是指在同一个主机内的不同namespace之间的通信,以及namespace和主机的通信,也就是要解决的第一个问题;其实此问题在Docker网络学习第一篇-Linux虚拟网络 有演示过,这里再回顾一遍。

要解决第一个问题,需要借助网桥和veth-pair 实现。


图1

具体演示步骤如下:

  • 创建命名空间
ip netns add ns1
ip netns add ns2
  • 创建网桥
ip link add name bridge0 type bridge
  • 创建veth-pair
ip link add veth1 type veth peer name vethb1
ip link add veth2 type veth peer name vethb2
  • 将veth的一端放在网桥上
ip link set vethb1 master bridge0
ip link set vethb2 master bridge0
  • 将veth另一端放在namespace
ip link set veth1 netns ns1
ip link set veth2 netns ns2
  • 给网络设备配置ip地址
ip netns exec ns1 ip addr add 10.1.1.2/24 dev veth1
ip netns exec ns2 ip addr add 10.1.1.3/24 dev veth2
ip addr add 10.1.1.1/24 dev bridge0
  • 启动网络设备
ip link set bridge0 up
ip link set vethb1  up
ip link set vethb2  up
ip netns exec ns1 ip link set veth1 up
ip netns exec ns2 ip link set veth2 up

图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中添加一条路由规则(默认网关)
ip netns exec ns1 ip route add default via 10.1.1.1

将bridge0 作为ns1 的默认网关。

  • 第二步,将bridge0上的请求转给eth0

图4

学习了iptables(Docker网络学习第二篇-认识iptables)之后会了解请求在进出网络设备时会先经过iptables的各种链,请求从bridge0发出时,先经过prerouting, 因为目标地址不是本机所以不会进入INPUT链,此处需要加条规则,允许请求走FORWARD链。

iptables -A FORWARD -i bridge0 ! -o bridge0 -j ACCEPT

这句命令的意思就是允许从设备bridge0进非bridge0出的请求通过;同时不要忘了加一条

iptables -A FORWARD -o bridge0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

加上这句话的意思是允许回包,假设请求成功到达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。具体命令如下:

iptables -A POSTROUTING -s 10.1.1.0/24 ! -o bridge0 -j MASQUERADE

把所有来自10.1.2.0/24网段的请求且出口不是bridge0的请求进行转发。(试了下不加! -o bridge0,暂时没看出影响,只是规则更加具体。 ) MASQUERADE,地址伪装,算是SNAT中的一种特例,可以实现自动化的SNAT。也可以手动指定snat的地址:

iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -j SNAT --to 172.31.131.149
  • 第三步,转出
    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实现,本文再原理上不作深究,后续篇章中还会具体学习。具体操作如下:

  1. 首先创建简单的点对点 VxLAN 环境, 在149和150建一条虚拟通道。


    图6

在149上执行

ip link add vxlan1 type vxlan id 1 remote 172.31.131.150 dstport 4789 dev eth0
ip link set vxlan1 up
ip addr add 10.0.0.2/24 dev vxlan1

在150上执行

ip link add vxlan1 type vxlan id 1 remote 172.31.131.149 dstport 4789 dev eth0
ip link set vxlan1 up
ip addr add 10.0.0.3/24 dev vxlan1

在149上执行ping 10.0.0.3, 显示结果已经可以ping通,说明vxlan虚拟通道已建立。

  1. 将vxlan1 添加到网桥中,ns1 请求到bridge0后,再将请求转到vxlan虚拟通道上。先把vxlan1的ip地址给移除(第一步添加ip只是为了确认通道是否建立,因为加到bridge0, ip地址也没用了。)
ip addr del 10.0.0.2/24 dev vxlan1 (149上执行)
ip addr del 10.0.0.3/24 dev vxlan1 (150上执行)

将vxlan1添加到网桥,分别在149和150上执行

ip link set vxlan1 master bridge0 

为了方便测试,在150上添加一个ns2, ip设置为10.1.1.5(和149中的ns同网段)

图7

进入10.1.1.2 去访问10.1.1.5, 成功!

总结

本篇演示了namespace通信的一些简单场景,在实际的使用中还有很多方面需要考虑。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349