前置知识——Linux网络虚拟化

Linux网络虚拟化

信息是如何通过网络传输被另一个程序接收到的?
我们讨论的虚拟化网络是狭义的,它指容器间网络。

好了,下面我们就从 Linux 下网络通信的协议栈模型,以及程序如何干涉在协议栈中流动的信息来开始了解吧。

Linux 系统下的网络通信模型

如果抛开虚拟化,只谈网络的话,那我认为首先应该了解的知识,就是 Linux 系统的网络通信模型,即信息是如何从程序中发出,通过网络传输,再被另一个程序接收到的。

从整体上看,Linux 系统的通信过程无论是按理论上的 OSI 七层模型,还是以实际上的 TCP/IP 四层模型,都明显地呈现出“逐层调用,逐层封装”的特(当前层级仅依赖上一层级)点,这种逐层处理的方式与栈结构,比如程序执行时的方法栈很类似,所以它通常被称为“Linux 网络协议栈”,简称“网络栈”,有时也称“协议栈”。

11

在图中传输模型的左侧,我特别标示出了网络栈在用户与内核空间的部分,也就是说几乎整个网络栈(应用层以下)都位于系统内核空间之中,而 Linux 系统之所以采用这种设计,主要是从数据安全隔离的角度出发来考虑的。

由内核去处理网络报文的收发,无疑会有更高的执行开销,比如数据在内核态和用户态之间来回拷贝的额外成本,所以就会损失一些性能,但是这样能够保证应用程序无法窃听到或者去伪造另一个应用程序的通信内容。当然,针对特别关注收发性能的应用场景,也有直接在用户空间中实现全套协议栈的旁路方案,比如开源的Netmap以及 Intel 的DPDK,都能做到零拷贝收发网络数据包。

另外,图中传输模型的箭头展示的是数据流动的方向,它体现了信息从程序中发出以后,到被另一个程序接收到之前经历的几个阶段,下面我来给你一一分析下。

网络工程的基础内容,数据经过包一次一次封装,添加协议头和内容最终完成传输通信。

而接受数据则是层层解包,提取协议体,传给上一层

  • Socket

应用层的程序是通过 Socket 编程接口,来和内核空间的网络协议栈通信的。Socket已经成为了各大主流操作系统共同支持的通用网络编程接口,是网络应用程序实际上的交互基础。

在这里,应用程序通过读写收、发缓冲区(Receive/Send Buffer)来与 Socket 进行交互,在 Unix 和 Linux 系统中,出于“一切皆是文件”的设计哲学,对 Socket 的操作被实现为了对文件系统(socketfs)的读写访问操作,通过文件描述符(File Descriptor)来进行。

  • TCP/UDP

这里我以 TCP 协议为例,内核发现 Socket 的发送缓冲区中,有新的数据被拷贝进来后,会把数据封装为 TCP Segment 报文,常见的网络协议的报文基本上都是由报文头(Header)和报文体(Body,也叫荷载“Payload”)两部分组成。

  • IP

以 IP 协议为例,它会把来自上一层(即前面例子中的 TCP 报文)的数据包作为报文体,然后再次加入到自己的报文头中,比如指明数据应该发到哪里的路由地址、数据包的长度、协议的版本号,等等,这样封装成 IP 数据包后再发往下一层。

  • Device

Device 即网络设备,它是网络访问层中面向系统一侧的接口。不过这里所说的设备,跟物理硬件设备并不是同一个概念,Device 只是一种向操作系统端开放的接口,它的背后既可能代表着真实的物理硬件,也可能是某段具有特定功能的程序代码,比如即使不存在物理网卡,也依然可以存在回环设备(Loopback Device)。

许多网络抓包工具,比如tcpdump、Wirshark就是在此处工作的,我在前面第 ,之前介绍微服务流量控制的时候(引入历史文章链接),曾提到过的网络流量整形,通常也是在这里完成的。

Device 主要的作用是抽象出统一的界面,让程序代码去选择或影响收发包出入口,比如决定数据应该从哪块网卡设备发送出去;还有就是准备好网卡驱动工作所需的数据,比如来自上一层的 IP 数据包、下一跳(Next Hop)的 MAC 地址(这个地址是通过ARP Request得到的),等等。

  • Driver

