虚拟化使得在一台物理的服务器上可以跑多台虚拟机,虚拟机共享物理机的 CPU、内存、IO 硬件资源,但逻辑上虚拟机之间是相互隔离的。
物理机我们一般称为宿主机(Host),宿主机上面的虚拟机称为客户机(Guest)。Hypervisor是统载虚拟机的全称,像kvm、xen、vmware、hyper-v都属于Hypervisor。
Host通过Hypervisor将自己的硬件资源虚拟化,并提供给 Guest 使用。
虚拟化分为两种:
1、全虚拟化
Hypervisor直接安装在物理机上,然后Hypervisor上运行多个虚拟机。xen、vmware、ESXI都属于全虚拟化!
2、半虚拟化
物理机器上先安装操作系统,然后再物理机上的操作系统上再运行虚拟机。
KVM、VirtualBox 和 VMWare Workstation 都属于半虚拟化。
3、两种虚拟化的对比
a、全虚拟化一般对硬件虚拟化功能进行了特别优化,性能比半虚拟化好。
b、半虚拟化比较灵活,支持虚拟机嵌套。
本篇主要介绍比较主流的半虚拟化的Hypervisor--KVM
KVM
KVM 全称是 Kernel-Based Virtual Machine。也就是说 KVM 是基于 Linux 内核实现的。
KVM有一个内核模块叫 kvm.ko,只用于管理虚拟 CPU 和内存。
那 IO 的虚拟化,比如存储和网络设备由谁实现呢?
这个就交给 Linux 内核和Qemu来实现。
作为一个 Hypervisor,KVM 本身只关注虚拟机调度和内存管理这两个方面。IO 外设备的任务交给 Linux 内核和 Qemu。
Libvirt
Libvirt就是 KVM的管理工具,除了能管理 KVM 这种 Hypervisor,还能管理 Xen,VirtualBox 等。
Libvirt 包含 3 个东西:后台 daemon 程序 libvirtd、API 库和命令行工具 virsh。
1、libvirtd是服务程序,接收和处理API 请求;
2、API 库使得其他人可以开发基于Libvirt 的高级工具,比如 virt-manager,这是个图形化的 KVM 管理工具。
3、virsh 是经常要用的 KVM 命令行工具。
CPU虚拟化
查看系统是否开启虚拟化:egrep -o ‘(vmx|svm)‘ /proc/cpuinfo
一个 KVM 虚机在宿主机中其实是一个 qemu-kvm 进程,与其他 Linux 进程一样被调度。
虚机中的每一个虚拟 vCPU 则对应 qemu-kvm 进程中的一个线程。看下图
在这个例子中,宿主机有两个物理 CPU,上面起了两个虚机 VM1 和 VM2。
VM1 有两个 vCPU,VM2 有 4 个 vCPU。可以看到 VM1 和VM2 分别有两个和 4 个线程在两个物理 CPU 上调度。
这里也演示了另一个知识点,即虚机的 vCPU 总数可以超过物理 CPU 数量,这个叫 CPU overcommit(超配)。
但前提是在同一时刻,不是所有的虚机都满负荷运行。当然,如果每个虚机都很忙,反而会影响整体性能。
内存虚拟化
KVM 通过内存虚拟化共享物理系统内存,动态分配给虚拟机。
为了在一台机器上运行多个虚拟机,KVM 需要实现 VA(虚拟内存) -> PA(物理内存) -> MA(机器内存)直接的地址转换。
虚机 OS 控制虚拟地址到客户内存物理地址的映射(VA -> PA),但是虚机 OS 不能直接访问实际机器内存,因此 KVM 需要负责映射客户物理内存到实际机器内存 (PA -> MA)。
存储虚拟化
KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的。
Storage Pool 是宿主机上可以看到的一片存储空间。
Volume 是在 Storage Pool 中划分出的一块空间,宿主机将 Volume 分配给虚拟机,Volume 在虚拟机中看到的就是一块硬盘。
Storage Pool种类:
1、本地目录或远程挂载点目录(比如nfs、Glusterfs)
2、宿主机上 VG 中的 LV,无MBR引导记录,只能做数据盘。这种情况下宿主机上的 VG 就是一个 Storage Pool,VG 中的LV 就是 Volume,LV 的优点是有较好的性能;
不足的地方是管理和移动性方面不如镜像文件,而且不能通过网络远程使用。
3、iSCSI,Ceph 等多种类型。
以lvm为例查看及添加Storage Pool:
创建了一个 Storage Pool 的定义文件/etc/libvirt/storage/HostVG.xml,内容为
virsh pool-list –all
virsh pool-define /etc/libvirt/storage/HostVG.xml
virsh pool-start HostVG
Volume 文件格式:
1、raw,默认格式,即原始磁盘镜像格式,移植性好,性能好,但大小固定,不能节省磁盘空间,不支持快照。
2、qcow2,cow 表示 copy on write,能够节省磁盘空间,支持 AES 加密,支持 zlib 压缩,支持多快照,功能很多。
3、vmdk 是 VMWare 的虚拟磁盘格式,VMWare 虚机可以直接在 KVM上 运行。
网络虚拟化
Linux Bridge:
Linux Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备,其功能可以简单的理解为是一个二层交换机或者 Hub。
virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。virbr0 默认分配了一个IP 192.168.122.1。
brctl show可以查看的到,配置文件位于/etc/libvirt/qemu/networks/default.xml
初始模板位于/usr/share/libvirt/networks/default.xml
virbr0 使用 dnsmasq 提供 DHCP 服务,可以在宿主机中查看该进程信息。
ps -elf|grep dnsmasq
VLAN
VLAN 表示Virtual Local Area Network,一个带有 VLAN 功能的switch 能够将自己的端口划分出多个 LAN。一个 LAN 表示一个广播域。VLAN 将一个交换机分成了多个交换机,限制了广播的范围。VLAN 的隔离是二层上的隔离,A 和 B 无法相互访问指的是二层广播包(比如 arp)无法跨越 VLAN 的边界。但在三层上(比如IP)是可以通过路由器让 A 和 B 互通的。
通常交换机的端口有两种配置模式: Access 和 Trunk
Access 口
这些端口被打上了 VLAN 的标签,表明该端口属于哪个 VLAN。
不同 VLAN 用 VLAN ID 来区分,VLAN ID 的 范围是 1-4096。
Access 口都是直接与计算机网卡相连的,这样从该网卡出来的数据包流入 Access 口后就被打上了所在 VLAN 的标签。
Access 口只能属于一个 VLAN。
Trunk 口
假设有两个交换机 A 和 B。
A 上有 VLAN1(红)、VLAN2(黄)、VLAN3(蓝);B 上也有 VLAN1、2、3
那如何让 AB 上相同 VLAN 之间能够通信呢?
办法是将 A 和 B 连起来,而且连接 A 和 B 的端口要允许 VLAN1、2、3 三个 VLAN 的数据都能够通过。这样的端口就是Trunk口了。
VLAN1、2、3 的数据包在通过 Trunk 口到达对方交换机的过程中始终带着自己的 VLAN 标签。
eth0 是宿主机上的物理网卡,有一个命名为 eth0.10 的子设备与之相连。
eth0.10 就是 VLAN 设备了,其 VLAN ID 就是 VLAN 10
eth0.10 挂在命名为 brvlan10 的 LinuxBridge 上,虚机 VM1 的虚拟网卡 vent0 也挂在 brvlan10 上。
这样的配置其效果就是:
宿主机用软件实现了一个交换机(当然是虚拟的),上面定义了一个 VLAN10。
eth0.10,brvlan10 和 vnet0 都分别接到 VLAN10 的 Access口上。而eth0 就是一个 Trunk 口。
VM1 通过 vnet0 发出来的数据包会被打上 VLAN10的标签。
eth0.10 的作用是:定义了 VLAN10
brvlan10 的作用是:Bridge 上的其他网络设备自动加入到 VLAN10 中。
KVM 的网络虚拟化总结:
1、物理交换机存在多个 VLAN,每个 VLAN拥有多个端口。
同一 VLAN 端口之间可以交换转发,不同 VLAN 端口之间隔离。
所以交换机其包含两层功能:交换与隔离。
2、Linux 的 VLAN 设备实现的是隔离功能,但没有交换功能。
一个 VLAN 母设备(比如 eth0)不能拥有两个相同 ID 的VLAN 子设备,因此也就不可能出现数据交换情况。
3、Linux Bridge 专门实现交换功能。
将同一 VLAN 的子设备都挂载到一个 Bridge 上,设备之间就可以交换数据了。
内容源于网络,整理!