运维排查篇 | Linux 连接跟踪表满了怎么处理
nf_conntrack (在老版本的 Linux 内核中叫 ip_conntrack )是一个内核模块,用于跟踪一个网络连接的状态
一旦内核 netfilter 模块 conntrack 相关参数配置不合理,导致 nf_conntrack table full ,就会出现丢包、连接无法建立的问题
这个问题其实是老问题了,之前也听说过,但都是左耳进右耳出,直到上周线上出现故障了,才真正的对这个问题有了一个较为全面的了解
于是我把我真实遇到的情况总结成今天这篇文章,让大家对这个问题产生的原因和背后细节有一个较好的了解
1.案例现象
上周周末,我们打算对 A 服务进行压测,在压测过程中测试小伙伴反馈后端服务挂了
登上机器查看一下服务器负载,发现正常,没有出现因负载过高导致服务器宕机的情况
然后查看 A 服务的日志,没有看到相关的请求记录,没有发现异常
接下来打算查看一下系统日志(/var/log/messages)
这时候才发现了不对劲,系统日志上记录了大量错误信息,如下:
Feb 18 14:02:17 localhost kernel: nf_conntrack: table full, dropping packet
Feb 18 14:02:17 localhost kernel: nf_conntrack: table full, dropping packet
Feb 18 14:02:17 localhost kernel: nf_conntrack: table full, dropping packet
Feb 18 14:02:17 localhost kernel: nf_conntrack: table full, dropping packet
Feb 18 14:02:22 localhost kernel: nf_conntrack: table full, dropping packet
Feb 18 14:02:22 localhost kernel: nf_conntrack: table full, dropping packet
看打印出来的信息应该是这个压测时候的高并发连接触发了 nf_conntrack 保护机制——table 满了之后就开始 drop packet
2.定位问题
根据系统日志可以基本定位到是 nf_conntrack
的问题,我们先来看看什么是 nf_conntrack
何为 nf_conntrack
nf_conntrack
从名字上看是 connection tracking ,它是一个内核模块,用于跟踪网络连接的状态
下面这个网站记录了有关这个模块的相关参数的含义,有兴趣的可以上去看看
https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt
nf_conntrack
与 iptables 有关,用来计算服务器上的 iptables 规则,最常见的两个使用场景是 iptables 的 nat 模块和 state 模块
我们知道,iptables 中 nat 模块的作用就是根据规则来修改目的地址或源地址
但光修改地址还不行,我们还需要到达的包能够路由到发请求的服务器,这时候就需要通过 nf_conntrack
来找到 nat 修改前那个连接的记录
而 state 模块通过 nf_conntrack
记录的连接状态(NEW
/ESTABLISHED
/RELATED
/INVALID
等)来匹配防火墙过滤规则
我们可以先看看 conntrack 的跟踪信息记录,我们可以在/proc/net/nf_conntrack
中看到已经被跟踪的连接
cat /proc/net/nf_conntrack
ipv4 2 tcp 6 431930 ESTABLISHED src=192.168.149.131 dst=192.168.149.130 sport=11638 dport=4505 src=192.168.149.130 dst=192.168.149.131 sport=4505 dport=11638 [ASSURED] mark=0 zone=0 use=2
可以看出,2 是 ipv4 的协议代码(网络层),6 是 tcp 的协议代码(传输层),这里 conntrack 可以跟踪 tcp/udp/icmp
等各种协议类型
ipv4 2
tcp 6
431930 则是该连接的生命周期(默认是五天),在收到新包之前该值会逐渐变小,如果收到新包,该值会被重置一下,然后又开始重新计时
431930
ESTABLISHED 是连接状态,不是所有协议都有(例如 udp)
ESTABLISHED
接下来就是四元组,第一个地址四元组(源地址和目标地址以及端口)是在原始方向上记录的地址,即发起方发送的地址
src=192.168.149.131 dst=192.168.149.130 sport=11638 dport=4505
第二个四元组是 conntrack 希望在收到来自对等方的答复时看到的内容
src=192.168.149.130 dst=192.168.149.131 sport=4505 dport=11638
最后的 ASSURED 就是该状态已经确认
[ASSURED]
nf_conntrack 是如何存储连接信息的
上面部分介绍了 nf_conntrack 模块的作用——追踪连接
接下来该介绍 nf_conntrack 模块是怎么存储这些 track 信息的
我们首先需要知道nf_conntrack
将每一条连接信息都 track 到一个哈希表里面(hash table),一条 conntrack 连接信息也称条目(entry)
哈希表中的最小存储单位称作 哈希桶(bucket),哈希表的大小称作 HASHSIZE
,所以哈希表有 HASHSIZE
个 bucket
bucket 的大小对应 nf_conntrack 模块中的nf_conntrack_buckets
值
而每个 bucket 包含一个链表(link list),每个链表都能够存放若干条 entry(bucket size
)
nf_conntrack_max
则表示系统最大允许连接跟踪数,即 entry 的个数
#nf_conntrack_max等于 bucket 个数乘上每个 bucket 的大小
nf_conntrack_max = HASHSIZE * bucket size
当有新的数据包到来时,内核是如何判断这条连接信息是否被 track 到的
- 内核提取此数据包信息(源目IP,port,协议号)进行 hash 计算得到一个 hash 值,在哈希表中以此 hash 值做索引,索引结果为数据包所属的 bucket。这一步 hash 计算时间固定并且很短
- 遍历 hash 得到所属的 bucket,查找是否有匹配的 entry。这一步是比较耗时的操作,
bucket size
越大,遍历时间越长 - 如果没有匹配到,则就新建
理想情况下,每个 bucket 下 link list 只存储一条 entry(即 bucket size = 1
),这样查询效率是最高的,每次查询追踪记录的时候都是完美的 O(1) 的效率
但如果一个 bucket 存放一个 entry,这样会导致内存消耗非常大
官方指出:每个 entry 会占用大概 300 字节的空间,如果一个 bucket 存放一个 entry,那么整个哈希表的大小就等于总 entry 的大小
假设一个 bucket 存放一个 entry,我们设置 nf_conntrack_max == 12262144,就意味着哈希表可以存放12262144条 entry
这样我们会需要12262144308字节= 12262144308/(1024*1024) = 3508.22753906MB ,大约3个G的内存
一般服务器配置高点的,32G内存或者64G,光是给 connection track 就达到了 3G,更何况其中有些连接还是没有实际意义的已经被释放掉的 time_wait 的连接
那么一个 bucket 里应该存放多少条 entry 呢?
我们看下官方的解释,官方一般推荐一个 bucket 里存放四条 entry
nf_conntrack_max = nf_conntrack_buckets *4
如果一个 bucket 存放过多的 entry,就意味着每个 bucket 中的 link list 会非常长,会影响 hash 查询效率
所以一个 bucket 里存放四条 entry,兼顾时间和存储空间
3.解决问题
回到遇到的问题,既然报错是nf_conntrack: table full, dropping packet
那就意味着系统的连接跟踪表满了,我们有如下几种方法可选,请大家可以结合自己服务器情况来选择使用
- 关闭防火墙
对不直接暴露在公网,也不使用 NAT 转发的服务器来说,关闭 Linux 防火墙是最简单的办法,还能避免防火墙/ netfilter 成为网络瓶颈
#以 CentOS 7 为例
systemctl stop firewalld
systemctl disable firewalld
- 修改 iptables 规则
对于需要防火墙的机器,可以设置 NOTRACK 规则,减少要跟踪的连接数
对于一些不需要 track 的连接,针对对应的 iptables 规则加一个 notrack 的动作
# 表示凡是不跟踪的连接统统放行
# iptables 处理规则的顺序是从上到下,如果这条加的位置不对,可能导致请求无法通过防火墙
iptables -I INPUT 1 -m state --state UNTRACKED -j ACCEPT
-j notrack
把不需要 track 的 iptables 直接 notrack,那自然就不会去占 hashtable 空间了,更不会报错了
- 优化内核参数
一般来讲有下面两个逻辑:
- 哈希表扩容(
nf_conntrack_buckets
、nf_conntrack_max
) - 让哈希表里面的元素尽快释放(超时相关参数)
对于nf_conntrack_buckets
和 nf_conntrack_max
的值,官方给了一个推荐大小
nf_conntrack_buckets - INTEGER
the default size is calculated by dividing total memory
by 16384 to determine the number of buckets but the hash table will
never have fewer than 32 and limited to 16384 buckets. For systems
with more than 4GB of memory it will be 65536 buckets.
This sysctl is only writeable in the initial net namespace.
nf_conntrack_max - INTEGER
Size of connection tracking table. Default value is
nf_conntrack_buckets value * 4
可以看到nf_conntrack_max
与宿主机的内存相关,有个默认算法
#其中 x 为 CPU架构,值为 32 或 64
CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (x / 32)
假设宿主机架构为 64 位且内存为 64GB,所以nf_conntrack_max
值如下:
CONNTRACK_MAX = 64 * 1024 * 1024 * 1024 / 16384 / (64 / 32) = 2097152
又因为nf_conntrack_max = nf_conntrack_buckets value * 4
nf_conntrack_buckets = 2097152 / 4 = 524288
nf_conntrack_max = 2097152 nf_conntrack_buckets = 524288
PS:要根据自身服务器配置情况来进行配置,切勿一刀切!
对于超时时间,下列给出一些官方默认参数供大家参考,结合自身服务器情况进行修改
nf_conntrack_tcp_timeout_established
:默认 432000 秒(5天)
代表 nf_conntrack 的 TCP 连接记录时间默认是五天,五天后该记录就被删除掉
攻击者可以根据这个参数,与你的服务器三次握手一建立就关闭 socket,分分钟把你的连接跟踪表打爆
net.netfilter.nf_conntrack_icmp_timeout
:默认 30s
谁家 ping 等 30s 才算超时?
nf_conntrack_tcp_timeout_syn_sent
:默认 120s
谁家程序的 connect timeout 需要 120s
nf_conntrack_tcp_timeout_last_ack
:默认 30s
被动关闭方发 FIN 后如果一直收不到对面的 ACK 或 RST,会不断重发,直到超时才 CLOSE
nf_conntrack_tcp_timeout_time_wait
:默认 120s
大家都知道 TIME_WAIT其实就是为了四次挥手的时候让数据包能够收收尾,现在网络环境好了,可以设置成 60s,没必要对 TIME_WAIT 的连接跟踪这么长时间
相关文章:

