网络设备
Linux内核中有一个网络设备管理层,处于网络设备驱动和协议栈之间,负责衔接它们之间的数据交互。驱动不需要了解协议栈的细节,协议栈也不需要了解设备驱动的细节。
对于一个网络设备来说,就像一个管道(pipe)一样,有两端,从其中任意一端收到的数据将从另一端发送出去。
比如一个物理网卡eth0,它的两端分别是内核协议栈(通过内核网络设备管理模块间接的通信)和外面的物理网络,从物理网络收到的数据,会转发给内核协议栈,而应用程序从协议栈发过来的数据将会通过物理网络发送出去。
- 物理网络设备的两端分别是内核协议栈(通过内核网络设备管理模块间接的通信,或者其他网络设备,如bridge)和外面的物理网络,从物理网络收到的数据,会转发给内核协议栈,而应用程序从协议栈发过来的数据将会通过物理网络发送出去
- 虚拟网络设备的一端也是协议栈,而另一端是什么取决于虚拟网络设备的驱动实现
物理网络设备
- 集线器(hub): 在物理层扩展局域网, 构成了一个冲突域和一个广播域
- 中继器(Repeater): 扩展网络距离,将衰减信号经过再生; 实现粗同轴电缆以太网和细同轴电缆以太网的互连; 构成了一个单个的冲突域和广播域.
- 二层交换机: 以太网交换机实质上就是一个多接口的网桥,可见交换机工作在数据链路层, 交换机上的每个接口都是自己的一个冲突域. 交换机上的学习的结果,称为转发表,有过期时间
- 基于vlan的二层交换机: 为隔离广播域而生的,它可以将一个大的共享局域网的用户分成许多独立的小的广播域.
- 路由器(Router): 工作在网络层, 路由器的每个端口所连接的网络都独自构成一个广播域, (如果各网段都是共享式局域网)每网段自己构成一个独立的冲突域.
- 网关(Gateway): 网关工作在OSI参考模型的高三层,因此,并不使用冲突域、广播域的概念。网关主要用来进行高层协议之间的转换, 注意,这里网关的概念完全不同于PC主机以及路由器上配置的默认网关(default gateway)
虚拟网络设备
首先它也归内核的网络设备管理子系统管理,对于Linux内核网络设备管理模块来说,虚拟设备和物理设备没有区别,都是网络设备,都能配置IP,从网络设备来的数据,都会转发给协议栈,协议栈过来的数据,也会交由网络设备发送出去,至于是怎么发送出去的,发到哪里去,那是设备驱动的事情,跟Linux内核就没关系了,所以说虚拟网络设备的一端也是协议栈,而另一端是什么取决于虚拟网络设备的驱动实现。
- 网桥: (比较特殊,有多个端口)能够起到虚拟交换机作用, 工作在数据链路层,它根据 MAC 帧的目的地址对收到的帧进行转发.每个冲突域共享自己的总线信道带宽. 隔离冲突域, 共享广播域. (网桥的端口有自己的物理地址, 但对于主机来说等于是透明的)(但是网桥本身可以有一个物理地址和ip地址)
- Veth Pair: 总是以两张虚拟网卡(Veth Peer)的形式成对出现的。并且,从其中一个“网卡”发出的数据包,可以直接出现在与它对应的另一张“网卡”上,哪怕这两个“网卡”在不同的 Network Namespace 里
- Tun/Tap虚拟设备: 都是虚拟网卡,没有直接映射到物理网卡,是一种纯软件的实现。Tun是三层虚拟设备,能够处理三层即IP包(在操作系统内核和用户应用程序之间传递 IP 包),Tap是二层设备,能处理链路层网络包如以太网包
1 | +----------------------------------------------------------------+ |
协议栈
协议栈(Protocol Stack)是指网络中各层协议的总和,其形象的反映了一个网络中文件传输的过程:由上层协议到底层协议,再由底层协议到上层协议。使用最广泛的是英特网协议栈,由上到下的协议分别是:应用层(HTTP,FTP,TFTP,TELNET,DNS,EMAIL等),运输层(TCP,UDP),网络层(IP),链路层(WI-FI,以太网,令牌环,FDDI,MAC等),物理层。
通俗一点讲就是,一个主机的数据要经过哪些过程才能发送到对方的主机上。
OSI
OSI model: The Open Systems Interconnection model
一种概念模型,由国际标准化组织(ISO)提出,一个试图使各种计算机在世界范围内互连为网络的标准框架。
通俗的说,为了全世界的计算机之间相互通信,而设计的一种协议框架,所有需要联网的设备或软件都需要遵循它的规则。另外,也为了尽可能避免所有功能混杂在一起,让不同公司或组织更聚焦在一个领域上,才有了现在的分层模型。
在每一层,根据实际应用场景,都有对应的协议被设计出来。
TCP/IP
基于 OSI 协议模型衍生而来,现今使用最多的就是 TCP/IP 协议栈了。注意这里的 TCP/IP 协议栈并不只是指 TCP 与 IP 协议的合集,它是一种更简化的 OSI 模型。
TCP/IP 协议采用4层结构,分别是应用层、传输层、网络层和链路层,每一层都呼叫它的下一层所提供的协议来完成自己的需求
对比:
除了以上的协议栈外,还有当今两个重要的协议:TLS 与 SPDY 。(不做介绍)
网络协议栈
小结
也就是说,协议栈就是位于网络设备和应用之间的一套通信协议的合集,网络设备和应用之间通过这一套协议进行数据的传输,每一次的数据传输都要走一遍这一套协议(包括从本机的一个网卡到另一个网卡,一层一层走)
网卡收发基础
网卡本身是有内存的,每个网卡一般都有4K以上的内存,用来发送,接收数据。
数据在从主内存搬到网卡之后,不是立即就能被发送出去的,而是要先在网卡自身的内存中排队,再按照先后顺序发送;同样的,数据从以太网传递到网卡时,网卡也是先把数据存储到自身的内存中,等到收到一帧数据了,再经过中断的方式,告诉主CPU(不是网卡本身的微处理器)把网卡内存的数据读走,而读走后的内存,又被清空,再次被使用,用来接收新的数据,如此循环往复。
bridge
是什么
首先,bridge是一个虚拟网络设备,所以具有网络设备的特征,可以配置IP、MAC地址等;其次,bridge是一个虚拟交换机,和物理交换机有类似的功能。
对于普通的网络设备来说,只有两端,从一端进来的数据会从另一端出去,如物理网卡从外面网络中收到的数据会转发给内核协议栈,而从协议栈过来的数据会转发到外面的物理网络中。
而bridge不同,bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看mac地址。
创建bridge
当刚创建一个bridge时,它是一个独立的网络设备,只有一个端口连着协议栈,其它的端口啥都没连,这样的bridge没有任何实际功能,如下图所示:
1 | +----------------------------------------------------------------+ |
将bridge和虚拟网卡相连
1 | +----------------------------------------------------------------+ |
这里为了画图方便,省略了IP地址前面的192.168,比如.3.21就表示192.168.3.21
br0和veth0相连之后,发生了几个变化:
- br0和veth0之间连接起来了,并且是双向的通道
- 协议栈和veth0之间变成了单通道,协议栈能发数据给veth0,但veth0从外面收到的数据不会转发给协议栈
- br0的mac地址变成了veth0的mac地址
相当于bridge在veth0和协议栈之间插了一脚,在veth0上面做了点小动作,将veth0本来要转发给协议栈的数据给拦截了,全部转发给bridge了,同时bridge也可以向veth0发数据。
veth0收到应答包后没有给协议栈,而是给了br0。
给bridge配上IP
通过上面的分析可以看出,给veth0配置IP没有意义,因为就算协议栈传数据包给veth0,应答包也回不来。这里我们就将veth0的IP让给bridge。
1 | +----------------------------------------------------------------+ |
其实veth0和协议栈之间还是有联系的,但由于veth0没有配置IP,所以协议栈在路由的时候不会将数据包发给veth0,就算强制要求数据包通过veth0发送出去,但由于veth0从另一端收到的数据包只会给br0(只能给br0,看图中箭头),所以协议栈还是没法收到相应的arp应答包,导致通信失败。
这里为了表达更直观,将协议栈和veth0之间的联系去掉了,veth0相当于一根网线。
将物理网卡添加到bridge
br0根本不区分接入进来的是物理设备还是虚拟设备,对它来说都一样的,都是网络设备,所以当eth0加入br0之后,落得和上面veth0一样的下场,从外面网络收到的数据包将无条件的转发给br0,自己变成了一根网线。
r0通过eth0这根网线连上了外面的物理交换机,所以连在br0上的设备都能ping通网关,这里连上的设备就是veth1和br0自己(图上和协议栈有直接连接的就这两个),veth1是通过veth0这根网线连上去的,而br0可以理解为自己有一块自带的网卡(同样的,这个网卡起着网线的作用,将bridge br0和协议栈连接)。
由于eth0已经变成了和网线差不多的功能,所以在eth0上配置IP已经没有什么意义了,并且还会影响协议栈的路由选择,比如如果上面ping的时候不指定网卡的话,协议栈有可能优先选择eth0,导致ping不通,所以这里需要将eth0上的IP去掉。
经过上面一系列的操作后,网络变成了这个样子:
1 | +----------------------------------------------------------------+ |
bridge必须配IP吗
在我们常见的物理交换机中,有可以配置IP和不能配置IP两种,不能配置IP的交换机一般通过com口连上去做配置(更简单的交换机连com口的没有,不支持任何配置),而能配置IP的交换机可以在配置好IP之后,通过该IP远程连接上去做配置,从而更方便。
bridge就属于后一种交换机,自带虚拟网卡,可以配置IP,该虚拟网卡一端连在bridge上,另一端跟协议栈相连。和物理交换机一样,bridge的工作不依赖于该虚拟网卡,但bridge工作不代表机器能连上网,要看组网方式。
bridge常用场景
虚拟机
虚拟机通过tun/tap或者其它类似的虚拟网络设备,将虚拟机内的网卡同br0连接起来,这样就达到和真实交换机一样的效果,虚拟机发出去的数据包先到达br0,然后由br0交给eth0发送出去,数据包都不需要经过host机器的协议栈,效率高。
1 | +----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+ |
docker
由于容器运行在自己单独的network namespace里面,所以都有自己单独的协议栈,情况和上面的虚拟机差不多,但它采用了另一种方式来和外界通信:
1 | +----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+ |
容器中配置网关为.9.1,发出去的数据包先到达br0,然后交给host机器的协议栈,由于目的IP是外网IP,且host机器开启了IP forward功能,于是数据包会通过eth0发送出去,由于.9.1是内网IP,所以一般发出去之前会先做NAT转换(NAT转换和IP forward功能都需要自己配置)。由于要经过host机器的协议栈,并且还要做NAT转换,所以性能没有上面虚拟机那种方案好,优点是容器处于内网中,安全性相对要高点。(由于数据包统一由IP层从eth0转发出去,所以不存在mac地址的问题,在无线网络环境下也工作良好)
总结
网桥是需要网卡作为接口的,接入到网桥中的网卡,对外不可见,即使网卡本身有IP,在接入网桥之后,IP对外不可见了,使用ip a
命令查看,网卡网络信息里面没有ipv4的地址了,或者你的GUI界面的网络显示你是断网的, 这不用担心,因为网卡的网络能力已经通过网桥进行工作,你的host网络还是能正常工作的。
网桥可以看做是一个自带网卡的网络设备,这个网卡充当网线的作用,将网桥和协议栈连接上;
接入网桥的网卡配置IP是没有意义的:
(例:将网卡eth0接入网桥br0)当eth0加入br0之后,从外面网络收到的数据包将无条件的转发给br0,自己变成了一根网线;由于eth0已经变成了和网线差不多的功能,所以在eth0上配置IP已经没有什么意义了,并且还会影响协议栈的路由选择(有ip的话,协议栈会优先走eth0而非br0,但是进入eth0之后,eth0依然无条件转发给br0,不如协议栈直接走br0)。
网络联通的的本质是:
协议栈能通过机器中的一些网络设备(网桥、网卡等)和机器外的物理网络连接,形成一条畅通的能走通的路;
而就机器内的所有网络设备而言,如果有多个和协议栈连接,则协议栈会选其中一个(具体选那个还不清楚),如果该网络设备(假设为1号)直接连接的外部物理网络,那么直接就能上网了;如果该设备没有接到外部物理网络,而是接到另一个网络设备(2号),而2号连接这物理网络(bridge不就是这样的东西吗),那么协议栈就会通过先到1再到2来连接网络,依然可以联通网络;多来几个相连的网络设备还是同样的原理;而如果没有一个和外网连接,那么机器就无法连接到网络上;
参考:
v1.4.14