网卡驱动程序(Driver)是网络访问层中面向硬件一侧的接口,网卡驱动程序会通过DMA把主存中的待发送的数据包,复制到驱动内部的缓冲区之中。数据被复制的同时,也会把上层提供的 IP 数据包、下一跳的 MAC 地址这些信息,加上网卡的 MAC 地址、VLAN Tag 等信息,一并封装成为以太帧(Ethernet Frame),并自动计算校验和。而对于需要确认重发的信息,如果没有收到接收者的确认(ACK)响应,那重发的处理也是在这里自动完成的。

干预网络通信的 Netfilter 框架

到这里,我们似乎可以发现,网络协议栈的处理是一套相对固定和封闭的流程,在整套处理过程中,除了在网络设备这层,我们能看到一点点程序以设备的形式介入处理的空间以外,其他过程似乎就没有什么可供程序插手的余地了。

然而事实并非如此,从 Linux Kernel 2.4 版开始,内核开放了一套通用的、可供代码干预数据在协议栈中流转的过滤器框架,这就是 Netfilter 框架。

Netfilter 框架是 Linux 防火墙和网络的主要维护者罗斯迪·鲁塞尔(Rusty Russell)提出并主导设计的,它围绕网络层(IP 协议)的周围,埋下了五个钩子(Hooks),每当有数据包流到网络层,经过这些钩子时,就会自动触发由内核模块注册在这里的回调函数,程序代码就能够通过回调来干预 Linux 的网络通信。

下面我给你介绍一下这五个钩子分别都是什么:

  • PREROUTING:来自设备的数据包进入协议栈后,就会立即触发这个钩子。注意,如果 PREROUTING 钩子在进入 IP 路由之前触发了,就意味着只要接收到的数据包,无论是否真的发往本机,也都会触发这个钩子。它一般是用于目标网络地址转换(Destination NAT,DNAT)。
  • INPUT:报文经过 IP 路由后,如果确定是发往本机的,将会触发这个钩子,它一般用于加工发往本地进程的数据包。
  • FORWARD:报文经过 IP 路由后,如果确定不是发往本机的,将会触发这个钩子,它一般用于处理转发到其他机器的数据包。
  • OUTPUT:从本机程序发出的数据包,在经过 IP 路由前,将会触发这个钩子,它一般用于加工本地进程的输出数据包。
  • POSTROUTING:从本机网卡出去的数据包,无论是本机的程序所发出的,还是由本机转发给其他机器的,都会触发这个钩子,它一般是用于源网络地址转换(Source NAT,SNAT)

12

Netfilter 允许在同一个钩子处注册多个回调函数,所以数据包在向钩子注册回调函数时,必须提供明确的优先级,以便触发时能按照优先级从高到低进行激活。而因为回调函数会有很多个,看起来就像是挂在同一个钩子上的一串链条,所以钩子触发的回调函数集合,就被称为“回调链”(Chained Callbacks),这个名字也导致了后续基于 Netfilter 设计的 Xtables 系工具,比如下面我要介绍的 iptables,都使用到了“链”(Chain)的概念。

那么,虽然现在看来,Netfilter 只是一些简单的事件回调机制而已,但这样一套简单的设计,却成为了整座 Linux 网络大厦的核心基石,Linux 系统提供的许多网络能力,比如数据包过滤、封包处理(设置标志位、修改 TTL 等)、地址伪装、网络地址转换、透明代理、访问控制、基于协议类型的连接跟踪、带宽限速,等等,它们都是在 Netfilter 的基础之上实现的。

而且,以 Netfilter 为基础的应用也有很多,其中使用最广泛的毫无疑问要数 Xtables 系列工具,比如iptables、ebtables、arptables、ip6tables,等等。如果你用过 Linux 系统来做过开发的话,那我估计至少这里面的 iptables 工具,你会或多或少地使用过,它常被称为是 Linux 系统“自带的防火墙”。

