Ubuntu 20.04实战:KVM虚拟机与Bridge网桥配置全攻略

1. 环境准备与KVM安装:从零开始的基石

大家好,我是老张,一个在虚拟化领域折腾了十多年的老运维。今天咱们不聊那些高大上的云原生,就踏踏实实地,在一台装着Ubuntu 20.04的笔记本或者服务器上,从零开始,手把手搭建一个能直接连上你家路由器、和物理机平起平坐的KVM虚拟机。这个过程我走过无数遍,也踩过不少坑,今天就把最稳、最有效的一套流程分享给你,保证你跟着做,一次就能成功。

首先,咱们得搞清楚我们要做什么。简单说,KVM是Linux内核自带的虚拟化模块,性能损耗极低,特别适合在个人开发机或者内部服务器上跑多个隔离的系统环境。而Bridge网桥,你可以把它想象成一个虚拟的“网络交换机”。物理机的网线插在这个“交换机”上,虚拟机也把网线(虚拟的)插在这个“交换机”上,这样它们就处在同一个局域网里了,虚拟机就能获得一个和你物理机同网段的真实IP,能直接上网,也能被同局域网的其他设备访问。这个场景对于需要做网络测试、部署内网服务或者搭建开发环境的朋友来说,是刚需。

动手之前,先看看你的“家伙事儿”够不够。我用的是一台老笔记本,i5-6300HQ的CPU,16G内存,500G固态,系统是Ubuntu 20.04.3 LTS。你的配置比这个好,那肯定没问题;比这个差一点,跑一两个轻量级虚拟机也完全够用。最关键的一步,是检查你的CPU支不支持虚拟化技术。这就像盖房子要先看地基稳不稳。打开终端,输入下面这条命令:

grep -Eoc '(vmx|svm)' /proc/cpuinfo

如果输出数字大于0,比如显示“8”,那就恭喜你,你的Intel(vmx)或AMD(svm)CPU硬件虚拟化支持是开启的。如果输出是0,那你可能需要进电脑的BIOS/UEFI设置里,找到类似“Intel Virtualization Technology”或“AMD-V”的选项,把它打开。这一步千万别跳过,否则后续所有操作都是白费力气。

确认硬件支持后,咱们来安装KVM全家桶。Ubuntu的apt包管理器让这一切变得非常简单。一条命令就能搞定大部分事情:

sudo apt update && sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager -y

我来给你掰扯一下这几个包都是干嘛的,理解了才不容易晕。qemu-kvm是底层干活的“引擎”,负责模拟CPU、内存这些硬件。libvirt-daemon-systemlibvirt-clients是一套管理工具,你可以把libvirt理解成一个“虚拟机管家”,我们后面创建、启动、管理虚拟机,主要都通过它提供的命令(比如virsh)或者图形界面(virt-manager)来进行。bridge-utils包含了配置网桥需要的工具,虽然我们主要用Netplan,但有它更保险。virtinst提供了命令行创建虚拟机的工具(比如virt-install),virt-manager则是一个图形化管理界面,如果你在带桌面的Ubuntu上操作,装一个会很方便;如果是纯命令行服务器,可以不装。

安装完成后,检查一下libvirt这个“管家”的服务跑起来没有:

sudo systemctl is-active libvirtd

看到输出“active”就对了。为了让你的普通用户账号也能管理虚拟机,不用每次都加sudo,需要把当前用户加到相关的用户组里。用你的用户名替换下面的USER

sudo usermod -aG libvirt USER sudo usermod -aG kvm USER

注意:执行完上面这条命令后,你需要完全退出当前终端会话,并重新登录,或者重启系统,这个组权限才会生效。很多朋友做到后面发现权限不足,问题就出在这步没生效。

2. 核心难点:Bridge网桥配置详解与避坑指南

好了,基础环境搭好了,接下来就是整个过程中最关键、也最容易出错的环节——配置Bridge网桥。很多教程在这里讲得不清不楚,导致大家配置完上不了网。咱们今天把它彻底讲透。

首先,我们要理解KVM安装后默认的网络情况。安装完libvirt后,它会自动创建一个叫default的虚拟网络,通常对应一个叫virbr0的网桥。这个默认网络用的是NAT模式,虚拟机可以通过它上网,但外部网络无法直接访问虚拟机,就像你家路由器给手机分配的Wi-Fi地址,外面是直接连不进来的。这不符合我们“虚拟机获得真实局域网IP”的需求,所以第一步,就是清理掉这个默认网络。

sudo virsh net-destroy default sudo virsh net-undefine default

执行完,用ip link命令看看,那个virbr0virbr0-nic接口应该消失了。如果还在,可以尝试手动删除:

sudo ip link delete virbr0 sudo ip link delete virbr0-nic

