做者朱瑜坚,腾讯云后台开发工程师,熟悉 CNI 容器网络相关技术,负责腾讯云 TKE 的容器网络的构建和相关网络组件的开发维护工做,做为主力开发实现了 TKE 下一代容器网络方案。shell
最近,某内部客户的 TKE VPC-CNI 模式的独立网卡集群上出现了 pod 间访问不通的状况,问题 pod ping 不通任何其余 pod 和节点。缓存
查看 dmesg 内核日志,有以下报错信息:neighbour: arp_cache: neighbor table overflow!(下图为后续复现的日志截图)网络
而且,这个集群规模较大,约有 1000 个节点,30000 个 pod,基本能够怀疑是因为集群规模较大,致使 ARP 表项过多,从而引发 ARP Overflow 的问题。数据结构
名词 | 说明 |
---|---|
TKE | 全称 Tencent Kubernetes Engine, 腾讯云容器服务,是基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务 |
VPC-CNI 模式 | 是容器服务 TKE 基于 CNI 和 VPC 弹性网卡实现的容器网络能力 |
Pod | Pod 是 kubernetes 的基本资源管理单位,拥有独立的网络命名空间,1个 Pod 可包含多个容器 |
从如上报错信息可知,这个问题的基本缘由在于 ARP 缓存表打满了。这里涉及到内核的 ARP 缓存垃圾回收机制。当 ARP 表项太多且又没有可回收的表项的时候,新表项就会没法插入。性能
这就致使网络包发送时没法找到对应的硬件地址(MAC)。使得网络包不能发送。测试
那么具体什么状况会致使新表项没法插入呢?回答这个问题,咱们须要先深刻了解一下 ARP 缓存老化及垃圾回收机制。spa
如上图,是整个 ARP 表项的生命周期及其状态机。日志
咱们知道,对于 TCP/IP 网络包发送时,网络栈须要对端的 MAC 地址才能让网络包转换成二层的数据结构——帧,从而在网络中传输。而对于不一样广播域的 IP 地址,其对端 MAC 地址为网关,发送端会将网络包发给网关让其转发,而对于同广播域中的 IP 地址,其对端 MAC 地址即与 IP 地址对应。code
而经过 IP 地址找到 MAC 地址就是 ARP 协议的主要工做内容。ARP 协议的工做过程此处再也不赘述,而经过 ARP 协议找到 IP 地址对应的 MAC 地址后,会将该对应关系存储在本机上一段时间,以减小 ARP 协议的通讯频率,加快网络包的发送。该对应关系,即 ARP 缓存表项,其状态机或整个生命周期可描述以下:blog
经过如下命令可查看当前网络命名空间(network namespace) 中 arp 表项及其状态:
ip neigh
如:
本机确认:这是代指本机收到了一个源 mac 地址匹配的网络包,这个网络包表示这次网络通讯的“上一跳”便是该 mac 地址的机器,能收到这个网络包即说明该 mac 地址可达。所以便可把该表项转为 Reachable 状态。经过这一机制,内核可减小 ARP 的通讯需求。
如下列出了该机制中主要涉及的内核参数:
参数 | 含义 | 默认值 |
---|---|---|
/proc/sys/net/ipv4/neigh/default/base_reachable_time | Reachable 状态基础过时时间,每一个表项过时时间是在[1/2base_reachable_time,3/2base_reachable_time]之间 | 30秒 |
/proc/sys/net/ipv4/neigh/default/base_reachable_time_ms | Reachable 状态基础过时时间,毫秒表示 | 30秒 |
/proc/sys/net/ipv4/neigh/default/gc_stale_time | Stale 状态过时时间 | 60秒 |
/proc/sys/net/ipv4/neigh/default/delay_first_probe_time | delay 状态过时到 Probe 的时间 | 5秒 |
/proc/sys/net/ipv4/neigh/default/gc_interval | gc 启动的周期时间 | 30秒 |
/proc/sys/net/ipv4/neigh/default/gc_thresh1 | 少于这个值,gc 不会启动 | 2048 |
/proc/sys/net/ipv4/neigh/default/gc_thresh2 | ARP表的最多纪录的软限制,容许超过该数字5秒 | 4096 |
/proc/sys/net/ipv4/neigh/default/gc_thresh3 | ARP表的最多纪录的硬限制,大于该数目,gc当即启动,并强制回收 | 8192 |
其中,gc 相关的内核参数是对全部网卡(interface)生效的。可是各类到期时间的设置是仅对单独网卡(interface)生效的,default 值仅对新增接口设备生效。
由其缓存表项的状态机咱们知道,不是全部的表项都会被回收,只有 Stale 状态过时后,Failed 的表项可能会被回收。另外,ARP 缓存表项的垃圾回收是触发式的,须要回收的表项不必定马上会被回收,ARP 缓存表项的垃圾回收有四种启动逻辑:
对于不可回收的表项,垃圾回收即使启动了也不会对其进行回收。所以当不可回收的表项数量大于 gc_thresh3 的时候,垃圾回收也无能为力了。
咱们知道,每一个独立的网络命名空间是有完整的网络协议栈的。那么,ARP 缓存的垃圾回收也是每一个命名空间单独处理的吗?
从涉及的内核参数能够看出,gc 相关的内核参数是对全部接口设备生效的,所以,这里能够推测垃圾回收的阈值也是子机级别生效的,而不是按网络命名空间。
这里作了一个简单的实验来验证:
能够发现, 各命名空间的累计 arp 表项的数目在每次达到 60 以后就会快速降低,也就是达到 60 以后就产生了垃圾回收。重复几回都是相似的结果,所以,这说明了垃圾回收在计算 ARP 表项是否触发阈值时,是计算各命名空间的累计值,也就是按子机级别生效,而非命名空间级别。
由前面的介绍咱们知道,垃圾回收机制并不是回收任意 ARP 缓存,所以,当全部可达状态的 ARP 表项打满 ARP 缓存表时,也即达到 gc_thresh3 时,会发生什么行为?能够推测,此时旧的没法回收,新的 ARP 表项也没法插入,新的网络包会没法发送,也即发生了本次文章所描述的问题。
为了验证这一点,继续在以上环境中实验:
查看内核日志 dmesg -T,能够看到文章开头描述的信息:neighbour: arp_cache: neighbor table overflow!
以上实验说明了,不可回收的 ARP 表项打满 ARP 表会让新的表项没法插入,从而网络不通。
要回答这个问题,咱们先简单看一下 TKE 各网络模式的原理介绍
该网络模式下,每一个节点上的容器 IP 是预先分配到节点上的,这些 IP 同属一个子网,且每一个节点就是一个小子网。咱们知道,ARP 协议是为二层通讯服务的,所以,该网络方案中,每一个 Pod 的网络命名空间内的 ARP 表最大可能保存了节点上全部其余 Pod 的 ARP 表项,最后节点的 ARP 表项的数量最大即为 节点子网 IP 数的平方,如节点的子网大小是128,则其 ARP 表项最大可能为 127 的平方,约 16000。
该网络模式下,每一个节点会绑定辅助弹性网卡,节点上的 Pod 共享使用该辅助网卡,每一个 Pod 内不会作网络包的路由,只会有一条 ARP 表项,实际的路由控制在节点的 default 命名空间内完成。所以,该网络模式下,ARP 缓存表几乎是共享的,又由于网卡只能属于 1 个子网,所以每一个节点的 Pod ARP 缓存表只能存储一个子网的 IP-MAC 映射关系,至多数量为各网卡所在子网内 IP 的数量和,如子网是 /22,即含有约 1000 个 ip, 那么 arp 表项也大概有 1000,因为节点网卡配额通常不超过 10,所以该节点的最大 ARP 表项通常不超过 10000。
独立网卡模式是 TKE 团队推出的下一代“零损耗”容器网络方案,其基本原理以下图所示:
即母机虚拟出的弹性网卡,直接置于容器中,使容器得到与 CVM 子机同样的网络通讯能力和网络管理能力,大大提高了容器网络的数据面能力,真正作到“零损耗”。
目前,独立网卡网络方案已在 TKE 产品中开放白名单测试,欢迎内外部客户体验试用。
以上网络方案中,每一个 Pod 都会独占一个网卡,也会拥有独立的命名空间和独立的 ARP 缓存表。而每一个网卡均可以属于不一样的子网。所以,在独立网卡模式里,ARP 缓存表项数量至多为同可用区的子网 IP 数量之和。这一数量量级是能够很轻易上万的,很容易就突破了默认的 ARP 缓存设置。也就触发了这个问题。
从以上的分析能够看出,这个问题,调大垃圾回收的阈值,能够比较好的解决问题。所以,临时的解决方案,就是调大 ARP 缓存表的垃圾回收阈值:
echo 8192 > /proc/sys/net/ipv4/neigh/default/gc_thresh1echo 16384 > /proc/sys/net/ipv4/neigh/default/gc_thresh2echo 32768 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
ARP 缓存打满以后,Pod 就会网络不通。初看起来很简单,可是其背后的 ARP 缓存老化和垃圾回收机制也是比较复杂的。查询了不少资料,可是都对“垃圾回收阈值是对各命名空间的 ARP 表项累积值生效仍是单独生效”,“垃圾回收会回收哪些表项”,“表项打满后的具体行为如何”等问题说不清、道不明。所以,笔者尝试经过几个小实验验证了具体的行为模式。相比直接阅读晦涩的内核源码,实验法也许也是一个研究问题和理解机制的捷径了。但愿可以帮助到各位读者。
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!