type
status
date
slug
summary
tags
category
icon
password
1. 前言:创造操作系统与“制定规则”
创造操作系统,就是去创造一个所有应用程序赖以运行的基础环境。从根本上来说,就是在制定规则:什么可以接受,什么可以做,什么不可以做。事实上,所有的程序都是在制定规则,只不过操作系统是在制定最根本的规则。—— 摘自《Linus Torvalds 自传》
从上述引言中可以看出,操作系统在整个软件世界中扮演着“基石”的角色。以 Linux 为例,它为应用程序提供了最底层的规则体系,从 CPU 调度、内存管理到网络协议栈都属于操作系统层面所制定和执行的“规则”。本文我们主要讨论linux内核网络技术
2. OSI 网络七层模型
OSI 模型将网络通信分成了七层,每层负责特定的网络功能。各层之间相互独立、层层相依,让网络通信更易于理解和实现。
层级 | 名称 | 含义 |
7 | 应用层(Application) | 与用户应用直接交互,例如电子邮件、文件传输、网页浏览等。常见协议:HTTP、FTP、SMTP 等。 |
6 | 表示层(Presentation) | 数据格式化和转换(加密、解密、压缩等),确保发送方和接收方理解彼此的数据格式。 |
5 | 会话层(Session) | 管理应用程序之间的会话或连接,负责建立、维护和终止通信会话,提供会话恢复功能。 |
4 | 传输层(Transport) | 端到端的数据传输管理,如数据分段、重组、流量控制和错误校正。常见协议:TCP、UDP。 |
3 | 网络层(Network) | 数据包在不同网络之间的路由和转发,使用 IP 地址确定传输路径。 |
2 | 数据链路层(Data Link) | 节点之间的数据传输,提供错误检测和纠正,使用 MAC 地址标识设备。 |
1 | 物理层(Physical) | 物理硬件传输层(电缆、光纤、集线器等),处理 bit 在物理介质上的传输及信号特性。 |
术语补充
- 帧(Frame):数据链路层的数据单元
- 数据包(Packet):网络层的数据单元
- 数据段(Segment):传输层的数据单元
- 数据(Data):应用层数据单元
在实际描述时,通常不严格区分上述术语,往往会将它们统称为“数据包”以简化表达。
3. Linux 系统收包流程
当网络数据包从外部到达 Linux 系统时,会经历网卡接收、硬件中断、软中断、协议栈分层处理以及最终送达应用程序的流程。其核心步骤如下图所示:
下图:Linux 系统收包流程
- 网卡接收数据包
网卡(如 eth0)从外部网络接收数据包后,利用DMA(Direct Memory Access直接内存访问) 技术将数据包写入内核的 RingBuffer,避免CPU频繁参与。RingBuffer 是一种首尾相接的环形数据结构,它的主要作用是作为缓冲区,缓解网卡接收数据的速度快于 CPU 处理数据的速度问题。
- 硬件中断通知
数据包进入 RingBuffer 后,网卡触发 IRQ(中断请求) 通知内核有新数据。
- 软中断处理(SoftIRQ)
内核唤醒 ksoftirqd 线程,从 RingBuffer 中读取数据。调用 NAPI(New API) 接口,将数据包转换成 skb(Socket Buffer) 结构便于后续处理。
- 协议栈分层处理
- 网络层(L3):根据路由表决定数据去向(本机或转发)。
- 传输层(L4):可能会进行 NAT 转换或连接跟踪等操作。
- 应用层获取数据
最终,内核将数据放入应用程序相应的 Socket 缓冲区。应用程序通过 Socket API 调用即可获取数据。
下面是相应的 Mermaid 流程图,展示了收包的关键节点:
关键技术要点:
- DMA:网卡绕过 CPU,直接访问内存。
- RingBuffer:缓冲数据,平衡网卡与 CPU 的处理速度差异。
- IRQ/SoftIRQ:降低 CPU 的实时中断负担。
- NAPI:内核统一网络接口。
- skb:协议栈中的核心数据结构,用于存储数据包各层的头部和内容。
问题点:
- 多层解包/封包。
- 频繁的内核态-用户态切换。
- CPU 被中断机制和协议栈处理占用较多时间。
4. Netfilter 的 5 个钩子
Netfilter 是 Linux 内核中的网络数据包处理框架,提供了 5 个钩子函数(Hook),分别对应数据包在协议栈中的不同处理阶段:
钩子名称 | 触发时机 | 作用 | 所在网络协议栈层面 | 典型用途 |
PREROUTING | 数据包刚进入协议栈时 | 路由前修改数据包目标地址(DNAT) | 网络层(L3)路由之前 | 修改目标 IP 地址 |
FORWARD | 数据包需要转发且目标不是本机 | 处理转发数据包(如路由、防火墙过滤) | 网络层(L3)路由之后 | 管理和保护转发的数据包 |
INPUT | 数据包目标是本机 | 处理本地数据包,允许或拒绝访问,保护本机安全 | 网络层(L3)路由之后 | 数据过滤、传递给本地进程 |
OUTPUT | 本机生成的数据包 | 在路由前对本机生成数据包进行加工或过滤(限制访问目标) | 网络层(L3)路由之前 | 丢弃、过滤或修改本地主机流量 |
POSTROUTING | 数据包即将离开协议栈(转发/本地主机) | 路由后对数据包进行源地址转换(SNAT) | 网络层(L3)路由之后(出口) | 修改源 IP 地址(NAT 需求) |
下面这张示意图展示了这 5 个钩子在协议栈中的位置:
Netfilter 钩子的 Mermaid 图
更直观的解释与增强理解
- PREROUTING:位于 网络层入站之前,修改目标 IP(DNAT)。
- FORWARD:位于 网络层中转的路由后,处理非本机流量。
- INPUT:位于 本机接收数据包的路由后,确保数据到本地应用。
- OUTPUT:位于 本地主机生成数据的路由前,用于过滤/修改出口数据。
- POSTROUTING:位于 所有出栈数据的路由后,执行源地址转换(SNAT)。
在 Kubernetes、eBPF 等系统中也采用类似“钩子”模式,通过暴露接口让用户插入自定义代码或逻辑来扩展功能。
5. iptables:数据包过滤工具
iptables 是基于 Netfilter 的命令行工具,用于管理网络流量和配置防火墙、NAT 等功能。它以更友好的方式抽象了 Netfilter 的钩子。
5.1 iptables 的表与链
- 链(Chain)
- ACCEPT:允许数据包通过,继续执行后续规则。
- DROP:丢弃数据包。
- RETURN:退出当前链,返回上一链的规则。
- DNAT:修改目标地址,实现目标网络地址转换。
- SNAT:修改源地址,实现源网络地址转换。
- REDIRECT:端口映射,将数据包重定向到本机其他端口。
- REJECT:丢弃数据包,并向发送端返回错误信息。
- MASQUERADE:动态 SNAT,常用于动态 IP 地址的 NAT。
- LOG:记录数据包的日志信息。
对应 Netfilter 的 5 个钩子:
PREROUTING
、INPUT
、FORWARD
、OUTPUT
、POSTROUTING
。常见动作
- 表(Table)
iptables 中有五张规则表,用于分类管理不同类型的处理规则:
表名 | 功能 |
raw | 禁用连接追踪,加速数据包处理。 |
mangle | 修改数据包内容(如 ToS、TTL),进行报文头处理。 |
nat | 网络地址转换(SNAT/DNAT),修改源或目标 IP 地址。 |
filter | 数据包过滤,决定放行(ACCEPT)、拒绝(REJECT)或丢弃(DROP)。 |
security | 应用安全策略(SELinux),一般不常用。 |
5.2 数据包流动过程(结合表与链)
数据包通过 Netfilter 时,会按一定顺序经过各表和链:
- raw 表:标记连接追踪(也可禁用)。
- mangle 表:修改数据包报文头。
- nat 表:NAT 转换(SNAT/DNAT)。
- filter 表:放行、拒绝或丢弃数据包。
- security 表:应用安全策略。
5.3 iptables 使用示例
放行 TCP 22 端口的流量:
A INPUT
:在INPUT
链追加规则
p tcp
:匹配 TCP 协议
-dport 22
:匹配目标端口 22
j ACCEPT
:允许数据包通过
数据包流动顺序:raw -> mangle -> nat -> filter -> security,不同链上的规则按顺序处理数据包。iptables 将链与规则表解耦,便于管理复杂的规则集,同时支持多种动作,覆盖从防火墙到 NAT 的广泛功能。
6. iptables 自定义链:以 Kubernetes 为例
当规则日益复杂时,可以通过“自定义链”来分模块管理。Kubernetes 在 iptables 模式下大量使用自定义链来实现 Service VIP 转发和负载均衡。数据包从 Service VIP 流量开始,通过自定义链多次跳转,最终根据负载均衡策略转发到具体 Pod 的 IP 和端口。
- 自定义链特点
- 扩展内置链:通过跳转指令,将数据包从内置链转发到自定义链进行处理。
- 动态跳转:比如 Kubernetes 会创建
KUBE-SERVICES
、KUBE-SVC-*
、KUBE-SEP-*
等链进行流量分发。 - 灵活设计:便于维护与扩展。
- Kubernetes Service 流量管控示例
- Service VIP 引流:当目标地址为 Service VIP 时,iptables 规则跳转到对应的
KUBE-SVC-*
链。 - 负载均衡:
KUBE-SVC-*
链使用随机算法将数据包分发到不同的KUBE-SEP-*
链。 - 后端 DNAT:
KUBE-SEP-*
通过 DNAT,将流量指向真正的 Pod IP:Port。
- 性能限制
- 规则数量暴增时,iptables 性能显著下降。
- IPVS 模式 或 Cilium 可替代 iptables 模式,提升大规模集群性能。
kube-proxy 与 iptables 总结:
- 灵活性:iptables 自定义链简单易用、配置直观。
- 性能瓶颈:大型集群可能遭遇性能下降,可考虑 IPVS 模式 或 eBPF 方案。
下图:数据包通过 Netfilter 时的流动过程
7. 连接跟踪模块 conntrack
conntrack 是内核模块,用于跟踪网络连接状态(如 TCP 的 NEW、ESTABLISHED 等)。结合 NAT 可以保证请求和响应正确地映射回去。
- 核心功能:跟踪连接、支持 NAT。
- 在 Kubernetes 中:DNAT 映射到 Pod IP 后,返回流量需要 SNAT 回 Service VIP,conntrack 记录这些映射关系。
- 问题:同机内通信可能绕过网络层导致 conntrack 记录不完整,需
bridge-nf-call-iptables=1
保证所有流量都走 iptables。
8. 内核旁路技术:DPDK、XDP、eBPF、RDMA
网络密集型应用中,Linux 内核频繁在内核态与用户态之间切换,加之复杂的网络协议栈处理,往往成为性能瓶颈。为提升性能,内核旁路(Kernel Bypass)技术应运而生,通过绕过内核直接处理网络数据包,从而减少开销。主要代表技术包括:
- DPDK(Data Plane Development Kit):完全绕过内核,直接在用户空间处理数据包。
- XDP(eXpress Data Path):在内核驱动层快速处理数据包,结合 eBPF 提高性能。
- RDMA(Remote Direct Memory Access):主机间直接内存访问,极大减少 CPU 干预,提升高性能计算与 AI 训练效率。
8.1 eBPF 与 XDP
- eBPF(Extended Berkeley Packet Filter)
简介:eBPF 是一种强大的内核扩展机制,允许在内核空间运行经过安全验证的用户定义代码,几乎可以访问所有内核资源。
发展:从传统 BPF 发展而来,eBPF 扩展了功能,支持更多用途,如网络、性能监控和安全。有严格验证器保证安全。
- XDP(快速数据路径)
- 高性能:类似 DPDK 的处理速度。
- 内核集成:无需第三方库或专用 CPU。
- 灵活性:通过 eBPF 程序定义处理逻辑
- 编写与编译:
- 编写:开发者使用 C 等高级语言编写 eBPF 程序,定义具体的网络数据包处理逻辑。
- 编译:使用专用编译器(如 Clang)将 C 代码编译为 eBPF 字节码。
- 加载与验证:
- 加载:通过高级语言库(如 Golang、Python)或工具(如
ip
命令、bpftool
)将编译后的 eBPF 字节码加载到内核。 - 验证(Verification):
- 内核中的 eBPF 验证器对程序进行静态检查,确保其安全性和正确性。
- 验证内容包括:无死循环、无越界内存访问、有限的栈空间使用等。
- 只有通过验证的 eBPF 程序才能被加载,避免对系统稳定性和安全性的潜在威胁。
- 挂载与执行:
- 挂载:将验证通过的 eBPF 程序挂载到特定的钩子点(如 XDP、TC、Tracepoints)。
- 执行:
- 当数据包或事件触发相应的钩子时,内核会执行挂载在该钩子的 eBPF 程序。
- eBPF 程序在内核态执行,处理数据包并根据逻辑返回相应的动作(如
XDP_DROP
、XDP_PASS
)。 - 管理与卸载:
- 管理:通过工具和命令监控 eBPF 程序的运行状态、性能指标。
- 卸载:在不需要时,可以安全地从钩子点卸载 eBPF 程序,释放资源。
位于网卡驱动层,在数据包进入协议栈前处理。
优势:
eBPF 程序的加载、验证与执行
为了安全高效地在内核中运行用户定义的 eBPF 程序,Linux 内核执行了一系列严格的步骤:
eBPF 程序加载流程:编写/编译 -> 加载 -> 验证 -> 挂载 -> 执行/卸载
XDP 支持的五种返回动作
返回码 | 描述 |
XDP_ABORTED | 处理时发生错误或异常。 |
XDP_DROP | 直接在网卡驱动层丢弃数据包,常用于过滤无效或恶意数据包(如 DDoS 防护)。 |
XDP_PASS | 允许数据包继续进入内核的网络协议栈,结合传统处理方式。 |
XDP_TX | 重新发送数据包到入站网络接口,适用于快速转发和修改数据包。 |
XDP_REDIRECT | 将数据包重定向到其他网卡或 CPU,结合 AF_XDP 可将数据包直接送往用户空间。 |
eBPF 钩子类型及其用途
钩子名称 | 描述 |
TC(Traffic Control) | 位于网络流量控制层,处理流经内核的网络数据包,可在数据包进入或离开网络栈的各个阶段触发。 |
XDP | 位于网卡驱动层,处理收到的网络数据包,用于高性能操作如 DDoS 防护和负载均衡。 |
Tracepoints | 内核代码中的静态探测点,用于性能分析、故障排查和监控,分布在调度器、文件系统等子系统中。 |
LSM(Linux Security Modules) | 安全模块框架中的钩子,触发 eBPF 程序以实施安全策略和访问控制,如文件和网络访问。 |
8.2 Cilium:基于 eBPF 的容器网络
Cilium 利用 eBPF/XDP 构建容器网络,替代传统 Netfilter:
高级功能:
- L3/L4 负载均衡:高效处理网络流量分发。
- 网络策略:精细控制容器间的网络访问。
- 观测与安全认证:实时监控与安全事件检测。
连接跟踪与 NAT 都在 eBPF 层实现,告别繁琐的 iptables 规则。
专用查询命令:使用 Cilium 提供的命令如
cilium bpf nat list
和 cilium bpf ct list global
查看 NAT 规则和连接记录。适合大规模 Kubernetes 集群,性能更好、可扩展性更高。
8.3 RDMA:远程直接内存访问
近年来,随着人工智能、分布式训练和分布式数据存储的快速发展,对网络传输性能提出了更高的要求。传统以太网在网络延迟、吞吐量和 CPU 资源消耗方面存在先天不足。在此背景下,广泛应用于高性能计算(HPC)领域的 RDMA(Remote Direct Memory Access,远程直接内存访问)技术,因其卓越的性能,逐渐成为满足上述需求的首选解决方案。
RDMA 的设计灵感来源于 DMA(Direct Memory Access,直接内存访问),是一种允许主机之间直接访问彼此内存的技术。其主要特点包括:
- 低延迟与高吞吐:RDMA 能够实现极低的网络延迟(小于 3 μs)和高吞吐量(超过 400Gb/s)。RDMA 在高性能计算(HPC)、分布式训练中大放异彩。
- CPU 资源消耗低:由于数据传输过程中无需频繁的 CPU 介入,RDMA 极大地减少了 CPU 负载,提高了整体系统性能。
- 绕过传统协议栈:应用程序通过专用接口(RDMA Verbs API)绕过主机操作系统和 TCP/IP 协议栈,直接进行内存间数据交换。
RDMA 网络的协议实现主要分为三类:Infiniband、RoCE 和 iWARP,它们各具特点:
- Infiniband(无限带宽)
- 特点:专为 RDMA 设计,性能极高(延迟 < 3 μs,吞吐量 > 400Gb/s)。
- 应用:广泛用于高性能计算(HPC)(如人工智能训练 ChatGPT 背后的分布式机器学习系统)。
- 局限:需要专用硬件(网卡、交换机、网线),成本高,且无法兼容现有以太网。
- iWARP(Internet Wide Area RDMA Protocol)
- 简介:将 RDMA 封装在 TCP/IP 协议内。
- 性能:由于依赖 TCP/IP 的可靠性机制(如三次握手、拥塞控制),在 RDMA 性能上受限,失去了大部分优势。因先天设计缺陷,逐渐被业界抛弃。
- RoCE(RDMA over Converged Ethernet)
- 特点:基于以太网实现 RDMA,分为两种版本::
- RoCEv1:基于二层以太网,局限于同一子网,无法跨子网通信。
- RoCEv2:基于三层 IP 网络,支持跨子网通信。
- 优势:
- 降低了 RDMA 技术的使用成本。
- 兼容现有以太网基础设施(支持 RoCE 的专用网卡和标准以太网交换机)。
- RoCEv2 解决了 RoCEv1 的跨子网通信限制,广泛应用于分布式存储、并行计算等通用数据中心场景,成为分布式存储和并行计算的主流选择。
- 应用:云计算平台 Azure 公开信息显示,至 2023 年,Azure 数据中心 70% 的流量已为 RDMA 流量。
RDMA 网络的可靠性保障
RDMA 网络对丢包极为敏感,任何数据包的丢失都可能导致大量重传,降低传输性能。为了确保网络的可靠性,采取了以下措施:
- Infiniband:依赖专用硬件确保网络可靠性。
- RoCE:通过无损以太网技术避免丢包,常用的可靠性算法包括:
- DCQCN(数据中心量化拥塞通知):由微软和 Mellanox 提出。
- HPCC(高性能拥塞控制):由阿里巴巴提出。
这些算法优化了以太网流量控制,使 RoCE 网络在高负载下仍能保持低延迟和高吞吐。
简而言之:eBPF、XDP、RDMA 等技术在不完全依赖传统协议栈的前提下,实现了高性能、低延迟的网络数据处理模式,广泛应用于云原生、AI 训练和大规模集群环境。RoCEv2 由于其低成本和高兼容性,已成为通用数据中心的主流 RDMA 实现方案。
9. Linux 网络虚拟化:网络命名空间与虚拟设备
在现代容器化与云环境中,同一台物理机常同时运行多个隔离环境。Linux 提供了 网络命名空间 来实现网络隔离,每个命名空间拥有自己独立的网络栈、接口和路由表。
核心技术:
- Veth 对(Veth Pair):两端分别连接不同的网络命名空间,相当于一根“虚拟网线”。
- Linux Bridge:类似虚拟交换机,用来连接多个 Veth 接口实现二层互通。
- TUN/TAP:分别在三层和二层处理数据包,多用于 VPN 或虚拟机桥接。
网络命名空间:
TUN/TAP 设备示意:
9.1 软件定义网络(SDN)与 Overlay
在云原生环境下,容器的动态部署、扩展和跨数据中心迁移需要灵活且可编程的网络配置。而传统基于物理设备的网络拓扑难以满足这种高频率的调整需求。
核心理念:
- 软件定义网络(SDN):通过将网络的控制平面与数据平面分离,利用软件进行网络配置和管理,实现高度可编程和灵活的网络架构。
SDN 思想的核心是,在现有的物理网络之上新增一层虚拟网络,将控制平面(操作系统和各类网络控制软件等)和数据平面(底层通信的物理设备,以及各类通信协议等)解耦,将网络服务从底层硬件设备中抽象出来,由代码直接编程控制。
模型:
- Overlay 网络:如 VXLAN/Geneve,通过三层网络在底层封装二层帧,支持大规模多租户。
- Underlay 网络:物理网络部分。
优点:灵活、可扩展,适合跨主机或跨数据中心场景。
10. VLAN 与 VXLAN 简明总结
最后,对常见的二层虚拟化方式做一简要对比:
10.1 虚拟局域网(VLAN)
VLAN(Virtual Local Area Network):通过逻辑分割,将一个物理网络划分为多个独立的广播域,减少广播流量,提升网络管理效率。
- 基于二层,最多支持 4096 个 VLAN。
- 通过在以太帧中添加 VLAN Tag 来区分不同广播域。
- Router-on-a-Stick:用单臂路由实现不同 VLAN 间的通信。
- 扩展性有限,跨数据中心部署复杂。
10.2 虚拟可扩展局域网(VXLAN)
VXLAN(Virtual eXtensible Local Area Network):一种隧道封装技术,通过在三层网络上封装二层以太网帧,实现大规模、多租户的虚拟网络。
- 大规模 Overlay 隧道技术,在 UDP 中封装二层帧。
- 24 位 VNI,可支持 1677 万网络隔离。
- 跨三层网络,更易在多数据中心环境中部署。
- VTEP(VXLAN Tunnel Endpoint)执行封装解封。
通信流程:
- 封装:源宿主机的VTEP将以太网帧封装为VXLAN报文。
- 传输:通过物理网络传输至目标宿主机。
- 解封:目标宿主机的VTEP解封VXLAN报文,获取原始数据帧并转发至目标容器或虚拟机。
对比:
- VLAN:在同一物理道路上设置多个车道,每个车道限制特定车辆通行。
- VXLAN:在公路网络上架设高速公路(隧道),允许更多种类和数量的车辆独立通行。
特性 | VLAN | VXLAN |
扩展性 | 4096 个 VLAN | 1677 万+ 虚拟网络(VNI) |
协议层级 | 二层 | 三层之上封装二层 |
跨数据中心 | 较困难 | 较容易,直接通过三层网络 |
适用场景 | 较小规模、单数据中心 | 大规模、多租户、容器化数据中心 |
11. 总结
- 从操作系统与网络协议栈谈起
Linux 操作系统从内核底层“制定规则”,为网络通信提供了强大的基础设施。
- 分层模型与 Netfilter/iptables
OSI 七层模型帮助理解网络分层;Netfilter 的钩子机制与 iptables 的规则表与链提供灵活的数据包处理能力。
- 内核性能优化:kernel bypass 与 eBPF
传统内核协议栈可能成为瓶颈,高性能场景可采用 DPDK、XDP、RDMA 等技术;eBPF 在内核态灵活扩展网络逻辑。
- 虚拟化与现代云原生
网络命名空间与虚拟网络设备(Veth、Bridge、TUN/TAP)为容器网络奠定了基础;Kubernetes 通过 iptables 或 eBPF(Cilium)管理流量。
- VLAN 与 VXLAN
VLAN 适合中小规模网络;VXLAN 则满足超大规模、多租户、跨数据中心需求。
一句话总结:整个 Linux 网络世界就像一座充满规则的“城市”:操作系统是城市的法律,Netfilter/iptables 是警察与交通管制,eBPF/XDP 则是高速专用快车道,VLAN/VXLAN 则是城市内部和城际间的虚拟“道路扩展”方案。它们共同构筑了现代云原生和大规模网络的坚实根基。祝你在学习和实践中掌握并灵活运用这些“规则”与“道路”!
本文主要受益于isno分享,使我收益颇丰,感谢大佬分享。