清理完战场,现在开始搭建我们自己的桥接网络。这里我强烈推荐使用Ubuntu 20.04默认的Netplan来配置,它比老旧的/etc/network/interfaces方式更现代、更清晰。Netplan的配置文件通常在/etc/netplan/目录下,文件名可能是00-installer-config.yaml01-netcfg.yaml等。在修改之前,务必备份原文件

我们先创建一个内核参数配置文件,目的是让网桥能正常处理网络数据包。新建文件/etc/sysctl.d/bridge.conf

sudo vim /etc/sysctl.d/bridge.conf

写入以下三行内容:

net.bridge.bridge-nf-call-ip6tables=0 net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-arptables=0

这三行的作用是让经过网桥的数据包绕过iptables等防火墙的过滤规则,避免桥接网络出现奇怪的通断问题。为了让这个配置在系统启动、加载br_netfilter内核模块时自动生效,我们再创建一个udev规则文件:

sudo vim /etc/udev/rules.d/99-bridge.rules

写入以下内容(注意是一行):

ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"

接下来就是重头戏:配置Netplan。首先,你需要知道你物理网卡的名字。在终端输入ip link,你会看到类似eno1(有线网卡)、wlo1(无线网卡)这样的名字。非常重要:桥接必须使用有线网卡(如eno1),无线网卡通常不支持桥接模式。找到你的有线网卡名,记下来。

现在,编辑Netplan的主配置文件:

sudo vim /etc/netplan/00-installer-config.yaml

假设你的有线网卡是eno1,你家路由器的局域网网段是192.168.0.0/24,网关是192.168.0.1,你想给这台Ubuntu主机(宿主机)在桥接网络上分配的固定IP是192.168.0.100。那么配置文件内容如下:

network: version: 2 ethernets: eno1: dhcp4: no dhcp6: no bridges: br0: interfaces: [eno1] addresses: [192.168.0.100/24] gateway4: 192.168.0.1 mtu: 1500 nameservers: addresses: [8.8.8.8, 8.8.4.4] parameters: stp: true forward-delay: 4 dhcp4: no dhcp6: no

我来解释一下这个配置的要点:

  1. ethernets部分声明了物理网卡eno1,并关闭了它的DHCP,因为它将作为桥接设备br0的一个端口,IP地址将由桥接设备br0来持有。
  2. bridges部分定义了我们的桥br0interfaces: [eno1]表示把物理网卡eno1“绑”到桥br0上。
  3. addresses设置的是宿主机br0桥接网络上的IP地址和子网掩码。这个IP必须是你局域网内空闲的、合法的IP。
  4. gateway4nameservers设置网关和DNS,确保宿主机本身能通过这个桥上网。
  5. parameters下的stp(生成树协议)建议开启,防止网络环路,forward-delay是端口转发延迟时间。

配置完成后,应用它:

sudo netplan apply

这个命令执行时可能会让网络中断几秒钟,属于正常现象。执行成功后,再用ip linkip addr show br0命令查看,你应该能看到一个名为br0的网桥,并且eno1master显示为br0br0上也拥有了你配置的IP地址192.168.0.100。此时,你的宿主机应该已经通过br0桥接网络正常连接互联网了,可以ping一下百度试试。

3. 将Bridge网桥接入KVM并创建虚拟机

网桥在宿主机层面已经建好了,但KVM这个“管家”还不知道怎么用它。我们需要告诉libvirt:“嘿,我这儿有个现成的桥叫br0,以后创建虚拟机时,可以把它连接到这个桥上。” 这一步是通过定义一个libvirt网络来实现的。

创建一个XML格式的配置文件,比如叫host-bridge.xml

vim host-bridge.xml

内容非常简单:

<network> <name>host-bridge</name> <forward mode="bridge"/> <bridge name="br0"/> </network>

这个文件定义了一个名为host-bridge的libvirt网络,其转发模式是“桥接”,并且桥接到我们宿主机上已经存在的br0网桥。然后用libvirt的命令将其定义并启动:

sudo virsh net-define host-bridge.xml sudo virsh net-start host-bridge sudo virsh net-autostart host-bridge

net-autostart命令是设置这个网络在libvirt服务启动时自动激活。执行完后,用virsh net-list --all检查一下,应该能看到host-bridge网络是active状态,并且Autostartyes

万事俱备,只欠虚拟机!现在我们可以用virt-install命令来创建一台虚拟机了。这里我以安装CentOS 7为例。你需要提前下载好CentOS 7的ISO镜像文件,放到一个路径下,比如/var/lib/libvirt/images/。同时,想好虚拟机磁盘文件要放在哪里。

下面是一条比较完整的virt-install命令示例,我把它拆开讲解每个参数:

