Linux网络子系统中的计数器

在Prometheus node-exporter中,存在多个网络监控指标指标标志着主机的网络状态,但是大家常常忽略这些指标,而这些指标又很重要,这些指标的来源是根据Linux网络子系统中的多个计数器定义的,本文就解开这些TCP计数器的面目。 TcpExtListenOverflows 和 TcpExtListenDrops 当内核从客户端接收到 SYN 时,如果 TCP 接受队列已满,内核将丢弃 SYN 并将 TcpExtListenOverflows +1。同时内核也会给TcpExtListenDrops +1。当 TCP 套接字处于 LISTEN 状态,并且内核需要丢弃数据包时,内核总是将 TcpExtListenDrops +1。因此,增加 TcpExtListenOverflows 将使 TcpExtListenDrops 同时增加,但在不增加 TcpExtListenOverflows 的情况下,TcpExtListenDrops 也会增加,例如内存分配失败也会导致 TcpExtListenDrops 增加。 以上解释基于内核 4.10 或更高版本,在旧内核上,当 TCP 接受队列已满时,TCP Stack有不同的行为。在旧内核上,TCP Stack不会丢弃 SYN,它会完成 3 次握手。当接受队列已满时,TCP 堆栈会将套接字保留在 TCP 半开队列中。由于处于半开队列中,TCP 堆栈将在指数退避计时器上发送 SYN+ACK,在客户端回复 ACK 后,TCP Stack检查接受队列是否仍满,如果未满,则将套接字移至接受队列如果队列已满,则将套接字保留在半开队列中,下次客户端回复ACK时,该套接字将有另一次机会移至接受队列。 这两个计数器在 node_expoter 中的指标是: node_netstat_TcpExt_ListenDrops node_netstat_TcpExt_ListenOverflows TcpInSegs 和 TcpOutSegs TcpInSegs 和 TcpOutSegs 都是被定义在 RFC1213 [1] TcpInSegs 是指 TCP layer 接收到的数据包数量,包括错误接收的数据包,例如校验和错误、无效的TCP头等。只有一个错误不会被包含在内:如果第 2 层目标地址不是 NIC 的第 2 层地址。如果数据包是多播或广播数据包,或者 NIC 处于混杂模式,则可能会发生这种情况。在这些情况下,数据包将被传递到 TCP 层,但 TCP 层将在增加 TcpInSegs 之前丢弃这些数据包。 TcpInSegs 计数器不知道 GRO (Generic Receive Offload)。因此,如果两个数据包被 GRO 合并,TcpInSegs 计数器只会增加 1。...

 ·  · 

Linux网络栈

Linux 架构概述 [1] 本章节简单阐述Linux系统的结构,并讨论子系统中的模块之间以及与其他子系统之间的关系。 Linux内核本身鼓励无用,是作为一个操作系统的一部分参与的,只有为一个整体时他才是一个有用的实体,下图展示了Linux操作系统的分层 图:Linux子系统分层图 Source:https://docs.huihoo.com/linux/kernel/a1/index.html 由图可以看出Linux操作系统由四部分组成: 用户应用 OS服务,操作系统的一部分(例如shell)内核编程接口等 内核 硬件控制器,CPU、内存硬件、硬盘和NIC等都数据这部分 Linux内核阐述 Linux内核将所有硬件抽象为一致的接口,为用户进程提供了一个虚拟接口,使用户无需知道计算机上安装了哪些物理硬件即可编写进程,并且Linux支持用户进程的多任务处理,每个进程都可以视作为操作系统的唯一进程独享硬件资源。内核负责维护多个用户进程,并协调其对硬件资源的访问,使得每个进程都可以公平的访问资源,并保证进程间安全。 Linux内核主要为五个子系统组成: 进程调度器(SCHED), 控制进程对 CPU 的访问。调度程序执行策略,确保进程可以公平地访问 CPU。 内存管理器 (MM), 允许多个进程安全地共享操作系统的内存 虚拟文件系统 (VFS),向所有设备提供通用文件接口来抽象出各种硬件设备 网络接口 (NET),提供对多种网络标准与各种网络硬件的访问 进程间通信 (IPC),在单个操作系统上的多种机制进程间通信机制 网络子系统架构 [2] 网络子系统功能主要是允许 Linux 系统通过网络连接到其他系统。支持多种硬件设备,以及可以使用的多种网络协议。网络子系统抽象了这两个实现细节,以便用户进程和其他内核子系统可以访问网络,而不必知道使用什么物理设备或协议。 子系统模块包含 网络设备驱动层 (Network device drivers),网络设备驱动程序与硬件设备通信。每个硬件设备都有对应的设备驱动程序模块。 独立设备接口层(device independent interface),设备独立接口提供了所有硬件设备的统一视图,因此在网络子系统之上的级别无需了解硬件信息 网络协议层 (network protocol),网络协议实现了网络传输的协议 协议独立/无关接口层 (protocol independent interface),提供了独立于硬件设备的网络接口,为内核内其他子系统访问网络时不依赖特定的协议和硬件接口。 系统调用层 (system call) 用于限制用户进程导出资源的访问 网络子系统的结构图如下图所示, 图:网络子系统中的上下文 Source:https://docs.huihoo.com/linux/kernel/a1/index.html 当网络子系统转换为网络栈时,如下图所示 图:ISO Stack与TCP/IP Stack Source:https://www.washington.edu/R870/Networking.html 当然Linux网络子系统是类似于TCP/IP栈的一种结构,当发生一个网络传输时,数据包会按照所经过的层进行封装。例如应用层应用提供了REST API,那么应用将要传输的数据封装为HTTP协议,然后传递给向下的传输层。传输层是TCP协议就会被添加对应的TCP包头。整个封装过程原始包保持不变,会根据所经过层的不同增加固定格式的包头。 图:数据包传输在每层被封装的过程 Source:http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-13-SECT-1.html 对于Linux来说TCP/IP 的五层结构则是构成网络子系统的的核心组件,下图是Linux网络栈结构图 图:Linux网络栈的结构图 Source:https://medium.com/geekculture/linux-networking-deep-dive-731848d791c0 图中橙色部分是位于TCP/IP的五层结构中的应用层,应用层向下通讯通过 system call 与 socket接口进行交互 蓝色部分是位于内核空间,socket向下则是传输层与网络层 最底层是物理层包含网卡驱动与NIC 通过图可以看出,NIC是发送与接收数据包的基本单位,当系统启动时内核通过驱动程序向操作系统注册网卡,当数据包到达网卡时,被放入队列中。内核通过硬中断,运行中断处理程序,为网络帧分配内核数据结构(sk_buff),并将其拷贝到缓冲区中,此为内核与网卡交互的过程。...

 ·  · 

