Linux内核中的网络协议栈解析 (linux内核–网络协议栈深入分析)

随着网络技术的不断发展和普及,人们日常生活中使用的各种设备,如电脑、手机、路由器等都要依赖底层的网络协议栈来实现网络通信。这其中的关键组成部分就是操作系统内核中的网络协议栈,它是实现网络通信的重要基础设施。

Linux作为自由软件界更具影响力的操作系统之一,我们就来一探究竟,看看Linux内核中的网络协议栈究竟是如何实现的。

1.网络协议栈的基本概念

网络协议栈是指对网络通信所需的协议的总称,它是一个按不同层次组织的协议堆栈。在通信过程中,不同层次的网络协议需要协同工作,实现信息的传输和处理。

网络协议栈的通信层次大致可以分为四个层次:网络接口层、网络层、传输层和应用层。

网络接口层:负责获取和发送数据帧;

网络层:实现源与目的主机之间的逻辑通信;

传输层:实现进程之间的端到端通信;

应用层:提供特定服务,如文件传输、电子邮件等。

2.Linux内核中的网络协议栈架构

Linux内核中的网络协议栈采用了分层的设计思路,分为硬件驱动层、网络层、传输层和应用层四个部分。

硬件驱动层:主要负责将网络物理层的帧转化为适合内核协议栈的数据格式,并完成底层设备的管理和驱动。

网络层:负责实现IP协议,并提供路由和地址功能。

传输层:实现TCP和UDP协议,实现端口的服务功能。

应用层:提供各种网络服务,如FTP、TP、HTTP、SSH等。

网络协议栈中不同层次之间的交互通过一种叫做套接字(socket)的机制来实现。套接字是通信过程中的一种通用的接口,实现不同层次之间的数据传输和处理。

3.Linux内核中的网络协议栈实现

在Linux内核中,网络协议栈的实现主要有以下几个方面:

3.1 路由算法

路由算法是指在网络层中,将数据报从源地址传送到目标地址所需的路径选择算法。Linux内核中的路由算法主要有静态路由和动态路由两种,其中动态路由又可以分为OSPF、BGP等协议。由于动态路由算法需要实时更新路由表,所以在网络规模比较大的情况下,它具有很大的优势。

3.2 TCP/IP协议的实现

在Linux内核中,TCP/IP协议是网络协议栈中的重要部分。它通过IP协议实现了互联网上不同主机之间的数据传输。而TCP协议则基于IP协议之上,实现了可靠的、基于连接的数据传输。

对于TCP/IP协议的实现,Linux内核中采用的是一种叫做半同步/半异步的方式。其中,TCP连接中的数据传输是异步的,而连接的管理则是同步的。

3.3 网络设备驱动程序的实现

网络设备驱动程序是实现网络协议栈与底层硬件交互的关键部分。在Linux内核中,网络设备驱动程序主要有两种实现方式:一种是将驱动程序编译为内核模块,另一种是将驱动程序编译到内核中。

与以往不同的是,Linux内核为网络设备驱动程序提供了一种名叫网络设备驱动接口(Network Device Driver Interface,简称NDDI)的接口,来让网络设备驱动程序更加灵活和智能化。

4.

在Linux内核中,网络协议栈是实现网络通信的核心设施。Linux内核中的网络协议栈采用了分层的设计思路,并采用了较为先进的算法和驱动机制来实现网络数据传输。同时,在网络协议栈的实现中还依靠着一种名叫套接字的通用接口。

随着互联网技术的不断发展和普及,操作系统内核中的网络协议栈的作用和意义也越来越重要。相信随着技术的不断进步和发展,Linux内核中的网络协议栈会越来越完善和智能化。

相关问题拓展阅读:

k8s 网络基础

author:sufei

说明:本文主要记录在学习k8s网络方面的相关知识

 Linux在内核网络栈中引入网络命名空间,将

独立的网络协议栈隔离

到不同的命令空间中,彼此间无法通信;

1、Linux操作系统,解析和封装网络包是通过一个网络协议栈完成,下层为上层服务,这个

协议栈中即包括如软件也包括硬件网络设

备。网络命名空间就是以软件方式隔离出纳神单独的网络栈信息;世茄凯

2、不同network namespace的软硬件资源相互不可见,好像处在物理隔离的不同物理机上一样,彼此隔离;

3、不同的网络命名空间会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源

4、实验:可以借助 ip netns 命令来完成对 Network Namespace 的各种操作,如:

问题

:什么是转移设备?

 可以在不同的 Network Namespace 之间转移设备(如veth)。由于一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。

veth设备属于可转移设备

,而很多其它设备(如lo、bridge等)是不可以转移的。

 veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。而veth pair就是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。