sudo virt-install \ --name=my_centos7 \ --ram=4096 \ --vcpus=2 \ --virt-type=kvm \ --os-type=linux \ --os-variant=centos7.0 \ --network network=host-bridge,model=virtio \ --graphics vnc,listen=0.0.0.0,port=5901 \ --noautoconsole \ --accelerate \ --cdrom=/var/lib/libvirt/images/CentOS-7-x86_64-Minimal-2003.iso \ --disk path=/var/lib/libvirt/images/my_centos7.qcow2,size=40,format=qcow2,bus=virtio,cache=writeback
  • --name: 给你的虚拟机起个名字。
  • --ram--vcpus: 分配内存(MB)和CPU核心数。根据你的宿主机资源量力而行。
  • --virt-type=kvm: 指定使用KVM加速。
  • --os-variant: 指定操作系统类型,这有助于优化虚拟硬件。可以通过osinfo-query os命令查看支持的系统列表。
  • --network:这是关键!network=host-bridge指定使用我们刚才创建的桥接网络。model=virtio指定使用半虚拟化网卡驱动,性能最好。
  • --graphics: 设置图形控制台。这里用VNC,监听所有IP(0.0.0.0),端口是5901。你可以通过VNC客户端连接宿主机IP:5901来看到虚拟机的安装界面。如果宿主机有桌面环境,也可以直接用--graphics spice
  • --cdrom: 指定安装ISO镜像的路径。
  • --disk: 指定虚拟磁盘文件路径、大小(GB)、格式(qcow2动态分配,节省空间)、总线类型(virtio性能最佳)和缓存模式(writeback性能好,但有一定风险,生产环境慎用)。

命令执行后,会自动启动虚拟机并弹出VNC窗口(如果环境支持),或者提示你通过VNC连接。接下来就是正常的操作系统安装过程了。

4. 虚拟机内部网络配置与连通性终极测试

虚拟机安装好系统启动后,我们还需要在虚拟机内部进行网络配置,才能让它通过我们搭建的桥接网络上网。因为我们的桥br0所在的网络是192.168.0.0/24,网关是192.168.0.1,所以我们需要给虚拟机也配置一个同网段的静态IP。

以CentOS 7为例,网络配置文件在/etc/sysconfig/network-scripts/目录下,网卡名可能是eth0ens3(取决于系统版本和驱动)。我们编辑对应的配置文件,比如ifcfg-eth0

vi /etc/sysconfig/network-scripts/ifcfg-eth0

将其内容修改为类似下面这样(请根据你的实际网络环境调整):

TYPE=Ethernet BOOTPROTO=static NAME=eth0 DEVICE=eth0 ONBOOT=yes IPADDR=192.168.0.101 NETMASK=255.255.255.0 GATEWAY=192.168.0.1 DNS1=114.114.114.114 DNS2=8.8.8.8

关键点

  • BOOTPROTO要改成static(静态)。
  • ONBOOT要改成yes(开机启动)。
  • IPADDR必须设置一个和宿主机br0192.168.0.100)在同一网段(192.168.0.0/24)且未被其他设备占用的IP,比如192.168.0.101
  • GATEWAY和宿主机br0的网关一致,即192.168.0.1
  • DNS可以设置为你常用的DNS服务器。

保存退出后,重启网络服务:

systemctl restart network

对于Ubuntu 20.04的虚拟机,配置方式不同,需要使用Netplan。假设网卡名为ens3,则编辑/etc/netplan/00-installer-config.yaml

network: version: 2 ethernets: ens3: addresses: - 192.168.0.101/24 gateway4: 192.168.0.1 nameservers: addresses: [114.114.114.114, 8.8.8.8]

然后执行sudo netplan apply

配置完成后,就是激动人心的测试环节了。在虚拟机内部,依次执行以下测试:

  1. 测试虚拟机到网关的连通性ping 192.168.0.1。成功说明虚拟机到路由器通了。
  2. 测试虚拟机到外网的连通性ping 114.114.114.114。成功说明DNS解析前的纯IP访问外网通了。
  3. 测试虚拟机DNS解析和公网访问ping www.baidu.com。成功说明DNS工作正常,可以访问公网域名。
  4. 测试宿主机到虚拟机的连通性:在宿主机上,ping 192.168.0.101。成功说明宿主机和虚拟机在二层网络是互通的。
  5. 测试局域网其他设备到虚拟机的连通性:用你局域网内的另一台电脑或手机,ping 192.168.0.101。如果成功,那真是太棒了!这说明你的虚拟机已经完全融入了你的家庭或公司局域网,就像一台真实的物理机器一样。

如果以上测试全部通过,那么恭喜你,一个基于Ubuntu 20.04 KVM和Bridge网桥的、具备完整网络能力的虚拟机环境就成功搭建完毕了!以后每次宿主机重启,br0网桥和host-bridge网络都会自动启动,你创建的虚拟机也会随着libvirt服务自启动(如果设置了的话),真正做到“一劳永逸”。这套配置我在多台设备和不同网络环境下都反复测试过,只要严格按照步骤,注意我提到的几个关键点(CPU虚拟化、有线网卡、IP网段设置),成功率非常高。遇到问题别慌,回头检查一下每一步的配置和命令输出,网络配置这东西,差一个字母可能效果就完全不同。