KVM 网络的配置有一下几种
- 用户模式,即创建 vm 时默认的网络模式
- Bridge 模式
- NAT 模式
- 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
中。
前端网络流入流程
- 网络流量从 Physical 层接收,到达 Bridge br0
- 根据 MAC 地址转发规则,br0 将数据包转发给 vm1eth0,数据由 tap 网路驱动设备接收
- 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 时,已通
GuestOS_ping.png
网友评论