LVS 前话 你需要理解的网络基础知识

阿里妹导读:本文是一个理论过度到实践的典型案例,借助程序员经常遇到的一个问题——网络为什么不通,来具体说明怎么将书本上的死知识真正变成我们解决问题的能力。

大学学到的基本概念


我相信你脑子里关于网络基础知识的概念都在下面这张图中。知识内容有点乱,感觉都认识,又都模模糊糊,更谈不上将内容转化成生产力或是用来解决实际问题了。这是因为知识没有贯通、没有实践、没有组织。

上图中知识点的作用在RFC1180[1]中讲得无比通俗易懂了。看第一遍的时候也许你就看懂了,但是一个月后又忘记了。其实这些东西我们在大学也学过,但还是忘了(能够理解,缺少实操环境和条件),或者碰到问题才发现之前看懂了的东西其实没懂。

所以接下来我们将示范书本知识到实践的贯通过程,希望把网络概念之间的联系通过实践来组织起来

还是从一个问题入手


最近的环境碰到一个网络ping不通的问题,当时的网络链路是(大概是这样,略有简化):

现象

  • 从容器1 ping 物理机2 不通;

  • 从物理机1上的容器2 ping物理机2 通;

  • 同时发现即使是通的,有的容器 ping物理机1只需要0.1ms,有的容器需要200ms以上(都在同一个物理机上),不合理;

  • 所有容器 ping 其它外网IP(比如百度)反而是通的。

这个问题扯了一周才解决是因为容器的网络是我们自己配置的,交换机我们没有权限接触,由客户配置。出问题的时候都会觉得自己没问题对方有问题,另外就是对网络基本知识认识不够,所以都觉得自己没问题而不去找证据。

这个问题的答案在大家看完本文的基础知识后会总结出来。

解决这个问题前大家先想想,假如有个面试题是:输入 ping IP 后敲回车,然后发生了什么?

 

复习一下大学课本中的知识点


要解决一个问题你首先要有基础知识,在知识欠缺的情况下就算逻辑再好、思路再清晰、智商再高,也不一定有效。

route 路由表

假如你在这台机器上ping 172.17.0.2 ,根据上面这个IP符合下面这条路由:

这条路由规则,那么ping 包会从docker0这张网卡发出去。

但是如果是ping 1.1.4.4 根据路由规则就应该走eth0这张网卡而不是docker0了。接下来就要判断目标IP是否在同一个子网了。

 

arp协议


网络包在物理层传输的时候依赖的mac 地址而不是上面的IP地址,也就是根据mac地址来决定把包发到哪里去。

arp协议就是查询某个IP地址的mac地址是多少,由于这种对应关系一般不太变化,所以每个os都有一份arp缓存(一般15分钟过期),也可以手工清理,下面是arp缓存的内容:

进入正题,回车后发生什么?


有了上面的基础知识打底,我们来思考一下 ping IP 到底发生了什么。

首先 OS 的协议栈需要把ping命令封成一个icmp包,要填上包头(包括src-IP、mac地址),那么OS先根据目标IP和本机的route规则计算使用哪个interface(网卡),确定了路由也就基本上知道发送包的src-ip和src-mac了。每条路由规则基本都包含目标IP范围、网关、MAC地址、网卡这样几个基本元素。

 

如果目标IP和本机使用的IP在同一子网


如果目标IP和本机IP是同一个子网(根据本机ifconfig上的每个网卡的netmask来判断是否是同一个子网——知识点:子网掩码的作用),并且本机arp缓存没有这条IP对应的mac记录,那么给整个子网的所有机器广播发送一个 arp查询,比如我ping 1.1.3.42,然后tcpdump抓包首先看到的是一个arp请求:

上面就是本机发送广播消息,1.1.3.42的mac地址是多少?很快1.1.3.42回复了自己的mac地址。 收到这个回复后,先缓存起来,下个ping包就不需要再次发arp广播了。 然后将这个mac地址填写到ping包的包头的目标Mac(icmp包),然后发出这个icmp request包,按照mac地址,正确到达目标机器,然后对方正确回复icmp reply(对方回复也要查路由规则,arp查发送方的mac,这样回包才能正确路由回来,略过)。

来看一次完整的ping 1.1.3.43,tcpdump抓包结果:

我换了个IP地址,接着再ping同一个IP地址,arp有缓存了就看不到arp广播查询过程了。

 

如果目标IP不是同一个子网


arp只是同一子网广播查询,如果目标IP不是同一子网的话就要经过本IP网关进行转发(知识点:网关的作用)。如果本机没有缓存网关mac(一般肯定缓存了),那么先发送一次arp查询网关的mac,然后流程跟上面一样,只是这个icmp包发到网关上去了(mac地址填写的是网关的mac)。

从本机1.1.3.33 ping 11.239.161.60的过程,因为不是同一子网按照路由规则匹配,根据route表应该走1.1.15.254这个网关,如下截图:

首先是目标IP 11.239.161.60 符合最上面红框中的路由规则,又不是同一子网,所以查找路由规则中的网关1.1.15.254的Mac地址,arp cache中有,于是将 0c:da:41:6e:23:00 填入包头,那么这个icmp request包就发到1.1.15.254上了,虽然包头的mac是 0c:da:41:6e:23:00,但是IP还是 11.239.161.60。

看看目标IP 11.239.161.60 真正的mac信息(跟ping包包头的Mac是不同的):

这个包根据Mac地址路由到了网关上。

 

网关接下来怎么办?


为了简化问题,假设两个网关直连

网关收到这个包后(因为mac地址是它的),打开一看IP地址是 11.239.161.60,不是自己的,于是继续查自己的route和arp缓存,发现11.239.161.60这个IP的网关是11.239.163.247,于是把包的目的mac地址改成11.239.163.247的mac继续发出去。

11.239.163.247这个网关收到包后,一看 11.239.161.60是自己同一子网的IP,于是该arp广播找mac就广播,cache有就拿cache的,然后这个包才最终到达目的11.239.161.60上。

整个过程中目标mac地址每一跳都在变,IP地址不变,每经过一次MAC变化可以简单理解成一跳。

实际上可能要经过多个网关多次跳跃才能真正到达目标机器。

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/106730905
lvs