已发表的技术专栏(订阅即可观看所有专栏)
0 grpc-go、protobuf、multus-cni 技术专栏 总入口
1 grpc-go 源码剖析与实战 文章目录
2 Protobuf介绍与实战 图文专栏 文章目录
3 multus-cni 文章目录(k8s多网络实现方案)
4 grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录
本篇文章模拟一下,如何将veth pair链接的网络可以访问本局域网的其他宿主机。
| 1、测试环境介绍 |
一台centos虚拟机
# 查看操作系统版本
cat /etc/centos-release
# 内核版本
uname -a
uname -r
# 查看网卡信息
ip a s eth0

| 2、网络拓扑 |

| 3、操作实战 |
| 3.1、创建命令 |
ip netns add ns1ip link add veth1 type veth peer name veth2ip link set veth2 netns ns1ip addr add 10.244.1.2/24 dev veth1
ip link set veth1 upip netns exec ns1 ip addr add 10.244.1.3/24 dev veth2
ip netns exec ns1 ip link set veth2 upip netns exec ns1 route add default gw 10.244.1.2echo 1 > /proc/sys/net/ipv4/ip_forward
| 3.2、在ns1里发起请求命令 |
ip netns exec ns1 ping 10.211.55.123

| 4、原因分析 |
| 4.1、分别对veth1,eth0进行抓包分析 |
| 4.1.1、对veth1进行抓包 |
tcpdump -nn -i veth1

| 4.1.2、接下来,对eth0进行抓包分析: |
tcpdump -nn icmp -i eth0

也就是说,在ns1里可以直接ping到同网段的其他宿主机,并且
本宿主机也接收到了10.211.55.123宿主机的反馈
本宿主机收到数据包后,发现数据包的目的地址,并非是eth0网卡,因此丢弃了。
所以,veth1没有收到反馈的数据包。
| 4.2、为什么本宿主机10.211.55.122上能够收到宿主机10.211.55.123节点反馈的数据包呢? |
你想想,我们并没有在宿主机10.211.55.122上为ns1的网络10.244.1.0/24设置路由
这样吧,可以先查看一下10.211.55.123节点上的路由情况

做个测试:删除10.211.55.123节点上的默认路由

| 4.3、那么,接下来的问题就是,从节点10.211.55.123上通过默认路由出来的数据包,它怎么知道就去了10.211.55.122节点上呢? |
其实,是由"路由环路"现象
即,数据包在网络中来回转发,形成在路由器间踢皮球现象,而无法到达最终用户。
也就是说,从10.211.55.123节点的默认路由发送的数据包,会在整个链路上,来回试探,
肯定能转发到10.211.55.122节点上去。
我也在第3台测试机10.211.55.160上,也抓取到了10.211.55.123上发出去的数据包,如下图:

可参考下面的文章
关于路由概念的理解:直连路由,非直连路由,静态路由,动态路由,默认路由,路由环路
| 4.4、为什么10.211.55.122节点收到10.211.55.123反馈的数据包后,丢弃了呢? |
上面我们解决的问题是,为什么122节点能够收到123节点反馈的数据包,
那么,现在要解决的问题是,122节点收到数据包后,为什么丢弃了
在122节点上,分别对veth1,以及eth0网卡抓取数据包分析
| 4.4.1、先查看一下,目标网卡MAC地址 |
接下来,主要分析一下MAC地址情况,因此,我们先查询一下,
方便对比:
122节点上eth0的MAC地址

122节点上veth1,veth2的MAC地址

123节点上eth0的MAC地址

| 4.4.2、对veth1抓取数据包 |
tcpdump -nn -i veth1 -w icmp-veth1.pcap

从上面的图中,可以看出来,只有发送出去的数据包,没有接收到回来的数据包
| 4.4.3、对eth0抓取数据包 |
tcpdump -nn icmp -i eth0 -w icmp-eth0.pcap
数据包从veth1网卡出来后,
经过路由判断,去往10.211.55.123节点的数据包,
需要通过eth0网卡发送出去,因此,将数据包转发给了eth0网卡
分析一下,从eth0发送数去的数据包

分析一下,122节点的eth0网卡接收到123节点上eth0回复的数据包

也就是说,122节点上收到123节点反馈的数据包时,发现目的MAC地址并非是自己的MAC地址,就给抛弃了。
上图中,第2条语句有点问题。00:1c:42:00:00:18是本局域网网关的MAC地址
| 4.4.4、思考一下,123节点上反馈的数据包的目的MAC是如何产生的? |
123节点收到122节点发送的数据包,进行解析,发现源IP是10.244.1.3
123节点对122节点进行回复时,需要知道10.244.1.3IP的MAC地址,查询本地的ARP表,发现没有,
需要在本地局域网内发起ARP请求
最终没有ARP响应,于是只能将ARP请求包发送给本局域网的网关10.211.55.1
该网关的MAC地址就是00:1c:42:00:00:18

即,123节点发送的反馈数据包的目的MAC是网关的,目的IP是10.244.1.3
当本局域网内的服务器收到此数据包后,就会判断MAC地址是否是自己的,发现不是自己的就丢弃了。
如何解决此问题呢?
有很多种解决方式,比方说:
123节点在回复数据包时,将目的IP地址改为10.211.55.122,
通过IP、ARP协议,获取到122节点上eth0网卡的MAC地址
这样,122节点收到数据包后,对数据包进行解析,获取到目的MAC地址是自己,就不会丢弃。
只有这一点还不行,在给此数据添加一个特殊标记之类的,
122节点收到含有此标记的数据包后,对此类数据包自动的转发到ns1里,即可。
能够完成这个功能的是iptables中的snat 或者 MASQUERADE
| 5、设置MASQUERADE |
| 5.1、 MASQUERADE简单介绍 |
地址伪装,算是snat中的一种特例,可以实现自动化的snat
就是将veth1发送出去的数据包的源地址,由10.244.1.3改成了10.211.55.122了。
snat跟MASQUERADE的区别,可以参考一下下面的文章。
https://andblog.cn/2694
| 5.2、具体设置命令如下 |
iptables -t nat -A POSTROUTING -s 10.244.1.0/24 -o eth0 -j MASQUERADE

| 5.3、需要重新启动测试 |
ip netns exec ns1 ping 10.211.55.123

| 6、提供完整的测试用例 |
ip netns add ns1ip link add veth1 type veth peer name veth2ip link set veth2 netns ns1ip addr add 10.244.1.2/24 dev veth1
ip link set veth1 upip netns exec ns1 ip addr add 10.244.1.3/24 dev veth2
ip netns exec ns1 ip link set veth2 upip netns exec ns1 route add default gw 10.244.1.2echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 10.244.1.0/24 -o eth0 -j MASQUERADE# 可以增加FORWARD规则,观察访问
iptables -t filter -A FORWARD -i eth0 -o veth1 -j ACCEPT
iptables -t filter -A FORWARD -o eth0 -i veth1 -j ACCEPT
测试命令
ip netns exec ns1 ping 10.211.55.123
| 7、分析一下,不同网卡,报文情况: |
| 7.1、抓取veth1的数据报文分析 |

| 7.2、抓取eth0的数据报文分析 |

| 7.3、分析一下,经过veth1网卡,eth0网卡的报文情况? |

| 8、总结 |