为什么网络是分层的

Overview [1] 协议数据单元 Protocol Data Unit (PDU) 是应用于OSI模型中的数据结构,在OSI模型中每一层都会被添加一个header,tailer进行封装,header, tailer加原始报文的组合就是PDU。 在每层中,PDU的名称都是不同的,这也是很多人的疑问,一会数据报文称为数据包,一会数据报文成为数据帧,该文介绍网络中的单元,以了解之间的区别 物理层 物理层数据的呈现方式是以 “位” (bit) 为单位的,即0 1,在该层中数据以二进制形式进行传输 数据链路层 [2] 到达数据链路层,实际上可以说进入了TCP/IP栈对底层,而该层的单位为 ”帧“ (frame),该层中,MAC地址会被封装到数据包中,比如以太网帧,PPP帧都是指该层的数据包 该层中数据帧包含: 源MAC 目的MAC 数据,由网络层给出的 数据的总长度 校验序列 网络层 [3] 在网络层中协议数据单元被称为数据 “包" (package) ,是网络间节点通讯的基本单位。该层中IP地址会被封装到数据包内。 该层中数据包包含: 标头:源IP,目的IP,协议,数据包编号,帮助数据包匹配网络的位 payload:数据包的主体 标尾:包含几个位,用于告知已到达数据包的末尾与错误检查(循环冗余检查 (CRC)) 图:数据包组成 Source:https://computer.howstuffworks.com/question525.htm 例如一个电子邮件,假设电子邮件大小尾3500bit,发送时使用1024的固定大小数据包进行发送,那么每个数据包标头为 96bits,标尾为 32bit,剩余 896bits 将用于实际的数据大小。这里为3500bits,会被分为4个数据包,前三个数据包为 896bits,最后一个数据包大小为 812bits。接收端会根据包编号进行解包重组 传输层 Segment 在传输层TCP协议的协议数据单元被称为 ”段“ (Segment) ,上面讲到,IP数据包会以固定大小的数据包进行发送,如果超出大小的会被划分为多个数据包,每个数据包的碎片就被称之为Segment。 数据包分割通常会发生在该层,当发生下列场景时会需要分段 数据包大于网络支持的最大传输单元 (MTU) 网络不可靠,将数据包分为更小的包 datagram [4] 在传输层UDP协议的协议数据单元被称为 ”数据报“ (datagram) ,datagram是一种逐层增加的设计,用于无连接通讯 下图是一个UDP数据报被封装位一个IP数据包:IPv4字段值位17 表示udp协议 图:udp的IP包 Source:https://notes.shichao.io/tcpv1/ch10 对于udp数据报的组成包含header与payload,udp的header大小为固定的8字节 源端口:可选 目的端口:识别接收信息的进程 Length:udp header + udp payload的长度,最小值为8 checksum:与lenght一样其实是多余的,因为第三层包含了这两个信息 图:udp数据报组成 Source:https://notes....

 ·  · 

OSI模型与IP协议

