说明
内核的 arp_ignore 和 arp_announce 参数都和 ARP 协议相关,主要用于控制系统返回 ARP 响应和发送 ARP 请求时的动作。这两个参数很重要,特别是在 LVS 的 DR 场景下,它们的配置直接影响到 DR 转发是否正常。Linux 内核文档 中的描述:
1 | arp_ignore - INTEGER |
arp_ignore 参数的作用是控制系统在收到外部的 ARP 请求时,是否要返回 ARP 响应。参数常用到的有 0,1,2 三个值,3 ~ 8 较少用到:
- 0:响应任意网卡上接收到的对本机IP地址的 ARP 请求(包括环回网卡上的地址),而不管该目的 IP 是否在接收网卡上。
- 1:只响应目的IP地址为接收网卡上的本地地址的 ARP 请求。
- 2:只响应目的IP地址为接收网卡上的本地地址的 ARP 请求,并且发送 ARP 请求的源IP必须和接收网卡同网段。
- 3:如果 ARP 请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应 ARP 响应数据包,如果作用域为全局(global)或链路(link),则回应 ARP 响应数据包。
- 4~7:保留,未使用。
- 8:不回应所有的 ARP 请求
/etc/sysctl.conf
中包含 all 和 eth/lo(具体网卡)的 arp_ignore 参数,取其中较大的值生效。
1 | arp_announce - INTEGER |
arp_announce 的作用是控制系统在对外发送 ARP 请求时,如何选择 ARP 请求数据包的源IP地址。arp_announce 参数常用的取值有 0,1,2:
- 0:允许使用任意网卡上的IP地址作为 ARP 请求的源IP,通常就是使用数据包的源IP。
- 1:尽量避免使用不属于该发送网卡子网的本地地址作为发送 ARP 请求的源IP地址。
- 2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为 ARP 请求的源IP地址。
/etc/sysctl.conf
中包含 all 和 eth/lo(具体网卡)的 arp_announce 参数,取其中较大的值生效。
arp_ignore 参数示例
当 arp_ignore 参数配置为 0 时,eth0 网卡上收到目的IP为环回网卡IP的 ARP 请求,但是 eth0 也会返回 ARP 响应,并且把自己的 MAC 地址告诉对端。
当 arp_ignore 参数配置为 1 时,eth0 网卡上收到目的IP为环回网卡IP的 ARP 请求,发现请求的IP不是自己网卡(eth0)上的IP,就不会返回 ARP 响应。
arp_announce 参数示例
当 arp_announce 参数配置为 0 时,系统要发送的IP包源地址为 eth1 的地址,IP包目的地址根据路由表查询判断需要从 eth0 网卡发出,这时会先从 eth0 网卡发起一个 ARP 请求,用于获取目的IP地址的 MAC 地址。该 ARP 请求的源MAC 自然是 eth0 网卡的 MAC 地址,但是源 IP 地址会选择 eth1 网卡的地址。
当 arp_announce 参数配置为 2 时,eth0 网卡发起arp请求时,源IP地址会选择 eth0 网卡自身的IP地址。
DR 模式下的应用
arp_ignore
因为 DR 模式下,每个真实服务器节点都要在环回网卡上绑定虚拟服务IP。这时候,如果客户端对于虚拟服务IP的 ARP 请求广播到了各个真实服务器节点,如果 arp_ignore 参数配置为 0,则各个真实服务器节点都会响应该 ARP 请求,此时客户端就无法正确获取 LVS 节点上正确的虚拟服务IP所在网卡的 MAC 地址。假如某个真实服务器节点 A 的网卡 eth1 响应了该 ARP 请求,客户端把 A 节点的 eth1 网卡的 MAC 地址误认为是 LVS 节点的虚拟服务IP所在网卡的 MAC ,从而将业务请求消息直接发到了 A 节点的 eth1 网卡。这时候虽然因为 A 节点在环回网卡上也绑定了虚拟服务IP,所以 A 节点也能正常处理请求,业务暂时不会受到影响。但时此时由于客户端请求没有发到 LVS 的虚拟服务IP上,所以 LVS 的负载均衡能力没有生效。造成的后果就是,A节点一直在单节点运行,业务量过大时可能会出现性能瓶颈。
所以要求 arp_ignore 参数要求配置为1。
arp_announce
每个机器或者交换机中都有一张 ARP 表,该表用于存储对端通信节点IP地址和 MAC 地址的对应关系。当收到一个未知IP地址的 ARP 请求,就会在本机的 ARP 表中新增对端的IP和 MAC 记录;当收到一个已知IP地址( ARP 表中已有记录的地址)的 ARP 请求,则会根据 ARP 请求中的源 MAC 刷新自己的 ARP 表。
如果 arp_announce 参数配置为0,则网卡在发送 arp 请求时,可能选择的源IP地址并不是该网卡自身的IP地址,这时候收到该 ARP 请求的其他节点或者交换机上的 ARP 表中记录的该网卡IP和 MAC 的对应关系就不正确,可能会引发一些未知的网络问题,存在安全隐患。
所以要求 arp_announce 参数要求配置为2。
配置
配置 /etc/sysctl.conf
,然后使用 sysctl -p
刷新到内存即可立即生效:
1 | net.ipv4.conf.all.arp_ignore = 1 |