运维排查篇 | Linux 连接跟踪表满了怎么处理
nf_conntrack (在老版本的 Linux 内核中叫 ip_conntrack )是一个内核模块,用于跟踪一个网络连接的状态 一旦内核 netfilter 模块 conntrack 相关参数配置不合理,导致 nf_conntrack table full ,就会出现丢包、连接无法建立的问题 这个问题其…...

docker网络基
本文简单介绍下,容器之间的网络访问、容器与宿主机之间的网络访问、宿主机上有哪些网络接口。lolocal的简写,本地回环地址,127.0.0.1,它代表本地虚拟设备接口,默认被看作是永远不会宕掉的接口eth0ethernet的简写&#…...

C++:谈谈单例模式的多种实现形式
文章目录实现 1:静态成员实现 2:atexit 懒汉模式实现 3:原子变量 懒汉模式实现4:atexit 饿汉模式* 实现5:magic static单例模式:保证一个类仅有一个实例,并提供一个该实例的全局访问点。 稳…...

【Spring Cloud Alibaba】007-Nacos 配置*
【Spring Cloud Alibaba】007-Nacos 配置* 文章目录【Spring Cloud Alibaba】007-Nacos 配置*一、概述1、概述2、对比 spring cloud config二、基本使用1、在管理界面新建配置2、启动权限3、 搭建 nacos-config 服务第一步:引入依赖第二步:修改 yaml 配置…...