OSI Model OSI 七层网络模型如下(由下到上): 应用层 Application layer :直接接触用户数据的层。软件应用程序依靠应用层发起通信。这里的应用值得是协议而不是客户端软件;应用层协议包括 HTTP, SMTP, FTP, DNS,Telnet, etc.. 表示层 Presentation layer:表示层充当角色为网络数据转换器,负责完成数据转换,加密和压缩 会话层 Session layer:负责建立、管理和终止两个设备之间的通信 传输层 Transport layer:负责两个设备间的端到端通信。包括从会话层提取数据,将数据分解为多个区块(称为数据段);传输层协议包括,TCP, UDP 网络层 Network layer:负责管理网络地址,定位设备,决定路由,通俗来讲是负责*“不同”*网络之间的传输,也就是路由功能;网络层协议包括 IP,ARP,ICMP;代表设备 3 layer swtich, router, firewall。相应就代表对应网络协议也是三层的,如RIP, OSPF, BGP 数据链路层 Data link layer:数据链路层负责*“同一”*网络上设备之间的数据传输;该层协议包括 Ethernet, PPP(Point-to-Point Protocol);代表设备 Switch,Bridges,同样的MAC地址也是该层的 物理层 Physical layer:该层表示参与数据传输的物理设备,如网线,同时还负责将数据转换为位流,也就是由 1 和 0 构成的字符串。 图:OSI七层模型 Source:https://www.cloudflare.com/zh-cn/learning/ddos/glossary/open-systems-interconnection-model-osi/ MAC MAC地址介绍 MAC (Media Access Control) 地址用来定义网络设备的位置,由48比特长,12位的16进制组成,其中从左到右,0-23bit为厂商想IETF等机构申请用来标识厂商的代码OUI Organizationally-Unique Identifier,24-47bit由厂商自行分配,是厂商制造所有网卡的唯一编号。如00-50-56-C0-00-08 MAC地址类型 MAC地址分为三种类型: 物理MAC地址:Mac地址唯一的标识了以太网的一个终端,该地址为全球唯一的硬件地址。 广播(broadcast) MAC地址:每个比特都是 1 的 MAC 地址。广播 MAC 地址是组播 MAC 地址的一个特例。11111111-11111111-11111111-11111111-11111111-11111111 16进制表示为 FF-FF-FF-FF-FF-FF。 组播(multicast) MAC地址:第一个字节的最低位是 1 的 MAC 地址。二进制表示为 xxxxxxx1-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx ;16进制表示为01-00-00-00-00-00。如 a5-a9-a6-aa-5a-a6 这个mac地址的第一个字节的最低位 16进制a5 转换为二进制为10100101 最后一位为1就是组播MAC地址。 单播 (unicast) MAC 地址:第一个字节的最低位是 0 的 MAC 地址 xxxxxxx0-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx。 静态MAC地址 由用户通过命令配置的静态转发的MAC地址,静态MAC地址和动态MAC地址的功能不同,静态地址一旦被加入,该地址在删除之前将一直有效,不受最大老化时间的限制...

 ·  · 

H3C Cloud与WSL2共存

背景 由于Windows10 开启WSL2后无法和 eNSP 做到兼容,但是 H3C HCL 在版本 HCL_v2.1.2.1 提供了 VirtualBox 6.0.14 作为虚拟化后端,理论上来说可以做到 WSL2 与 HCL 共存。 并且开启了WSL2后并于其他虚拟化平台(VirtualBox, Vmvare)做到兼容的情况下,这种情况大部分禁止套娃(虚拟化下在虚拟化),通过安装虚拟机的方式再安装 eNSP 发现启动不报错,但是很长时间起不来。 Notes [1]:HCL官方给的建议是,对于windows7装的版本为HCL_v2.1.1;对于Windows10 并且开启了 Hype-v 或者 Dokcer-Desktop,推荐使用 HCL_v3.0.1.1 下载地址:HCL Download 安装过程 下载好安装时,直接下一步直至完成即可,VirtualBox已被内嵌至安装包内了。 图:HCL安装界面 Notes:如果需要抓包,自行安装Wireshark,安装好后,在HCL设置中配置 wireshark.exe 的路径即可 VirtualBox启用hyper-v支持 [2] 进入VirtualBox安装目录, 确定当前目录下存在VBoxManage.exe文件, 在当前目录打开powershell. 或者你将VBoxManage.exe所在目录加入环境变量, 任意路径下打开powershell. powershell 1 2 # 或指定vbox所有虚拟系统开启 ./VBoxManage.exe setextradata global "VBoxInternal/NEM/UseRing0Runloop" 0 开启后,HCL所有的设备就工作正常了,这种情况下也不用牺牲WSL2或者Dokcer-Desktop。因为eNSP官方没有再更新,导致hype-v与VirtualBox无法兼容,暂时无解。 Reference [1] H3C Cloud Lab [2] Windows 10 (2004) 启用wsl2, 并与VirtualBox 6.0+共存

 ·  ·