《零入门kubernetes网络实战》视频专栏地址
https://www.ixigua.com/7193641905282875942
本篇文章视频地址(稍后上传)
本篇文章我们使用nat技术来实现bridge管理的网络能够访问外网。
1、测试环境介绍 |
两台centos虚拟机
# 查看操作系统版本
cat /etc/centos-release
# 内核版本
uname -a
uname -r
# 查看网卡信息
ip a s eth0
2、网络拓扑 |
3、操作实战 |
3.1、在master上执行下面的命令 |
brctl addbr br0
ip link set br0 up
ip addr add 10.244.1.3/24 dev br0
ip netns add ns1
ip link add veth1a type veth peer name veth1b
ip link set veth1a netns ns1
ip netns exec ns1 ip addr add 10.244.1.2/24 dev veth1a
ip netns exec ns1 ip link set veth1a up
ip link set veth1b up
brctl addif br0 veth1b
ip netns exec ns1 route add default gw 10.244.1.3
iptables -t nat -A POSTROUTING -s 10.244.1.0/24 -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
3.2、查看一下当前环境的状态 |
3.2.1、查看ns1命名空间下,路由情况 |
ip netns exec ns1 route -n
3.2.2、查看ns1命名空间下,ARP表的情况 |
该表存储的是目的IP跟目的MAC的对应关系。
ip netns exec ns1 arp -n
3.2.3、查看宿主机命名空间下的,路由情况 |
route -n
3.2.4、查看宿主机命名空间下的网桥br0的情况 |
bridge fdb show br br0
3.2.5、查看宿主机命名空间下的arp情况 |
arp -n
3.3、在master节点对br0进行抓包 |
tcpdump -nn -i br0
tcpdump -nn -i br0 -w icmp-br0.pcap
将icmp-br0.pacp导入到Wireshark里,进行分析。
3.4、在master节点对eth0进行抓包 |
tcpdump -nn -i eth0 icmp
tcpdump -nn -i eth0 icmp -w icmp-eth0.pcap
3.5、在宿主机上,ns1命名空间里发起icmp请求 |
ip netns exec ns1 ping 10.211.55.123
ip netns exec ns1 ping -c 1 10.211.55.123
3.6、重新查看ns1命名空间下,ARP表的情况 |
ip netns exec ns1 arp -n
在ns1命名空间里,ping 10.211.55.123时,
首先查询ARP表,查看是否有10.211.55.123IP跟MAC地址的对应关系
发现没有,于是发送ARP广播,
但是,ARP广播的作用域只能是本地局域网呢,禁止跨域的
通过ARP广播后,发现还是没有目的地址的MAC
因此,只能将ARP数据包发送给网关地址
网关接收到后,会将自己的MAC地址发送给veth1a
因此,veth1a里存储的是网桥br0的MAC地址
4、echo 1 > /proc/sys/net/ipv4/ip_forward 命令说明 |
4.1、这条命令实现的效果? |
实现数据包的转发功能
临时生效的
4.2、什么是数据包的转发功能? |
那到底什么是数据包的转发功能呢?
当主机拥有多于一块的网卡时,其中一块网卡收到数据包,根据数据包的目的ip地址将包发往本机另一网卡,
该网卡根据路由表继续发送数据包。
这通常就是路由器所要实现的功能。
https://zhoupeng.blog.csdn.net/article/details/125597375
4.3、如何将数据包的转发功能永久生效呢? |
上面的命令仅仅是临时生效的。
如果想永久生效的,
操作如下
grep 'net.ipv4.ip_forward = 1' /etc/sysctl.conf || echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
先通过grep来获取目标属性,如果存在的话,就说明宿主机已经实现了数据包的转发功能
不存在的话,执行||后面的语句,
4.4、以本试用例说明 |
本测试用例中存在虚拟网桥bridge,以及物理eth0网卡
数据包由bridge到达eth0需要宿主机开启数据包的转发功能。
5、通过MASQUERADE后,数据包的报文内容是否被修改了? |
在master节点上,根据前面对虚拟网桥br0, 物理网卡eth0进行抓包,分析。
可以绘画出下面的数据包流转图:
通过MASQUERADE后,将数据包的源IP进行了修改
由于数据包是通过eth0发送出去的,修改了源MAC地址,目的MAC地址
6、继续延伸一下:思考一个问题:当122节点收到123节点的反馈数据包时?122节点的网卡eth0怎么知道将数据包转发给网桥呢? |
从上面的图中可以看出来从122节点发送到123节点的数据包中的源MAC,目的MAC,源IP全部被修改了,那么,
122节点收到123节点的反馈数据包时,源MAC地址,目的Mac地址,源IP,目的IP刚好跟发送的完全相反
如下图所示:
现在要思考的是,122节点的网卡eth0收到数据包后,122节点如何知道将数据包转发给网桥br0?
因为,单纯看数据包是看不出来的。
背后实现原因是:
似乎是在进行NAT操作时,往内核里注册里NAT操作相关的注册表,有了相关记录。
然后,根据链路追踪实现的。
我仅仅做了一些简单的测试,如下
添加了一些日志埋点,观察一下iptables日志
iptables -t nat -I POSTROUTING -p icmp -m state --state NEW -j LOG --log-prefix "nat2-output-"
iptables -t nat -A PREROUTING -p icmp -j LOG --log-prefix "nat3-prerouting-"
iptables -t filter -A FORWARD -p icmp -j LOG --log-prefix "filter-forward-"
普通的ping命令
ping 10.211.55.123
很遗憾,最终没有真正的搞清楚。
其实,我是希望在数据包中能够找到一个标志位,通过标志位来判断是否进行了nat操作。
后来想了一下,可能有问题,因为tcp,ip ,udp,以太网帧等协议的数据包中,应该没有这个标志位的。
暂时,也不知道深入研究了。
7、从iptables链的角度,对整个过程进行分析 |
为了分析整个传输过程,我们添加一些日志埋点,来验证我们的猜测。
如果你已经根据前面的文章安装过了rsyslog服务,就不需要重复操作了
7.1、安装 |
7.1.1、安装rsyslog服务 |
yum -y install rsyslog
7.1.2、更新配置文件 |
echo "kern.* /var/log/iptables.log" >> /etc/rsyslog.conf
.*,表示所有等级的消息都添加到iptables.log文件里
信息等级的指定方式
- .XXX,表示 大于XXX级别的信息
- .=XXX,表示等于XXX级别的信息
- 如,kern.=notice /var/log/iptables.log, 将notice以上的信息添加到iptables.log里
- .!XXX, 表示在XXX之外的等级信息
7.1.3、重启rsyslog服务 |
systemctl restart rsyslog
systemctl status rsyslog
7.2、日志埋点 |
7.3、在master节点上,进行日志埋点 |
将当前的日志统计清零
iptables -t nat -Z
iptables -t filter -Z
插入日志埋点前,先查看一下,当前的现状
iptables -t nat -nvL PREROUTING --line-number
iptables -t filter -nvL FORWARD --line-number
iptables -t nat -nvL POSTROUTING --line-number
插入日志埋点
iptables -t nat -I PREROUTING -p icmp -j LOG --log-prefix "Nat-PREROUTING-1-"
iptables -t filter -A FORWARD -p icmp -j LOG --log-prefix "Filter-FORWARD-1-"
iptables -t nat -I POSTROUTING -p icmp -j LOG --log-prefix "Nat-POSTROUTING-1-"
7.4、在master节点上,重新发起请求 |
在真正发起请求前,先实时追踪日志状态
tail -f /var/log/iptables.log
重新打开一个shell终端,在master节点上查看日志文件
ip netns exec ns1 ping 10.211.55.123
ip netns exec ns1 ping -c 1 10.211.55.123
查看一下,iptables日志
7.5、在使用了MASQUERADE后,请求过程经过了哪些iptables链? |
8、总结 |
本篇文章说了很多,其实,重点想表达的只有下面几个
- 当本宿主机上的内部网络想访问外部网络的话,可以通过SNAT,MASQURAED操作,修改数据包的源IP地址为本宿主机对外的IP 地址,这样的话,本宿主机接收到对方的回馈数据包后,只要进行数据包转发,转发到内网即可。
- 为什么内网访问外网时,必须使用snat这样的方案呢?我们在veth相关文章中已经总结过了,这里再总结一下。
- 当本宿主机A的内网访问本宿主机A所在网段的其他宿主机时(假设访问的是B宿主机),B宿主机是可以接收到数据包的;此时,B宿主机收到的数据包中的源IP是A宿主机的内网IP
- 当B宿主机进行回复时,发现通过ARP协议获取不到A宿主机里内网IP的MAC,此时,B宿主机就将目的MAC设置为了A网段的网关的MAC地址,然后,发送数据包
- 当A宿主机收到B宿主机的回复的数据包时,发现MAC地址,并非是自己的,就丢弃了。
- 也就是说,不做SNAT的情况下,数据包可以达到目的服务器,但是,目的服务器进行回复的时候,出现了问题。
- 因此,需要使用SNAT这样的技术,再发送数据包时,将数据包的源IP改为本宿主机对外的IP,这样,目的服务器进行回复的时候,就可以将数据包回复到源宿主机上,然后,再内部转发即可。
- 为什么内网访问外网时,必须使用snat这样的方案呢?我们在veth相关文章中已经总结过了,这里再总结一下。
- 数据包再发送过程中,跨网段的话,会修改源MAC地址,目的MAC地址
- 到底什么是数据包的转发
- 当访问的目的地址IP是跨网段的话,那么,本节点发送出去的数据包的目的MAC地址,是本局域网关的MAC地址,如上面的veth1a发送的数据包的目的MAC地址是br0的MAC地址
<<零入门kubernetes网络实战>>技术专栏之文章目录