《安富莱嵌入式周报》第304期:开源硬件耳机设计,AI单片机STM32N6已确定为M55内核,另外还有新品STM32H5, H50X, H7R, H7S发布
往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程: 第6期ThreadX视频教程:图文并茂吃透RTOS运行机制,任务管理&…...

vuex篇
1.简介(1)vuexVuex 是一个专为 Vue.js 应用程序开发的状态管理模式 库vuex是为vue.js开发的状态管理模式、组件状态集中管理(2)单页面数据流状态发生变化, 视图就重新渲染state发生变化时, 导致view视图发生改变, 视图通过操作action行为, 又会使得state状态发生变化(3)使用场…...

嵌入式开发:在嵌入式应用程序中混合C和C++
许多嵌入式应用程序仍使用c语言编写,但越来越多的嵌入式开发人员现在使用C语言编写程序。某些应用程序甚至共享这两种语言。这有意义吗?C是嵌入式应用中最常用的编程语言。多年来,人们一直期待着向C过渡,但过渡速度相当缓慢。但是࿰…...

【2023/图对比/增强】MA-GCL: Model Augmentation Tricks for Graph Contrastive Learning
如果觉得我的分享有一定帮助,欢迎关注我的微信公众号 “码农的科研笔记”,了解更多我的算法和代码学习总结记录。或者点击链接扫码关注【2023/图对比/增强】MA-GCL: Model Augmentation Tricks for Graph Contrastive Learning 【2023/图对比/增强】MA-…...

