OpenStack学习预备知识-2

KVM虚拟化原理

KVM 的虚拟化是需要 CPU 硬件支持的

root@ubuntu:~# egrep -o '(vmx|svm)'  /proc/cpuinfo
vmx

一个 KVM 虚机在宿主机中其实是一个 qemu-kvm 进程,与其他 Linux 进程一样被调度

CPU虚拟化

虚机中的每一个虚拟 vCPU 则对应 qemu-kvm 进程中的一个线程

VM1 有两个 vCPU,VM2 有 4 个 vCPU。 VM1 和 VM2 分别有两个和 4 个线程在两个物理 CPU 上调度。

虚机的 vCPU 总数可以超过物理 CPU 数量,这个叫 CPU overcommit(超配)。 KVM 允许 overcommit

这个特性使得虚机能够充分利用宿主机的 CPU 资源,但前提是在同一时刻,不是所有的虚机都满负荷运行。

内存虚拟化

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

KVM 将宿主机目录 /var/lib/libvirt/images/ 作为默认的 Storage Pool。

该目录下面的一个文件就是一个 Volume。虚拟机每加一个磁盘, /var/lib/libvirt/images/ 下就多加一个Volume

KVM 所有可以使用的 Storage Pool 都定义在宿主机的 /etc/libvirt/storage 目录下,每个 Pool 一个 xml 文件,默认有一个 default.xml,其内容如下:

LVM 类型的 Storage Pool

不仅一个文件可以分配给客户机作为虚拟磁盘,宿主机上 VG (Volume Group)中的 LV (Logical Volume)也可以作为虚拟磁盘分配给虚拟机使用。不过,LV 由于没有磁盘的 MBR 引导记录,不能作为虚拟机的启动盘,只能作为数据盘使用。这种配置下,宿主机上的 VG 就是一个 Storage Pool,VG 中的 LV 就是 Volume。

KVM 还支持 iSCSI,Ceph 等多种类型的 Storage Pool,这里就不一一介绍了,最常用的就是目录类型,其他类型可以参考文档 http://libvirt.org/storage.html

网络虚拟化

Linux Bridge 基本概念

宿主机有 1 块与外网连接的物理网卡 ens33,上面跑了 1 个虚机 VM1,现在有个问题是:如何让VM1 能够访问外网?

两种方案

  1. 将物理网卡ens33直接分配给VM1,但随之带来的问题很多: 宿主机就没有网卡,无法访问了;新的虚机,比如 VM2 也没有网卡。 下面看推荐的方案
  2. 给 VM1 分配一个虚拟网卡 vnet0,通过 Linux Bridge br0 将 ens33和 vnet0 连接起来,如下图所示

Linux Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备,其功能大家可以简单的理解为是一个二层交换机或者 Hub。多个网络设备可以连接到同一个 Linux Bridge,当某个设备收到数据包时,Linux Bridge 会将数据转发给其他设备。

在上面这个例子中,当有数据到达ens33 时,br0 会将数据转发给 vnet0,这样 VM1 就能接收到来自外网的数据; 反过来,VM1 发送数据给 vnet0,br0 也会将数据转发到 ens33,从而实现了 VM1 与外网的通信。

增加一个虚机 VM2

VM2 的虚拟网卡 vnet1 也连接到了ens33 上。现在 VM1 和 VM2 之间可以通信,同时 VM1 和 VM2 也都可以与外网通信。

配置 Linux Bridge br0

对 /etc/network/interfaces 的修改

有两点需要注意:

  1. 之前宿主机的 IP 是通过 dhcp 配置在 ens33 上的;创建 Linux Bridge 之后,IP 就必须放到 br0 上了
  2. 在 br0 的配置信息中请注意最后一行 “bridge_ports ens33”,其作用就是将 ens33挂到 br0 上

重启宿主机,查看 IP 配置,可以看到 IP 已经放到 br0 上了

用 brctl show 查看当前 Linux Bridge 的配置,ens33 已经挂到 br0 上了

而且 **virbr0 **上已经配置了 IP 地址 192.168.122.1

设置KVM1、KVM2 Network source 设置为br0

设置后

brctl show 告诉我们 br0 下面添加了一个 vnet1设备,通过 virsh 确认这就是VM1的虚拟网卡

KVM1、KVM2即可通过dhcp获取IP,通过br0和外部互通。

virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟网卡提供 DHCP 服务。

