Linux用户态和内核态
为了减少有限资源的访问和使用冲突,Unix/Linux的设计哲学之一就是:对不同的操作赋予不同的执行等级,就是所谓特权的概念。简单说就是有多大能力做多大的事,与系统相关的一些特别关键的操作必须由最高特权的程序来完成。Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程。
Linux命名空间
namespace本质上是宿主机上的进程,所以资源隔离主要就是指进程资源的隔离。隔离意味着可以抽象出多个轻量级的内核,这些进程可以充分利用宿主机的资源,宿主机有的资源进程都可以享有,但彼此之间是隔离的。同样,不同进程之间使用资源也是隔离的,这样,彼此之间进行相同的操作,都不会互相干扰,安全性得到保障。
为了支持这些特性,Linux namespace 实现了 6 项资源隔离,基本上涵盖了一个小型操作系统的运行要素,包括主机名、用户权限、文件系统、网络、进程号、进程间通信。
如果想要查看当前进程下有哪些 namespace 隔离,可以查看文件 /proc/[pid]/ns。
和network namespace 相关的操作的子命令是 ip netns。
tap和tun
tap/tun 是 Linux 内核 2.4.x 版本之后实现的虚拟网络设备。tap/tun 虚拟网卡完全由软件来实现,功能和硬件实现完全没有差别,它们都属于网络设备,都可以配置 IP,都归 Linux 网络设备管理模块统一管理。作为网络设备,tap/tun 也需要配套相应的驱动程序才能工作。tap/tun 驱动程序包括两个部分,一个是字符设备驱动,一个是网卡驱动。
TAP/TUN是Linux内核实现的一对虚拟网络设备,TAP工作在二层,TUN工作在三层,Linux内核通过TAP/TUN设备向绑定该设备的用户空间应用发送数据;反之,用户空间应用也可以像操作硬件网络设备那样,通过TAP/TUN设备发送数据。基于TAP驱动,即可以实现虚拟网卡的功能,虚拟机的每个vNIC都与Hypervisor中的一个TAP设备相连。当一个TAP设备被创建时,Linux设备文件目录下将会生成一个与之对应的字符设备文件,用户空间应用可以像打开普通文件一样打开这个文件进行读写。
当对TAP设备文件执行write()操作时,对于Linux网络子系统来说,相当于位于内核空间的TAP设备收到了数据,Linux内核收到此数据后将根据网络配置进行后续处理,处理过程类似于普通的物理网卡从外界收到数据。当用户空间应用执行read()请求时,相当于向内核查询TAP设备上是否有数据需要被发送,有的话则取出到用户空间里,从而完成 TAP 设备发送数据的功能。
tap 和 tun 虽然都是虚拟网络设备,但它们的工作层次还不太一样。
- tap 是一个二层设备(或者以太网设备),只能处理二层的以太网帧;
- tun 是一个点对点的三层设备(或网络层设备),只能处理三层的 IP数据包。
创建 tap/tun 设备:
ip tuntap add dev tap0 mod tap # 创建 tap
ip tuntap add dev tun0 mod tun # 创建 tun
- 1
- 2
删除 tap/tun 设备:
ip tuntap del dev tap0 mod tap # 删除 tap
ip tuntap del dev tun0 mod tun # 删除 tun
- 1
- 2
veth-pair
veth-pair 是成对出现的一种虚拟网络设备,一端连接着协议栈,一端连接着彼此,数据从一端出,从另一端进。它的这个特性常常用来连接不同的虚拟网络组件,构建大规模的虚拟网络拓扑,比如连接 Linux Bridge、OVS、LXC 容器等。一个很常见的案例就是它被用于 OpenStack Neutron,构建非常复杂的网络形态。
使用veth-pair连接两个namespace
如下图所示,创建两个Network Namespace,分别命名为net0与net1,同时创建了 VETH pair 对 veth0与 veth1,将它们分别加入 net0与 net1,将两个 Network Namespace连接起来。
图4.1、使用VETH pair连接两个Network Namespace
# 创建veth对veth1和veth2
$ ip link add veth1 type veth peer name veth2
# 为veth设备对设置IP地址
$ ip address add 10.0.1.1/24 dev veth1
$ ip address add 10.0.1.2/24 dev veth2
# 将veth加入namespace
$ ip link set veth1 netns ns1
$ ip link set veth2 netns ns2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
虽然 VETH pair 可以实现两个 Network Namespace 之间的通信,但是当多个Namespace需要通信的时候,就无能为力了。涉及多个网络设备之间的通信,首先想到的是交换机和路由器。因为这里要考虑的只是同一个网络,所以只用到交换机的功能,也就是后面所述的网桥。
使用veth-pair和网桥连接多个namespace
可以创建VETH pair,比如veth0与veth1,并将一个VETH接口veth0加入Network Namespace,另一个VETH接口veth1加入Bridge。
如图4.2所示,创建三个Network Namespace分别为net0、net1与net2,同时创建有Bridge br0,以及各个Network Namespace与br0之间连接的VETH pair,br0将net0、net1与net2连接起来。
图4.2、使用Bridge连接Network Namespace
bridge
Linux网桥具有交换机的所有功能。Bridge的实现有一个限制:当一个设备被绑定到Bridge上时,该设备的IP地址会变得无效,Linux不再使用该IP地址在三层接收数据。比如,如果eth0本来具有自己的IP地址192.168.1.1,在绑定到br0之后,它的IP地址会失效,用户程序不再能接收或发送到这个IP地址的数据,只有目的地址为br0 IP的数据包才会被Linux接收。
Bridge 设备通常就是结合 tap/tun、veth-pair 设备用于虚拟机、容器网络里面。虚拟机一般通过 tap/tun 设备将虚拟机网卡同宿主机里的 Bridge 连接起来,完成同主机和跨主机的通信。如下图所示:
#创建一个bridge:
ip link add br0 type bridge
ip link set br0 up
- 1
- 2
- 3
Linux虚拟机网络模型
总的来说,目前有四种常见的网络模型:
- 桥接(Bridge Adapter)
- NAT
- 主机(Host-only Adapter)
- 内部网络(Internal)
这也是 VirtualBox 支持的四种模型,对于 VMware,则只有前三种。
桥接(Bridge Adapter)
虚拟机桥接网络模型就是使用虚拟交换机(Linux Bridge),将虚拟机和物理机连接起来,它们处于同一个网段,IP 地址是一样的。如下图所示:
在这种网络模型下,虚拟机和物理机都处在一个二层网络里面,所以有:
- 虚拟机之间彼此互通
- 虚拟机与主机彼此可以互通
- 只要物理机可以上网,那么虚拟机也可以。
桥接网络的好处是简单方便,但也有一个很明显的问题,就是一旦虚拟机太多,广播就会很严重。所以,桥接网络一般也只适用于桌面虚拟机或者小规模网络这种简单的形式。
NAT
另一种模型是 NAT,即网络地址转换(Network Address Translatation)。这种模型严格来讲,又可以分为 NAT 和 NAT 网络两种。根据 NAT 的原理,虚拟机所在的网络和物理机所在的网络不在同一个网段,虚拟机要访问物理所在网络必须经过一个地址转换的过程,也就是说在虚拟机网络内部需要内置一个虚拟的 NAT 设备来做这件事。
NAT 和 NAT 网络都可以通过物理机访问外网,但两者还有些许的不同:
- NAT:主机上的虚拟机之间是互相隔离的,彼此不能通信(它们有独立的网络栈,独立的虚拟 NAT 设备)
- NAT 网络:虚拟机之间共享虚拟 NAT 设备,彼此互通。
如下图,展示了两者细微的差别:
PS:NAT 网络模式中一般还会内置一个虚拟的 DHCP 服务器来进行 IP 地址的管理。
NAT 网络 虚拟机之间共享网络栈,它们的 IP 地址处于同一个网段,所以彼此是互通的。
总结一下,以上两种 NAT 模式,如果不做其他配置,那么有:
- 虚拟机可以访问主机,反之不行
- 如果主机可以上外网,那么虚拟机也可以
- 对于 NAT,同主机上的虚拟机之间不能互通
- 对于 NAT 网络,虚拟机之间可以互通
PS:如果做了 端口映射 配置,那么主机也可以访问虚拟机。
主机网络(Host-only Adapter)
主机网络顾名思义,就是只限于主机内部访问的网络,虚拟机之间彼此互通,虚拟机与主机之间彼此互通。但是默认情况下虚拟机不能访问外网(注意:这里说的是默认情况下,如果稍作配置,也是可以的)。主机网络模型会在主机中模拟出一块虚拟网卡供虚拟机使用,所有虚拟机都连接到这块网卡上,这块网卡默认会使用网段 192.168.56.x(在主机的网络配置界面可以看到这块网卡),如下是基本的拓扑图示:
默认情况下,虚拟机之间可以互通,虚拟机只能和主机上的虚拟网卡互通,不能和不同网段的网卡互通,更不能访问外网,如果想做到这样,那么需要如图中 红虚线 所示,将物理网卡和虚拟网卡桥接或共享。
内部网络internal
最后一种网络模型是内部网络,这种模型是相对最简单的一种,虚拟机与外部环境完全断开,只允许虚拟机之间互相访问,这种模型一般不怎么用,所以在 VMware 虚拟机中是没有这种网络模式的。这里我们就不多说了。
总结
下面以一张表来描述它们之间的通信行为:
ifconfig命令
[root@mysql ~]# ifconfig // 查看所有网卡的信息(不包括down状态的网卡)
[root@mysql ~]# ifconfig -a // 查看所有网卡的信息(包括down状态的网卡)
[root@mysql ~]# ifconfig eth0 // 查看指定网卡的信息
[root@mysql ~]# ifconfig eth0 up // 启用指定的网卡,等同于:ifup eth0
[root@mysql ~]# ifconfig eth0 down // 关闭指定的网卡,等同于:ifdown eth0
[root@mysql ~]# ifconfig eth0 arp // 开启网卡的ARP协议
[root@mysql ~]# ifconfig eth0 -arp // 关闭网卡的ARP协议
[root@mysql ~]# ifconfig eth0 192.168.0.100 // 设置/修改网卡的IP地址(临时生效)
[root@mysql ~]# ifconfig eth0 192.168.0.100/24 // 设置/修改网卡的IP地址和子网掩码(临时生效)
[root@mysql ~]# ifconfig eth0 192.168.0.100 netmask 255.255.255.0 // 设置/修改网卡的IP地址和子网掩码(临时生效)
[root@mysql ~]# ifconfig eth0 192.168.0.100 hw ether 04:64:03:00:12:51 // 设置/修改网卡的IP地址和MAC地址(临时生效),ether(以太网)表示网卡的接口类型
[root@mysql ~]# ifconfig eth0 mtu 1500 // 设置/修改网卡的最大传输单元(临时生效)
[root@mysql ~]# ifconfig eth0:0 192.168.0.50/24 // 给网卡配置虚拟接口,相当于给网卡再配置一个IP地址(临时生效)
[root@mysql ~]# ifconfig eth0:1 192.168.0.51/24 // 给网卡配置虚拟接口,相当于给网卡再配置一个IP地址(临时生效)
[root@mysql ~]# ifconfig eth0:2 192.168.0.52/24 // 给网卡配置虚拟接口,相当于给网卡再配置一个IP地址(临时生效
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
要把配置好的ip清除掉,可以使用以下命令:
ip addr flush dev eth0
如果系统中没有ip这个命令,可以使用更简单的:
ifconfig eth0 0.0.0.0
查看内存信息
/proc/meminfo这个文件记录着比较详细的内存配置信息,使用cat /proc/meminfo查看
也可以使用free命令
top命令
top 命令运行时默认是按照 CPU 利用率进行排序的,如果要按照内存排序,该怎么操作呢?两种方法,一种直接按 “M”(相应的按 “P” 是 CPU),另外一种是在键入 top 之后,按下 “F”,然后选择要排序的字段,再按下 “s” 确认即可。
缓存和缓冲区的区别
Buffer的核心作用是用来缓冲,缓和冲击。比如你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两件事嘛。用个buffer暂存起来,变成每10秒写一次硬盘,对系统的冲击就很小,写入效率高了,日子过得爽了。极大缓和了冲击。
Cache的核心作用是加快取用的速度。比如你一个很复杂的计算做完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了。加快了数据取用的速度。
简单来说就是buffer偏重于写,而cache偏重于读。
ps:有时候大家要好好理解这些专有名词字面上的意思,对理解这些概念有好处,缓冲:缓解冲击,缓存:临时存储
参考
Linux探秘之用户态与内核态
一文搞懂 Linux network namespace
一文总结 Linux 虚拟网络设备 eth, tap/tun, veth-pair
虚拟机网络模型详解,看这篇就够了(图文并茂)
Linux 虚拟网络设备 veth-pair 详解,看这一篇就够了
缓冲区(buffer)与缓存(cache)