但其实,iptables 实际能做的事情已经远远超出了防火墙的范畴,严谨地讲,iptables 比较贴切的定位应该是能够代替 Netfilter 多数常规功能的 IP 包过滤工具。

要知道,iptables 的设计意图是因为 Netfilter 的钩子回调虽然很强大,但毕竟要通过程序编码才够能使用,并不适合系统管理员用来日常运维,而它的价值就是以配置去实现原本用 Netfilter 编码才能做到的事情。

一般来说,iptables 会先把用户常用的管理意图总结成具体的行为,预先准备好,然后就会在满足条件的时候自动激活行为,比如以下几种常见的 iptables 预置的行为:

  • DROP:直接将数据包丢弃。
  • REJECT:给客户端返回 Connection Refused 或 Destination Unreachable 报文。
  • QUEUE:将数据包放入用户空间的队列,供用户空间的程序处理。
  • RETURN:跳出当前链,该链里后续的规则不再执行。
  • ACCEPT:同意数据包通过,继续执行后续的规则。
  • JUMP:跳转到其他用户自定义的链继续执行。
  • REDIRECT:在本机做端口映射。
  • MASQUERADE:地址伪装,自动用修改源或目标的 IP 地址来做 NAT
  • LOG:在 /var/log/messages 文件中记录日志信息。
  • ……

当然,这些行为本来能够被挂载到 Netfilter 钩子的回调链上,但 iptables 又进行了一层额外抽象,它不是把行为与链直接挂钩,而是会根据这些底层操作的目的,先总结为更高层次的规则。

我举个例子,假设你挂载规则的目的是为了实现网络地址转换(NAT),那就应该对符合某种特征的流量(比如来源于某个网段、从某张网卡发送出去)、在某个钩子上(比如做 SNAT 通常在 POSTROUTING,做 DNAT 通常在 PREROUTING)进行 MASQUERADE 行为,这样具有相同目的的规则,就应该放到一起才便于管理,所以也就形成了“规则表”的概念。

iptables 内置了五张不可扩展的规则表(其中的 security 表并不常用,很多资料只计算了前四张表),我们来看看:

1.raw 表:用于去除数据包上的连接追踪机制(Connection Tracking)。

2.mangle 表:用于修改数据包的报文头信息,比如服务类型(Type Of Service,ToS)、生存周期(Time to Live,TTL),以及为数据包设置 Mark 标记,典型的应用是链路的服务质量管理(Quality Of Service,QoS)。

3.nat 表:用于修改数据包的源或者目的地址等信息,典型的应用是网络地址转换(Network Address Translation)。

4.filter 表:用于对数据包进行过滤,控制到达某条链上的数据包是继续放行、直接丢弃或拒绝(ACCEPT、DROP、REJECT),典型的应用是防火墙。

5.security 表:用于在数据包上应用SELinux,这张表并不常用。

这五张规则表是有优先级的:raw→mangle→nat→filter→security,也就是前面我列举出的顺序。这里你要注意,在 iptables 中新增规则时,需要按照规则的意图指定要存入到哪张表中,如果没有指定,就默认会存入 filter 表。此外,每张表能够使用到的链也有所不同,具体表与链的对应关系如下所示:

13

那么,你从名字上其实就能看出,预置的五条链是直接源自于 Netfilter 的钩子,它们与五张规则表的对应关系是固定的,用户不能增加自定义的表,或者修改已有表与链的关系,但可以增加自定义的链。

新增的自定义链与 Netfilter 的钩子没有天然的对应关系,换句话说就是不会被自动触发,只有显式地使用 JUMP 行为,从默认的五条链中跳转过去,才能被执行。

可以说,iptables 不仅仅是 Linux 系统自带的一个网络工具,它在容器间通信中也扮演着相当重要的角色。比如,Kubernetes 用来管理 Sevice 的 Endpoints 的核心组件 kube-proxy,就依赖 iptables 来完成 ClusterIP 到 Pod 的通信(也可以采用 IPVS,IPVS 同样是基于 Netfilter 的),这种通信的本质就是一种 NAT 访问。

