华为ECS下安装docker服务部署容器,在其中一个容器下ping其他容器,无论是容器名还是IP都出现“ping: sendmsg: Invalid argument”
用户Linux云服务器向同子网服务器发起请求时,服务端已经收到包,但是没有回包。在服务器端对客户端进行ping操作时返回“sendmsg: Invalid argument”。
64 bytes from 192.168.0.54: icmp_seq=120 ttl=64 time=0.064 ms
64 bytes from 192.168.0.54: icmp_seq=122 ttl=64 time=0.071 ms
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
用户在Linux云服务器日志文件/var/log/messages中查询到或运行dmesg命令输出neighbour table overflow异常信息。
[21208.317370] neighbour: ndisc_cache: neighbor table overflow!
[21208.317425] neighbour: ndisc_cache: neighbor table overflow!
[21208.317473] neighbour: ndisc_cache: neighbor table overflow!
[21208.317501] neighbour: ndisc_cache: neighbor table overflow!
问题原因
Neighbour表引用ARP缓存,Neighbour表溢出说明ARP表满了,新的连接会因为ARP表满而被拒绝,导致连接问题。
可以通过以下命令来检查最大ARP缓存表大小:
cat /proc/sys/net/ipv4/neigh/default/gc_thresh3
ARP缓存表有三个参数,分别如下:
/proc/sys/net/ipv4/neigh/default/gc_thresh1
/proc/sys/net/ipv4/neigh/default/gc_thresh2
/proc/sys/net/ipv4/neigh/default/gc_thresh3
gc_thresh1,最小条目数。如果缓存中的条目数少于此数目,则垃圾回收器将不会运行。
gc_thresh2,软最大条目数。如果实际条目数超过该值超过5秒,垃圾收集器将运行。
gc_thresh3,硬最大条目数。如果缓存中的条目数超过此数目,则垃圾回收器将始终运行。
要验证IPv4的ARP条目的实际数量,可以运行以下命令:
ip -4 neigh show nud all | wc -l
解决方案
规划网段时控制子网可容纳的主机数量小于default.gc_thresh3值。
调整内核参数,修改ARP缓存条目数,使gc_thresh3的值远大于VPC同一网段内实例数量。并确保gc_thresh3的值大于gc_thresh2的值,gc_thresh2的值大于gc_thresh1的值。
假设子网为20位掩码,则网络内可容纳的主机数最大为4096,则default.gc_thresh3的数值不能小于4096。
临时生效:
sysctl -w net.ipv4.neigh.default.gc_thresh1=10240
sysctl -w net.ipv4.neigh.default.gc_thresh2=20480
sysctl -w net.ipv4.neigh.default.gc_thresh3=40960
永久生效:
编辑/etc/sysctl.conf添加内容如下:
net.ipv4.neigh.default.gc_thresh1 = 10240
net.ipv4.neigh.default.gc_thresh2 = 20480
net.ipv4.neigh.default.gc_thresh3 = 40960
如果系统环境需要使用到IPV6,则还需要添加IPV6的配置项:
net.ipv6.neigh.default.gc_thresh1 = 10240
net.ipv6.neigh.default.gc_thresh2 = 20480
net.ipv6.neigh.default.gc_thresh3 = 40960