实验

 veth pair打破了 Network Namespace 的限制,实现了不同 Network Namespace 之间的通信。但veth pair有一个明显的缺陷,就是只能实现两个网络接口之间的通信。如果我们想实现多个网络接口之间的通信,就可以使用下面介绍的网桥(Bridge)技术(

类似于物理交换机

)。

 简单来说,网桥就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。

 网桥是一个二层网络设备,通过网桥可搜唤以将linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。

实验:

 Netfilter负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核 模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表;通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。

 iptables/netfilter(简称iptables)组成了Linux平台下的包过滤防火墙,可以完成封包过滤、封包重定向和网络地址转换(NAT)等功能。这部分主要了解两部分知识:

 应用层不管是要发送还是接收网络消息,都需要通过linux内核提供的一系列关卡。每个”关卡“担负着不同的工作。这里的”关卡“被称为”链“。如下图:

 Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关(如上面的172.17.0.1)。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

 Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过:访问容器。

 下面具体来说说docker容器的几种网络模式,以便后续学习k8s网络。

 在host模式下( –net=host),容器不会去建立新的网络命名空间,而直接使用宿主机的网络设备以及网络协议栈。这样自然不会虚拟出自己的网卡,配置自己的IP等。其特点如下:

 这个模式就是在创建容器时,指定网络(–net=container:NAME_or_ID)与之前容器在同一个网络命名空间中,而不是和宿主机共享(这也就是k8s中pod内各容器的一种网络模式)。下面说明几点:

 none模式(–net=none)Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

 bridge模式是docker容器的默认模式,当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器在bridge模式下会连接到这个虚拟网桥上,并由网桥自动分配ip。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

 下面说明这个模式下的工作方式:

 首先我们来看看k8s想要一个什么样的网络,也就是k8s网络设计的要求,具体如下:

 下面简单从几中不同的通信要求来看看k8s网络实现。

 在 Kubernetes 的世界里,IP 是以 Pod 为单位进行分配的。一个 Pod 内部的所有容器共享一个网络堆栈。实际上就是docker container网络模式。可以直接通过本地localhost进行网络访问。这个模式在mysql容器化中就是agent容器与mysql容器的网络通信方式。

 Pod1和Pod2都是通信veth pair连接到同一个docker0网桥上,它们的IP地址都是从docker0网段上动态获取的,它们和网桥本身的IP是同一个网段的。可以通过docker0作为交换机进行通信,也就是采用的docker bridge网络模式进行通信。

 由于在同一个网桥docker0上即可以保证分配的pod IP不会冲突,且可以相互通信,而如果需要跨Node物理节点,则无法通过docker网络直接满足要求了,那这些要求具体有哪些呢?

解决方案

方法一:k8s中通过在etcd中记录正在运行中pod的IP分配信息,这样我们就可以满足Pod IP与Node IP之间映射关系的记录;

方法二:可以在etcd中规划配置好所有主机docker0网桥的子网范围,从而满足Pod IP不冲突的要求;如:

方法三:要实现Pod跨Node通信,以k8s默认网络Flannel为例,就是采用overlay(覆盖网络)实现。具体下面说明:

问题:什么是覆盖网络?

覆盖网络就是应用层网络,是指建立在另一个网络上的网络。怎么理解呢?简单理解就是将TCP数据包装在另一种网络包里面进行路由转发和通信,另一种网络包目前可以是UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。默认以UDP为例来说明flannel工作方式。

下面看看具体实现

问题

:为保证各node内docker容器分配的ip地址不冲突,每个节点上的Docker会使用不同的IP地址段?如何实现的呢?

问题

Linux内核源码剖析的介绍

《Linux内核源码剖析》是由裤空樊东东,莫澜编著,机械工业出版社于2023年1月1日出版的一本书籍。胡碧瞎本书详细论述了Linux内核2.6.20版本中TCP/IP的实现。书中给出了大量的源代码,通过对源代码的详细注释,帮助读者掌握TCP/IP的实现。本书根据协议栈层次,从驱动层逐步论述到传输层,包括驱动的实现、接口层的输入输出、IP层的输入输出以及IP选项的处理、邻居子系统、路由、套接口及传输层等内容,全书基本涵盖了网络体系架构全部的知识点。特别是TCP,包括TCP连接的建立和终止、输慧闹入与输出,以及拥塞控制的实现。

linux内核–网络协议栈深入分析的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux内核–网络协议栈深入分析,Linux内核中的网络协议栈解析,k8s 网络基础,Linux内核源码剖析的介绍的信息别忘了在本站进行查找喔。


数据运维技术 » Linux内核中的网络协议栈解析 (linux内核–网络协议栈深入分析)