[KVM] 网络虚拟化原理

KVM 网络的配置有一下几种

  1. 用户模式,即创建 vm 时默认的网络模式
  2. Bridge 模式
  3. NAT 模式
  4. VT-d 技术

Bridge 模式

bridge 是二层转发设备,主要功能是多个 LAN 间的的数据帧转发,即包括 MAC 学习,生成树协议等。
Qemu vm 启动时的网桥配置,是使用 tap 设备完成的,如下命令:

qemu-system-x86_64 
-netdev tap,id=host-net0,ifname=vm1eth0,script=/etc/ifup,downscript=/etc/ifdown 
-device virtio-net-pci,netdev=host-net0,id=host-net0,mac=0a:e8:4f:c5:6a:16,bus=pci.0,addr=0x7

// 解释:
// -ifname: Host 上呈现的 tap 虚拟设备的名称
// -script: Host 在启动 GuestOS 时默认执行脚本,一般是将 tap (vm1eth0) 加入到 bridge 中
// -downscript: Host 在关闭 GuestOS 时默认执行脚本,一般是将 tap (vm1eth0) 从 bridge 中移除

tap 原理:

tap 模拟了二层网络设备,即处理 MAC 学习,数据帧转发。
User Space: 实现了网络数据包在内核态与用户态之间的传输;
Kernel Space: 模拟了一个真实的网络设备。
简单理解:在 User Space 会打开字符设备 /dev/net/tun ,来监听是否可读、可写,来实现数据帧在 Kernel Space 和 User Space 之间的数据传输。
即包含两部分内容,一部分是字符驱动设备,通过读写 /dev/net/tun 实现 Kernel、User Space 数据传输;一部分是网路驱动设备,即将 /dev/net/tun 中读取到的网络数据交由内核协议栈处理,或者将协议栈转发的网络数据,写入到 /dev/net/tun 中。

前端网络流入流程

  1. 网络流量从 Physical 层接收,到达 Bridge br0
  2. 根据 MAC 地址转发规则,br0 将数据包转发给 vm1eth0,数据由 tap 网路驱动设备接收
  3. qemu 线程监听到打开的 fd(/dev/net/run) 可读,则通过 read 操作,字符设备驱动将网络数据从 Kernel Space 拷贝到 User Space
    网络数据的流出流程和上面流程相反。

GuestOS 网络数据的接收流程:
qemu 监听到打开的 fd 可读,并将数据读取到 User Space 之后,由于 GuestOS 的物理内存其实是 qemu 进程的虚拟内存,所以qemu 进程将网络数据写入到 GuestOS 对应 qemu 进程的虚拟内存的位置,即实现了,网络数据流传送到了 GuestOS 的物理内存中,然后 qemu 使 GuestOS 触发中断,即类似网络包到达操作系统的流程。

GuestOS 网络数据的发送流程:
当 GuestOS 准备好数据包,要发送时,IO 操作会触发 VM Exit,进入到 Host OS 中的 kvm 中,KVM 会想这个异常转发给用户空间的 Qemu 来处理。Qemu 进程检测到是网络请求后,会从 Qemu 的虚拟内存空间(即 GuestOS 的物理内存空间),读取出网络数据包,之后的流程和 前端网络流程 相反。

Bridge 模式实验

实验准备

  • 安装 qemu, bridge-utils
  • 制作 debian-8.7.1-adm64.img 镜像
// 创建 bridge br0
brctl addbr br0
brctl addif br0 eth1

// eth1 三层的 IP 已经无效了
ip addr flush dev eth1
  
// 设置 br0 IP 地址
ip addr add 192.168.98.100/24 dev br0
ip link set br0 up

cat /data/vm/ifup
> #!/bin/sh
> br='br0'
> /sbin/ifconfig $1 0.0.0.0 up
> brctl addif $br $1

cat /data/vm/ifdown
> #!/bin/sh
> br='br0'
> /sbin/ifconfig $1 0.0.0.0 down
> brctl delif $br $1

// 可执行
chmod +x ifup ifdown

在 Host 查看 br0 设备

ip addr show br0
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 4a:89:6f:b8:a8:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.98.100/24 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:74ff:feb6:948d/64 scope link 
       valid_lft forever preferred_lft forever


执行命令

qemu-system-x86_64 -m 512M -smp 1 
-drive file=debian-8.7.1-amd64.img,if=none,cache=writeback,id=-disk0,,media=disk,format=qcow2 
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=system-disk0,id=disk0,bootindex=1 
-netdev tap,id=net0,ifname=vm1eth0,script=/data/vm/ifup,downscript=/data/vm/ifdown 
-device virtio-net-pci,netdev=net0,id=net0,mac=0a:e8:4f:c5:6a:16,bus=pci.0,addr=0x7 
-nodefconfig -nodefaults -display vnc=:1 -vga cirrus

在 Host 上可以看到 vm1eth0 tap 设备

ip addr show vm1eth0
8: vm1eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN group default qlen 500
    link/ether 4a:89:6f:b8:a8:b5 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::4889:6fff:feb8:a8b5/64 scope link 
       valid_lft forever preferred_lft forever

在 GuestOS 中可以看到 eth0 设备


 
GuestOS_eth0.png

并在 GuestOS 中 ping 同网段的 IP 192.168.98.3 时,已通


 


转自:https://www.jianshu.com/p/93c226a4c780
原文地址:https://www.cnblogs.com/pipci/p/13021587.html