当然,对于 Linux 用户来说,前面提到的内容可能都是相当基础的网络常识,但如果你平常比较少在 Linux 系统下工作,就可能需要一些用 iptables 充当防火墙过滤数据、充当作路由器转发数据、充当作网关做 NAT 转换的实际例子,来帮助理解了,这些操作在网上也很容易就能找到,这里我就不专门去举例说明了

小结

Linux 目前提供的八种名称空间里,网络名称空间无疑是隔离内容最多的一种,它为名称空间内的所有进程提供了全套的网络设施,包括独立的设备界面、路由表、ARP 表,IP 地址表、iptables/ebtables 规则、协议栈,等等。

虚拟化容器是以 Linux 名称空间的隔离性为基础来实现的,那解决隔离的容器之间、容器与宿主机之间,乃至跨物理网络的不同容器间通信问题的责任,就很自然地落在了 Linux 网络虚拟化技术的肩上。这节课里,我们暂时放下了容器编排、云原生、微服务等等这些上层概念,走进 Linux 网络的底层世界,去学习了一些与设备、协议、通信相关的基础网络知识。

最后我想说的是,到目前为止,介绍的 Linux 下网络通信的协议栈模型,以及程序如何干涉在协议栈中流动的信息,它们与虚拟化都没有产生什么直接联系,而是整个 Linux 网络通信的必要基础。在下节课,我们就要开始专注于跟网络虚拟化密切相关的内容了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/9406.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全能PDF:Pdfium.Net SDK 2023-03-18 Crack

Pdfium.Net SDK 是领先的 .Net 库,用于生成、操作和查看可移植文档格式的文件。我们提供高级 c# / VB.Net API,用于在 WEB 服务器或任何其他服务器系统上动态创建 pdf,并在现有桌面或 WEB 应用程序中实现“另存为 PDF”功能。 入门&#xff1…

汽车网络管理的意义和分类

网络管理的意义: 1. 工作状态协同: 在任意多ECU节点网络工作时,对同一网络ECU的通信状态做统一的管理,保证各个ECU节点可以在条件满足的时候进入低功耗模式 2. 信息交互协同: 可以根据NM报文状态判定特定ECU的运行状态…

ESP32设备驱动-MPL3115A2压力传感器驱动

MPL3115A2压力传感器驱动 文章目录 MPL3115A2压力传感器驱动1、MPL3115A2介绍2、硬件准备3、软件准备4、驱动实现1、MPL3115A2介绍 MPL3115A2 是一款紧凑型压阻式绝对压力传感器,具有 I2C 数字接口。 MPL3115A2 具有 20 kPa 至 110 kPa 的宽工作范围,该范围涵盖了地球上的所…

CarSim仿真快速入门(二十四)-CarSimSimulink联合仿真中的输入和输出IO接口

导入和导出数组用于Simulink以外的外部仿真工具。同样的设置也用于LabVIEW、ASCET、FMI/FMU以及可能用MATLAB、Python和其他语言编写的自定义程序。 在所有这些情况下,I/O通道。导入和I/O通道。输出屏幕用于配置VS数学模型以满足外部仿真工具的通信要求。 I/O 通道:输出 输…

[攻城狮计划(三)] —— 看门狗定时器

🙌秋名山码民的主页 😂一个打过一年半的oier,写过一年多的Java,现在致力于学习iot应用的普通本科生 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 🙏作者水平有限,如发现…

双非二本如何入职腾讯?只需要做好这些准备就能进大厂?

每年的招聘旺季在“金三银四”和“金九银十”这2段时间,许多在春招中没有找到心仪大厂offer的测试小伙伴最近有私信我,想要了解如何在秋招中一举获得心仪大厂的青睐,那今天我就来和大家扒一扒那些大厂自动化测试面试题以及注意事项哦&#xf…

Python解题 - CSDN周赛第43期

感觉周赛越来越无趣了,基本都是考过的题目。上期周赛也是,4道题都曾考过,问哥也都写过题解,奖品也不吸引人,实在没什么好写了。 回想前段时间用力过猛,刷了C站大部分OJ题,以致于现在看到题目就直…

