第一次完整的LVS数据旅行格式linux
首先咱们定义一下IP报文的格式: 源MAC地址:目的MAC地址/源IP地址:目的IP地址算法
客户机须要发出一个IP报文(客户机MAC地址:目的MAC地址/客户机IP地址:VIP),这里对于客户机MAC地址,客户机的操做系统自己是知道的,而客户机的IP地址,客户机的操做系统
也是知道的,VIP地址客户机的浏览器上有,如今不肯定的是目标MAC地址,所以客户机的这个请求报文无法发出去,那该怎么办呢?浏览器
客户机就会先发一个广播报文,这报文的格式是这样的 客户机MAC地址:客户机IP地址/ ×××××:VIP地址 缓存
这个广播报文会发送给全部的局域网终端,意思是 :个人MAC地址是这个,个人IP地址是这个,请问VIP地址是这个的机器,你的MAC地址是什么?网络
这个数据被广播到交换机上,交换机一看,立刻会把"客户机MAC地址:客户机IP地址"记录在本身的缓存里面,记住,这一点很重要操作系统
咱们但愿这个数据被发送到Director上去,因此Director上应该正常配置这个VIP地址,以便响应这个ARP数据报文,所以在Director上配置这个VIPserver
如今Director上有VIP了,它会响应客户机的ARP请求,他响应客户的ARP请求:个人mac是这个,我是VIP接口
如今客户机能够发送报文(客户机MAC地址:Director的MAC地址/客户机IP地址:VIP),这个报文被直接发给了Directorip
第一步完成路由
Director收到报文以后,查看报文的目的IP地址,发现是发给它的,因而根据调度算法,选出一台realserver,假设是rs1,想把报文转发给rs1,因而director会怎么作呢?
director发送报文(director的MAC地址:目的MAC地址/客户机IP地址:VIP),注意,这里全部的IP都没有变化,只是mac地址有变化。
在这里,遇到一个问题,目的MAC地址该填什么呢?
咱们但愿director把这个报文转发给rs1,所以,目的MAC地址应该是rs1的目的地址,可是,rs1的MAC地址不知道啊?怎么办呢?
director是知道rs1的真实ip地址的(固然知道啊,director必定要清楚本身集群里面都有哪些节点嘛),因此director就发一个arp请求
director的MAC地址:VIP/*****:rs1的真实地址,这意思就是说,个人VIP地址是这个,个人MAC地址是这个,请问rs1真实地址是这个的机器,你的mac地址是什么?
这个数据被广播到交换机上,交换机一看,立刻会把"director的MAC地址:VIP"记录在本身的缓存中。注意,如今交换机中的VIP地址对应的是director的MAC地址,这很重要
rs1早就配置好了真实地址,所以它会响应director的arp请求:个人mac是这个,我是rs1真实IP
如今director能够把数据转发给rs1了(director的MAC地址:rs1的MAC地址/客户机IP地址:VIP) 注意这里IP层地址都没有变化,只有MAC地址发生了变化
第二步完成了
rs1收到数据以后,它会判断是否处理这个数据报文。判据是什么呢?是报文的目的IP地址,若是该报文的目的IP地址是本身,它就会处理,不然不处理
咱们知道,这个从director转发过来的数据的目的IP是VIP,可是rs1如今可没有VIP,所以rs1是不会处理这个数据报文的,那该怎么办呢?
办法就是给rs1配置一个VIP,那就应该在rs1的eth0上再配置一个VIP吗?(由于eth0上已经有一个真实IP了嘛),好的,咱们配一个试试看
配完以后,发现rs1上的VIP和director上的VIP发生IP地址冲突了(由于在第一步的客户机请求VIP的mac地址时,rs1和director都会响应这个arp请求),这下完蛋了。
所以,VIP须要配置到rs1的lo接口上。那么,为何设置到rs1的lo接口上就不会有问题呢?
首先,lo接口是个逻辑接口,这个接口根本不会收到arp请求,收不到arp请求也就不会发送arp响应,再说lo这种逻辑接口根本就不会有MAC地址,可是请注意,它能够收到IP数据报文
其次,在第一步中,客户机对VIP这个地址的MAC的ARP请求是会被广播给rs1的eth0接口的!此时eth0上有真实IP,没有VIP,lo接口上有VIP。在arp_ignore为0的状况下(这是默认状况),
eth0网卡收到了对lo上的VIP的arp请求,eth0也是会响应的,它很热情,它会把lo的mac地址(其实就是本身的MAC地址响应出去)--------0对应的是“回应任何网络接口上对任何本地IP地址
的arp查询请求”,所以咱们须要禁止eth0的这种热情的行为,使用arp_ignore = 1
1对应的是 “只回答目标IP地址是来访网络接口本地地址的arp查询请求”,也就是说,若是arp请求是询问eth0上的那个真实地址的mac,eth0才会响应(若是这个都不响应,director
就无法把报文转发给rs1了),对于其余的对lo上的VIP的arp的请求,根本不响应。
经过“在lo上配置VIP,在eth0上arp_ignore = 1”这两种手段,解决了VIP冲突的问题
如今rs1解开数据包,发现目标地址是VIP,而本身配置了VIP地址,所以它会处理这个数据包。
处理完以后,它会把本身的响应数据返回给客户机,这个数据报文是这样的
rs1的eth0的mac地址:目标MAC地址/rs1的IP(这里是VIP):客户机IP 注意这里IP层地址都没有变化,只有MAC地址发生了变化
对于rs1的eth0的mac地址,rs1操做系统本身是知道的,IP层的两个IP,也都是知道的,如今问题就是目标MAC地址,这个目标MAC地址应该填什么呢?
这个IP报文应该直接发给客户机,所以目标MAC地址应该是客户机的。但如今rs1并不知道客户机的MAC地址是什么,它该怎么办呢?
按照惯例,rs1应该发一个arp请求来获取客户机的MAC地址,下面的话很重要
这个arp请求里面包括了本身的ip地址和Mac地址,按照linux的默认设置,默认是将IP报文中的源IP地址做为arp请求中的源地址的。
咱们能够看到IP报文中的源IP地址是VIP,所以arp请求报文的数据是这样的
eth0的MAC地址:VIP/ ×××××:客户机IP
这意思就是说:个人ip是VIP,个人mac地址是这个,我想问一下,客户机IP是这个的机器,你的mac是什么?
结果这个arp请求一发出去,交换机一看,咦,VIP对应的MAC地址好像有变化啊,我要更新MAC地址表--------完蛋了
那该怎么办?
当内网的机器要发送一个到外部的ip包,那么它就会请求路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了本身的ip地址和Mac地址,
而linux默认是使用ip的源ip地址做为arp里面的源ip地址,而不是使用发送设备上面的,
若是设置 arp_announce 为2,则使用发送设备上的ip。
arp_announce = 0 在任意网络接口上的任何本地地址 (默认)
arp_announce = 2 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通讯的本地地址.
首要是选择全部的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 若是没有合适的地址被发现,将选择当前的
发送网络接口或其余的有可能接受到该ARP回应的网络接口来进行发送
对查询目标使用最适当的本地地址,意味着对客户机IP这个查询目标使用最适当的本地地址,最适当的本地地址就是eth0上的地址啊。由于数据最后是从这个
接口发出去的,eth0上的本地地址固然是最适当的,这个地址是rs1的真实IP地址。
因而arp请求报文是这样样子的:eth0的MAC地址:rs1的eth0上的真实IP地址/ ×××××:客户机IP
这时候就不会发生VIP地址冲突了,客户机也会顺利的响应这个arp请求,rs1收到了arp响应以后,
就能够把IP响应数据返回给客户机了
一次完整的数据流程结束