网卡选择default,vnet0 已经挂在了 virbr0 上,这个就是NAT模式

使用 NAT 的虚机 VM1 可以访问外网,但外网无法直接访问 VM1。 这个与使用 br0 不一样,在 br0 的情况下,VM1 通过自己的 IP 直接与外网通信,不会经过 NAT 地址转换。

VLAN概念

LAN 表示 Local Area Network,本地局域网,通常使用 Hub 和 Switch 来连接 LAN 中的计算机,一般来说,两台计算机连入同一个 Hub 或者 Switch 时,它们就在同一个 LAN 中。一个 LAN 表示一个广播域。 其含义是:LAN 中的所有成员都会收到任意一个成员发出的广播包。

VLAN 表示 Virtual LAN,一个带有 VLAN 功能的switch 能够将自己的端口划分出多个 LAN。计算机发出的广播包可以被同一个 LAN 中其他计算机收到,但位于其他 LAN 的计算机则无法收到。 简单地说,VLAN 将一个交换机分成了多个交换机,限制了广播的范围,在二层将计算机隔离到不同的 VLAN 中。一种方法是使用两个交换机,A 和 B 分别接到一个交换机。 另一种方法是使用一个带 VLAN 功能的交换机,将 A 和 B 的机器分别放到不同的 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 标签。

配置VLAN

逻辑图

编辑 /etc/network/interfaces,配置 ens33.10、brvlan10、ens33.20 和 brvlan20

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto ens33
iface ens33 inet dhcp


auto ens33.10
iface ens33.10 inet manual
  vlan-raw-device ens33

auto brvlan10
iface brvlan10 inet manual
  bridge_stp off
  bridge_waitport 0
  bridge_fd 0
  bridge_ports ens33.10

auto ens33.20
iface ens33.20 inet manual
  vlan-raw-device ens33

auto brvlan20
iface brvlan20 inet manual
  bridge_stp off
  bridge_waitport 0
  bridge_fd 0
  bridge_ports ens33.20

把VM1、VM2网卡分别选择ens33.10,ens33.20,启动VM1、VM2

下图可以看到,/etc/network/interfaces配置了ens33.10挂载到了brvlan10,ens33.20挂载到了brvlan20。图像化配置VM1的网卡vnet0挂载到了brvlan10,VM2的网卡vnet1挂载到了brvlan20

验证 VLAN10 和 VLAN20 之间的隔离,我们为 VM1 和 VM2 配置同一网段的 IP。

配置VM1的IP

配置VM2的IP

结果显然是ping不通的

1、VM2 向 VM1 发 Ping 包之前,需要知道 VM1 的 IP 192.168.1.10 所对应的 MAC 地址。VM2 会在网络上广播 ARP 包,其作用就是问 “谁知道 192.168.1.10 的 MAC 地址是多少?”

2、ARP 是二层协议,VLAN 的隔离作用使得 ARP 只能在 VLAN20 范围内广播,只有 brvlan20 和 ens33.20 能收到,VLAN10 里的设备是收不到的。VM1 无法应答 VM2 发出的ARP包。

3、VM2 拿不到 VM1 vnet0 的 MAC 地址,也就 Ping 不到 VM1。

Linux Bridge + VLAN = 虚拟交换机

  1. 物理交换机存在多个 VLAN,每个 VLAN 拥有多个端口。 同一 VLAN 端口之间可以交换转发,不同 VLAN 端口之间隔离。所以交换机其包含两层功能:交换与隔离。

  2. Linux 的 VLAN 设备实现的是隔离功能,但没有交换功能。一个 VLAN 母设备(比如 ens33),不能拥有两个相同 ID 的 VLAN 子设备,因此也就不可能出现数据交换情况。

  3. Linux Bridge 专门实现交换功能。

    将同一 VLAN 的子设备都挂载到一个 Bridge 上,设备之间就可以交换数据了。总结起来,Linux Bridge 加 VLAN 在功能层面完整模拟现实世界里的二层交换机。ens33 相当于虚拟交换机上的 trunk 口,允许 vlan10 和 vlan20 的数据通过

    ens33.10,vent0 和 brvlan10 都可以看成 vlan10 的 access 口

    ens33.20,vent1 和 brvlan20 都可以看成 vlan20 的 access 口

posted @ 2024-03-30 13:08  九天揽月丶  阅读(4)  评论(0编辑  收藏  举报