TensorBoard自定义修改单条及多条曲线颜色
在深度学习可视化训练过程中,曲线颜色是随机的,想要将好看的曲线颜色图放到论文中,就得自定义曲线颜色,具体方法见下文。 目录一、下载svg文件二、修改svg文件三、修改后曲线颜色对比四、总结一、下载svg文件 在TensorBoard界面中…...

时间和空间复杂度
文章目录 前言 一、算法效率 1.如何评判算法效率? 2.算法的复杂度 二、时间复杂度 1.时间复杂度的定义 2. 大O的渐进表示法 三、空间复杂度 总结 前言 本文章讲解时间与空间复杂度 提示:以下是本篇文章正文内容,下面案例可供参考 一、算法…...

关于Linux下调试
关于Linux下调试 无论是内核(操作系统)还是应用程序,都存在需要调试的情况。 所谓工欲善其事,必先利其器。一个好的称手的工具,对于快速分析问题、定位问题,提高效率,非常有帮助。 除了工具&a…...

理解TP、FP、TN、FN
概念定义 按照常用的术语,将两个类分别称为正类 (positive) 和 负类 (negative)。使用数学表示: 1表示正类 , -1 表示负类。 正类通常是少数类,即样本较少的类(例如有缺陷的零件) 负类通常是多数类&#x…...

软考中级有用吗
当然有用了! 软考“简历”:计算机软件资格考试在全国范围内已经实施了二十多年,近十年来,考试规模持续增长,截止目前,累计报考人数约有五百万人。该考试由于其权威性和严肃性,得到了社会各界及用人单位的广泛认同&…...

