背景
一直对lvs的dr模式模模糊糊,感觉似懂非懂的感觉,那今天就扒开他。
ARP
ARP是地址解析协议(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。简单点就是根据ip获取mac地址。
步骤如下
(1)主机A的IP地址为192.168.1.1
(2)主机B的IP地址为192.168.1.2
当主机A要与主机B通信时,地址解析协议可以将主机B的IP地址(192.168.1.2)解析成主机B的MAC地址,以下为工作流程:
- 第1步:根据主机A上的路由表内容,IP确定用于访问主机B的转发IP地址是192.168.1.2。然后A主机在自己的本地ARP缓存中检查主机B的匹配MAC地址。
- 第2步:如果主机A在ARP缓存中没有找到映射,它将询问192.168.1.2的硬件地址,从而将ARP请求帧广播到本地网络上的所有主机。源主机A的IP地址和MAC地址都包括在ARP请求中。本地网络上的每台主机都接收到ARP请求并且检查是否与自己的IP地址匹配。如果主机发现请求的IP地址与自己的IP地址不匹配,它将丢弃ARP请求。
- 第3步:主机B确定ARP请求中的IP地址与自己的IP地址匹配,则将主机A的IP地址和MAC地址映射添加到本地ARP缓存中。
- 第4步:主机B将包含其MAC地址的ARP回复消息直接发送回主机A。
- 第5步:当主机A收到从主机B发来的ARP回复消息时,会用主机B的IP和MAC地址映射更新ARP缓存。本机缓存是有生存期的,生存期结束后,将再次重复上面的过程。主机B的MAC地址一旦确定,主机A就能向主机B发送IP通信了。
说白了就是,有点像小学同学第一次见面,大家通过名字来认识每个同学长什么样,a同学对所有同学说我叫a你们谁叫b,b同学听见有人叫自己,他知道了a同学长什么样,并对a说我叫b,于是a也知道了b。
两个配置
聊之前先看两个配置arp_ignore、arp_announce
假设一台服务器有三个网卡,eth0,eth1,lo。每个网卡都有一个ip地址和一个mac地址
网卡 | ip | mac |
---|---|---|
eth0 | 1.1.1.1 | mac1 |
eth1 | 2.2.2.2 | mac2 |
lo | 3.3.3.3 | mac3 |
arp_ignore
控制系统在收到arp广播请求报文时,是否返回arp响应报文
常见取值解释:
0、主机上任意一个网卡接口有arp广播请求报文中的IP地址,就进行回应(eth0接到了arp广播请求问2.2.2.2的mac地址是多少,虽然eth0是1.1.1.1,但是eth0把eth1的mac地址响应了回去。)
1、只响应目的IP地址为接收网卡上的本地地址的arp请求(eth0接到了arp广播请求问2.2.2.2的mac地址是多少,eth0比较自己的ip是不是2.2.2.2,但是发现自己是1.1.1.1,eth0不响应。)
2、只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段(eth0接到了arp广播请求问1.1.1.1的mac地址是多少,eth0不仅比较自己的ip是不是1.1.1.1,并且还要看源ip是不是和1.1.1.1同网段。)
总结
arp_ignore就是控制能不能响应arp请求的。
arp_announce
arp_announce 对网络接口(网卡)上发出的ARP请求包中的源IP地址作出相应的限制;主机会根据这个参数值的不同选择使用IP数据包的源IP或当前网络接口卡的IP地址作为ARP请求包的源IP地址。说白了发arp请求时,我是用网卡的ip地址作为源ip还是用ip包中的ip做为源ip
上图就是ip数据包,看没看见里面有一个源ip地址的东西,说白了就是决定用网卡的ip还是数据包里的源ip地址。
IP数据包
假设数据包里的源ip地址是3.3.3.3,网卡如下。
网卡 | ip | mac |
---|---|---|
eth0 | 1.1.1.1 | mac1 |
eth1 | 2.2.2.2 | mac2 |
lo | 3.3.3.3 | mac3 |
0 - (默认) 在任意网络接口(eth0,eth1,lo)上使用任何本机地址进行ARP请求。也就是说如果IP数据包中的源IP与当前发送ARP请求的网络接口卡IP地址不同时(但这个IP依然是本主机上其他网络接口卡上的IP地址),ARP请求包中的源IP地址将使用与IP数据包中的 源IP相同的本主机上的IP地址,而不是使用当前发送ARP请求的网络接口卡的IP地址。【比如在eth0上发arp请求,数据包的源ip是3.3.3.3而eth0是1.1.1.1,但是3.3.3.3也是本机的网卡ip地址,arp请求中的源ip继续用3.3.3.3】
2 - 始终使用与目标IP地址对应的最佳本地IP地址作为ARP请求的源IP地址。在此模式下将忽略IP数据包的源IP地址并尝试选择能与目标IP地址通信的本机地址。首要是选择所有网络接口中子网包含该目标IP地址的本机IP地址。如果没有合适的地址,将选择当前的网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送ARP请求,并把发送ARP请求的网络接口卡的IP地址设置为ARP请求的源IP。【比如在eth0上发arp请求,数据包的源ip是3.3.3.3而eth0是1.1.1.1,那就是用当前eth01.1.1.1作为arp请求的源ip】
DR模式
总结
lvs的dr模式就是用到了arp的两个参数,以及对mac地址的修改,那是在哪里对mac地址进行修改的呢?在netfilter中,netfilter可看我之前写的传送门
在INPUT 链中注册ip_vs_in()函数,ip_vs_in干了什么呢?
根据目的 IP 和 Port(端口)确认是否为 LVS 定义的服务,如是定义过的 VIP 服务,会根据配置的服务信息,假如从 RS 中选择一个后端服务器 RS1,就用RS1 作为目标出方向的路由,确定下一跳信息及数据包通过具体的哪个网卡发出。
在postrouting链中注册ip_vs_post_routing()函数,ip_vs_post_routing()干了什么呢?会把目的MAC 地址将会修改为 RS1服务器 MAC 地址,源 MAC 地址修改为 LVS 的MAC 地址,然后将数据包发送给RS1。
今天你通了吗?
参考资料
https://blog.youkuaiyun.com/qianfeng_dashuju/article/details/82856901
http://www.linuxvirtualserver.org/zh/lvs1.html
https://www.jianshu.com/p/a682ecae9693
https://github.com/liexusong/linux-source-code-analyze/blob/master/lvs-principle-and-source-analysis-part2.md