Linux ARP/邻居表(NUD)完整笔记
本文档详细整理了 Linux 系统下的 ARP(地址解析协议)和邻居表的状态、生命周期、相关内核参数以及 MetalLB 对 ARP 缓存的影响等信息,适用于学习和故障排除。
1. ARP 和邻居表的基本概念
在 Linux 系统中,IPv4 采用 ARP(地址解析协议),而 IPv6 则使用 NDP(邻居发现协议)。这两种协议由内核中的邻居子系统统一管理,其工作机制被称为 NUD(邻居不可达检测)。邻居表不仅记录了 IP 地址到 MAC 地址的映射关系,还包含了这些映射的可达性状态,这对于确定是否需要重新探测邻居设备至关重要。
2. Linux 邻居表的所有状态(NUD State)
以下是 Linux 内核中定义的所有 NUD 状态及其含义:
| 状态 | 名称 | 含义 / 触发时机 |
| INCOMPLETE | 未完成 | 已发出 ARP 请求,正在等待响应;MAC 地址未知。 |
| REACHABLE | 可达 | 最近一次通信成功;在一定时间内(默认约 30 秒)认为可达。 |
| STALE | 过期 | 超过 REACHABLE 状态的时间但尚未重新探测,下次使用时会触发探测。 |
| DELAY | 延迟 | 使用过期条目时,内核会等待短暂时间(默认 5 秒)以接收无请求的 ARP 响应。 |
| PROBE | 探测中 | 发送 ARP 探测以重新验证邻居的可达性。 |
| FAILED | 失败 | 多次 ARP 或探测均失败,确认不可达。 |
| NOARP | 不需要 ARP | 主要用于点对点连接(如 GRE、TUN),不需要 ARP 协议。 |
| PERMANENT | 静态 | 手动添加的静态邻居条目,永不超时。 |
状态转换典型流程
REACHABLE → STALE → DELAY → PROBE → REACHABLE
↓
(失败)
FAILED
3. 查看邻居表状态的方法
- 查看所有邻居表:
ip neigh show
- 查看特定 IP 的邻居表:
ip neigh show <IP地址>
- 查看特定网卡的邻居表:
ip neigh show dev <接口名>
- 持续监控状态变化:
watch -n1 'ip neigh show | grep <IP或MAC>'
4. Linux ARP 缓存相关的内核参数
Linux 系统的 ARP 缓存并非简单的 TTL 机制,而是结合了 NUD 状态机和多个计时器。以下是几个关键参数及其默认值:
| 参数 | 默认值 | 意义 |
| base_reachable_time_ms | 30000 ms | REACHABLE 状态的持续时间(约 30 秒,包含随机扰动)。 |
| gc_stale_time | 60 秒 | 条目变为 STALE 状态前的时间。 |
| delay_first_probe_time | 5 秒 | DELAY 状态的持续时间。 |
| ucast_solicit / mcast_solicit | 3 次 | 在 PROBE 阶段发送单播/广播 ARP 试探的次数。 |
查看这些参数的命令如下:
cat /proc/sys/net/ipv4/neigh/default/base_reachable_time_ms
cat /proc/sys/net/ipv4/neigh/default/gc_stale_time
cat /proc/sys/net/ipv4/neigh/default/delay_first_probe_time
5. MetalLB Layer2 模式对 ARP 缓存的影响
MetalLB 在 Layer2 模式下通过发送免费 ARP(GARP)来宣布 VIP(LoadBalancer IP),使局域网内的所有主机更新其 ARP 缓存,指向当前的“owner node”。具体行为包括:
- VIP 分配时,立即发送 GARP 以刷新各主机的 ARP 缓存。
- 定期发送 GARP,默认每 30 秒一次。
- 当 VIP 的拥有者发生变化时,立即发送大量的 GARP 以实现快速收敛。
配置示例(可调整 GARP 发送周期):
protocol: layer2
announcement-interval: 30s
6. MetalLB 与 Linux ARP 的综合行为分析
由于 Linux 默认的 ARP 超时设置为:REACHABLE 状态约为 30 秒,STALE 状态在 60 秒后触发验证,而 MetalLB 每 30 秒广播一次 GARP,因此:
最终效果:局域网内的主机能够及时更新其 ARP 缓存,确保 VIP 的高可用性和快速切换。
7. 观察 MetalLB 对 ARP 缓存的刷新
可以通过监控 ARP 缓存的变化来观察 MetalLB 如何影响 ARP 缓存的刷新。
8. 常见排障技巧
- 某节点无法访问 VIP:检查该节点的 ARP 缓存,确认 VIP 是否正确指向当前的“owner node”。
- GARP 没有广播:检查 MetalLB 的配置,确保 GARP 广播功能正常开启。
- VIP 切换慢:检查 MetalLB 的配置,特别是 GARP 广播的频率,以及网络中的其他可能延迟因素。
9. 总结
本文档总结了 Linux 系统中 ARP 和邻居表的关键知识点,包括状态管理、缓存机制、内核参数设置,以及 MetalLB 在 Layer2 模式下对 ARP 缓存的影响。希望这些信息能帮助读者更好地理解和解决相关问题。
邻居表几乎总是处于 REACHABLE 或 STALE 状态,然后很快就会被刷新。ARP 的实际“有效时长”大约为 30 秒,这主要受到 MetalLB GARP 周期的影响。
当 VIP 切换到另一个节点时,收敛速度非常快,因为 GARP 会立即覆盖旧的记录。
如何观察 MetalLB 对 ARP 的刷新
要观察 MetalLB 如何刷新 ARP 表,可以在 Linux 主机上使用以下命令:
watch -n1 'ip neigh show | grep <VIP>'
这将显示一个类似的循环过程,如下图所示:
REACHABLE → STALE → REACHABLE → ...
默认情况下,MetalLB 的配置会使这个周期约为 30 秒。
常见排障技巧
- 某节点无法访问 VIP:首先检查本机的 ARP 表:
ip neigh show | grep <VIP>
如果发现 MAC 地址错误或状态为 FAILED,则可能导致访问失败。此时可以通过以下命令重置 ARP 表:
ip neigh flush dev <接口>
- GARP 没有广播:检查
metallb-speaker 的日志:
kubectl -n metallb-system logs -l component=speaker
- VIP 切换慢:检查以下几项:
- announcement-interval 设置是否过大
- 交换机是否过滤了 ARP 请求
- 节点网卡是否有 ARP 抑制设置(例如 bond 参数)
总结
Linux ARP 缓存的生命周期是由 NUD 状态机控制的,而不是简单的 TTL 计时器。常见的 NUD 状态包括:INCOMPLETE、REACHABLE、STALE、DELAY、PROBE、FAILED、NOARP 和 PERMANENT。
在 MetalLB 的 Layer2 模式下,通过定期发送 GARP(默认每 30 秒一次),不断刷新邻居表,确保 VIP 的 ARP 记录不会过期。在实际运行中,ARP 状态通常在 REACHABLE 和 STALE 之间切换。
排障的重点在于:
ip neigh show
以及:
metallb speaker logs
如果需要进一步的帮助,还可以参考以下内容:
- MetalLB speaker 的 GARP 数量与周期调优
- ARP 包抓包示例(使用 tcpdump)
- 针对 bond/team/VLAN 的特殊情况说明
- VIP 漂移时的 ARP 冲突排查