计算机网络之IP协议(详解
网络层主管地址管理与路由选择。而IP协议就是网络层中一个非常重要的协议。它的作用就是在复杂的网络环境中确定一个合适的路径。IP协议头格式4位版本号(version) 指定IP协议的版本,目前只有两个版本:IP v4和IP v6.对于IP v4来说,这个值就是4…...

Kubernetes之探针probe
deployment只保证pod的状态为running。如果pod状态是running,但是里面丢失了文件,导致用户不能访问数据,则deployment是不管用的,此时就需要probe来检测pod是否正常工作。 probe是定义在容器里的,可以理解为容器里加的…...

高性能低功耗4口高速USB2.0 HUB NS1.1S 兼容FE1.1
NS1.1S是一款高性能、低功耗4口高速 USB2.0 HUB 控制器,上行端口兼容高速 480MHz和全速12MHz两种模式,4个下行端口兼容高速480MHz、全速12MHz、低速1.5MHz三种模式。 NS1.1S采用状态机单事务处理架构,而非单片机架构,多个事务缓冲…...

通过VS Code轻松连接树莓派
如果您正在使用树莓派作为开发平台,那么通过远程连接VS Code到树莓派是非常方便的一种方法。这样,您可以在Windows或macOS等计算机上开发和测试代码,而不必在树莓派上进行。 以下是通过VS Code远程连接到树莓派的步骤: 1.安装Re…...

图纸等敏感文件数据外发时 如何确保效率和安全性?
很多企业随着业务的发展,需要频繁的与外部供应商、合作伙伴之间进行数据的交换和使用。尤其是制造型企业,可能每天都要与几十、上百家供应商及合作伙伴进行产品数据交换。目前,大多数企业已经在内部实施了PDM/PLM系统,实现了对组织…...

2023年CDGA考试-第4章-数据架构(含答案)
2023年CDGA考试-第4章-数据架构(含答案) 单选题 1.请从下列选项中选择不属于数据架构师职责的选项 A.确保数据架构和企业战略及业务架构一致 B.提供数据和组件的标准业务词汇 C.设计企业数据模型 D.整合企业数据架构蓝图 答案 C 2.请从下列选项中选择不属于企业数据架构…...

理解随机游走
随机游走 基本思想 从一个或一系列顶点开始遍历一张图。在任意一个顶点,遍历者将以概率1-a游走到这个顶点的邻居顶点,以概率a随机跳跃到图中的任何一个顶点,称a为跳转发生概率,每次游走后得出一个概率分布,该概率分布…...

mqtt协议1- 简介和报文格式
文章目录1.mqtt协议1: 简介和报文格式1.1.MQTT概念1.2.数据2.控制报文格式2.1.MQTT数据包结构2.2.固定头2.2.1.控制报文类型2.2.2.标志FLag2.2.3.剩余长度2.3.可变头2.4.有效载荷Payload消息体安全QoS(Quality of Service levels)ref:1.mqtt协议1: 简介和报文格式 Message Que…...

前端用动画快速实现骨架屏效果
一、动画的语法 1.定义动画 keyframes 自定义动画名称 {// 开始from {transform: scale(1);}// 结束to {transform: scale(1.5);} }// 或者还可以使用百分比定义keyframes 动画名称 {// 开始0% {transform: scale(1);}// 结束100% {transform: scale(1.5);} } 2.调用 anima…...

Python入门(未完待续。。。)
认识python 解释型(写完直接运行)、面向对象的高级编程语言;开源免费、支持交互式、可跨平台移植的脚本语言;优点:开源、易于维护、可移植、简单优雅、功能强大、可扩展、可移植;缺点:解释型→运…...

注解配置SpringMVC
使用配置类和注解代替web.xml和Spring和SpringMVC配置文件的功能。创建初始化类,代替web.xmlSpring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了Abstr…...

多项新规重磅发布,微信视频号近期需要关注这几点
随着功能的完善和内容生态的丰富,视频号逐渐放慢产品更新频率,将重点放到商家准入标准、创作者扶持计划上来,本期我们将更侧重解读平台新规,帮助大家了解行业动向,把握最新趋势。01 视频号小店结算规则修订 取消48小时…...

Java调用第三方http接口的方式
1. 概述 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)。 在Java项目中调用第三方接…...

【跟我一起读《视觉惯性SLAM理论与源码解析》】第五章第六章 对极几何图优化库的使用
极平面,极点,极线的概念对极几何,对极约束的概念,通过叉积以及点积的性质推导单应矩阵以及基础矩阵光束平差法BA是LSAM中常用的非线性优化方法一个图由若干个顶点以及这些顶点连接的边构成,顶点通常是待优化的变量例如…...

从没想过开源 API 工具的 Mock 功能,这么好用
很多时候,接口尚未开发完成,在系统交互双方定义好接口之后,我们可以提前进行开发和测试,并不依赖上游系统的开发实现。 通过使用Mock模拟数据接口,我们即可在只开发了UI的情况下,无须服务端的开发就可以进行…...

智慧教室--智能管控系统
智慧教室系统是一款基于AIOT数字化平台的智能教育解决方案,该系统实现了全面数字化、自动化管理和智能化控制,可大大提高教学效率和质量,为学生带来更加优质的教育体验。智能管控是智慧教室系统的核心功能之一。通过物联网技术,将…...

React的useLayoutEffect和useEffect执行时机有什么不同
我们先看下 React 官方文档对这两个 hook 的介绍,建立个整体认识 useEffect(create, deps): 该 Hook 接收一个包含命令式、且可能有副作用代码的函数。在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以…...