Elasticsearch:索引状态是红色还是黄色?为什么?

在我之前文章 “Elasticsearch:如何调试集群状态 - 定位错误信息” 中,我有详细介绍如何调试集群状态。在今天的文章中,我将详细介绍如何故障排除和修复索引状态。 Elasticsearch 是一个伟大而强大的系统,特别是创建一个可扩展性极…

MySQL函数、视图、存储过程及触发器

前言 MySQL在我们工作中都会用到,那么我们最常接触的就是增删改查,而对于增删改查来说,我们更多的是查询。但是面试中,面试官又不会问你什么查询是怎么写的,都是问一些索引啊,事务啊, 底层结构…

Hbase 介绍

Hbase 简介 Hbase 是一个开源的非关系型的分布式数据库,运用于HDFS文件系统之上,可以容错地存储海量稀疏的数据。Hbase是一个高可靠、高性能、面向列、可伸缩、实时读写的分布式数据库,主要用来存储非结构化和半结构化的松散数据 。 Hbase的…

ChatGPT中文在线官网-如何与chat GPT对话

怎么下载ChatGPT中文版 ChatGPT是一种基于Transformer架构的自然语言处理技术,其中包含了多个预训练的中文语言模型。这些中文ChatGPT模型大多数发布在Github上,可以通过Github的源码库来下载并使用,包括以下几种方式: 下载预训练…

高并发写场景:库存扣减

在设计商品的库存扣减逻辑时&#xff0c;可能一开始想到的(伪)代码是&#xff1a; <?php /*** 商品库存扣减** param int $skuId 商品ID* param int $num 库存扣减数量** return bool 扣减成功返回true&#xff0c;失败返回false*/ function stock_decr($skuId, $num) {…

Go是一门面向对象编程语言吗

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;tonybai|慕课网讲师 Go语言已经开源13年了&#xff0c;在近期TIOBE发布的2023年3月份的编程语言排行榜中&#xff0c;…

【hello Linux】Linux基本指令(下)

目录 1. more 指令&#xff1a;分批查看文件 1.1 more -n 文件名&#xff1a;查看文件前 n 行 1.2 more 文件名&#xff1a;屏幕输满 补充指令&#xff1a; 2. less 指令 2.1 less -N 文件名 2.2 /字符串&#xff1a;向下搜索“字符串”的功能 3. head 指令 3.1 head 文件名 3…

4.Java逻辑控制语句

Java逻辑控制语句 在实际生活中&#xff0c;我们的生活不是一成不变的&#xff0c;很多时候需要我们去选择&#xff0c;大到人生的十字路口&#xff0c;小到今天晚上吃什么&#xff0c;选择无处不在。小的选择决定了我们一件小事的走向&#xff0c;大的选择可能会改变我们人生…

基于多目标粒子群优化算法的计及光伏波动性的主动配电网有功无功协调优化(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JavaScript -- 对象

1. 概念 对象是 JavaScript 数据类型的一种&#xff0c;可以理解为是一种无序的数据集合 2. 对象的使用 2.1 对象的声明 let 对象名 {} let 对象名 new Object() 2.2 属性和方法 数据描述性的信息称为属性&#xff0c;如人的姓名、身高、年龄、性别等&#xff0c;一般是…

蓝桥杯之贪心

蓝桥杯之贪心1055.股票买卖II104.货仓选址AcWing112.雷达设备1235.付账问题1239.乘积最大K是奇数&#xff0c;需要转化为K是偶数的情况&#xff0c;于是先取一个数&#xff0c;为了使得结果最大&#xff0c;取最大的数&#xff08;正数的话绝对值最大&#xff0c;负数的话(K是奇…

java版工程项目管理系统源码 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单

ava版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示1…

托福高频真词List12 // 附托福TPO阅读真题

目录 4.5单词 生词 熟词 真题 4.5单词 生词 irreversiblepermanentadj.无法挽回的&#xff0c;永久的manipulateskillfully usedhandlev.操控monumentalenormousgreat and significantadj.极大的&#x1f9f8;retardslowv.放缓&#x1f9f8;subsistencesurvivaln.生存 wit…