单机KVM日常运维

KVM架构

KVM:提供 CPU / 内存硬件级虚拟化能力(内核层)

QEMU:模拟各种外设、磁盘、网络,配合 KVM 实现完整虚拟机(用户层)

Libvirt:封装 KVM+QEMU,提供统一 API / 命令行,方便管理、创建、控制虚拟机

KVM部署

操作系统:Ubuntu 20.04.1 LTS (Focal Fossa)

# 查看服务器是否支持KVM,返回值大于0即可
grep -E 'vmx|svm' /proc/cpuinfo|wc -l

# 安装基础包
apt-get install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager osinfo-db-tools osinfo-db

# 启动libvirtd并加入开机自启动
systemctl enable libvirtd --now

# 设置内核参数
# br0 是 Linux 原生网桥 → 走二层转发 → 受 bridge-nf-call-iptables 参数控制
# 当这两个参数为1时:br0 转发的所有数据包(包括 KVM 和 Docker 的流量)都会强制经过 iptables 规则过滤,而你的 iptables 规则仅针对性放行 Docker 或 KVM 流量,极易因规则遗漏 / 顺序问题导致一方流量被拦截;
# 当设置为0时:br0 仅做纯二层网桥转发(类似物理交换机),不再触发 iptables 规则,KVM 虚拟机的流量直接通过 br0 转发,Docker 的流量则走 docker0 网桥 + iptables 端口映射,两者互不干扰。
cat >> /etc/sysctl.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-ip6tables=0
EOF
sysctl -p

# 验证kvm是否可以正常运行,返回KVM acceleration can be used说明正常
kvm-ok

自动设置网卡桥接:virsh iface-bridge eno1 br0命令执行后,会把eno1的网络信息迁移到br0网卡上,把eno1加入到br0的网桥中,建议使用该方式操作。

virsh iface-bridge eno1 br0

手动设置网卡桥接:操作前先备份网卡的配置文件,如果配置错误会断开连接,必须保证配置的br0网卡IP和你的网络可以连通。该步骤不需要执行,仅用于做记录

# 备份配置文件
cp /etc/netplan/01-network-manager-all.yaml /etc/netplan/01-network-manager-all.yaml.bak
# 创建桥接网卡,并吧eno1网卡连接到br0网桥上
cat > /etc/netplan/01-network-manager-all.yaml <<EOF
network:
  ethernets:
    eno1:
      addresses: []
      dhcp4: no
      dhcp6: no
  bridges:
    br0:
      dhcp4: no
      dhcp6: no
      addresses: [192.168.6.136/22]
      gateway4: 192.168.4.1
      nameservers:
        addresses: [114.114.114.114,223.5.5.5]
      interfaces: [eno1]
  version: 2
EOF

查看网桥,网卡信息

# 查看网桥信息,eno1网卡接入br0网桥中
> brctl show 
bridge name     bridge id               STP enabled     interfaces
br0             8000.3cecefab46bc       yes             eno1

# 查看网卡信息,eno1没有IP地址,且MAC地址和br0MAC地址相同
> ifconfig 
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.6.136  netmask 255.255.252.0  broadcast 192.168.7.255
        ether 3c:ec:ef:ab:46:bc  txqueuelen 1000  (Ethernet)
        RX packets 8226194  bytes 3700218410 (3.7 GB)
        RX errors 0  dropped 368575  overruns 0  frame 0
        TX packets 1603790  bytes 1084981132 (1.0 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 3c:ec:ef:ab:46:bc  txqueuelen 1000  (Ethernet)
        RX packets 326368717  bytes 248360725787 (248.3 GB)
        RX errors 2940  dropped 218927  overruns 0  frame 2940
        TX packets 271161440  bytes 275610392685 (275.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

定制镜像

生产环境一般使用定制的qcow2(cow是copy on write)硬盘类型镜像, 支持快照、压缩、加密、动态扩容等,稀疏分配空间,占多少用多少,而raw类型硬盘是预分配空间,无高级功能,读写速度快,性能好。

定制qcow2的步骤:

  1. 新建一个空白 qcow2 格式的磁盘
  2. 用 ISO 镜像正常安装系统,提前准备镜像
  3. 进入系统做模板化优化,如执行初始化脚本
  4. 关机、压缩、得到最终定制 qcow2 模板
# 创建目录,images存储qcow2镜像,disk存储虚拟机磁盘,iso存储操作系统镜像
mkdir -p /opt/ops-kvm/{images,disk,iso}
cd /opt/ops-kvm/images

# 创建200G空白qcow2
qemu-img create -f qcow2 rocky9-custom-template.qcow2 200G

# 安装虚拟机
virt-install \
--name rocky9-install-temp \
--ram 16384 \
--vcpus 8 \
--disk path=/opt/ops-kvm/disk/rocky9-custom-template.qcow2,format=qcow2,bus=virtio \
--cdrom /opt/ops-kvm/iso/Rocky-9.6-x86_64-minimal.iso \
--network bridge=br0,model=virtio \
--graphics vnc,listen=0.0.0.0,port=5920 \
--noautoconsole \
--extra-args="console=ttyS0,115200n8" 

# 使用VNC连接虚拟机,设置网卡为eth0
# VNC连接后,按TAB,添加net.ifnames=0 biosdevname=0参数,设置网卡为eth0
# 执行初始化脚本,该步骤略

# 配置虚拟机eth0网卡信息,建议DHCP获取IP地址,并删除UUID,设置开机自启动
cat > /etc/NetworkManager/system-connections/eth0.nmconnection <<EOF
[connection]
id=eth0
type=ethernet
interface-name=eth0
autoconnect=yes

[ethernet]

[ipv4]
method=auto
#method=manual
#address1=192.168.6.12/22
#gateway=192.168.4.1
#dns=114.114.114.114;8.8.8.8;

[ipv6]
addr-gen-mode=eui64
method=disabled

[proxy]
EOF

# 清空machine-id
echo "" > /etc/machine-id

# 关闭虚拟机
virsh destroy rocky9-install-temp
# 删除虚拟机
virsh undefine rocky9-install-temp
# 对定制的qcow2镜像进行压缩,后面在安装新的虚拟机就可以基于此镜像进行操作
qemu-img convert -c -f qcow2 -O qcow2 rocky9-custom-template.qcow2 rocky9-custom-template-final.qcow2

运行虚机

# 安装名为ops-kvm-01的虚拟机
# 参数说明:
#     --name ops-kvm-01 \  虚拟机名称
#     --memory 16384,maxmemory=32768 \  单位M,当前内存16G,最大支持内存32G
#     --vcpus 8,,maxvcpus=16 \  CPU个数,当前cpu8个,最大支持16个
#     --virt-type kvm \    虚拟化类型
#     --os-type linux \    操作系统类型
#     --os-variant rocky9 \  操作系统版本
#     --import \  将disk导入为操作系统
#     --disk path=/opt/ops-kvm/disk/ops-kvm-01_rocky9.6.qcow2,format=qcow2,bus=virtio \  指定虚拟机的disk
#     --network bridge=br0,model=virtio \  指定桥接网络
#     --graphics vnc,listen=0.0.0.0,port=59181 \  开启VNC
#     --noautoconsole  不自动连接console

# 运行虚拟机
virt-install \
--name ops-kvm-01 \
--memory 16384,maxmemory=32768 \
--vcpus 8,maxvcpus=16 \
--virt-type kvm \
--os-type linux \
--os-variant rocky9 \
--import \
--disk path=/opt/ops-kvm/disk/ops-kvm-01_rocky9.6.qcow2,format=qcow2,bus=virtio \
--network bridge=br0,model=virtio \
--graphics vnc,listen=0.0.0.0,port=59181 \
--noautoconsole

# 如果运行报os-variant错误,说明操作系统中没有要指定的os-variant
# 下载最新版的osinfo-db,并进行导入,然后重新运行虚拟机
wget https://releases.pagure.org/libosinfo/osinfo-db-20251212.tar.xz
osinfo-db-import --system osinfo-db-20251212.tar.xz
osinfo-query os

# 加入开启自启动
virsh autostart ops-kvm-01

常用命令

基础管理

命令

功能说明

实操示例

virsh list

查看虚拟机状态

查看运行中虚机:virsh list

查看所有虚机:virsh list --all

virsh start

启动虚拟机

virsh start centos7-vm

virsh shutdown

正常关机(优雅关闭)

virsh shutdown centos7-vm

virsh destroy

强制断电(粗暴关闭)

virsh destroy centos7-vm

virsh reboot

重启虚拟机

virsh reboot centos7-vm

virsh suspend

挂起虚拟机(暂停运行)

virsh suspend centos7-vm

virsh resume

恢复挂起的虚拟机

virsh resume centos7-vm

virsh domrename

重命名虚拟机

virsh domrename centos7-vm new-centos7-vm(将旧名改为新名)

virsh undefine

删除虚拟机定义(配置)

virsh undefine centos7-vm(仅删配置,保留磁盘镜像)

virsh undefine centos7-vm --remove-all-storage(删配置 + 删除关联磁盘,彻底清理)

virsh domiflist

获取网络接口信息

virsh domiflist ops-master-01

配置管理

命令

功能说明

实操示例

virsh dumpxml

导出 / 备份虚拟机配置

virsh dumpxml centos7-vm > /backup/centos7-vm.xml(备份到指定文件)

virsh define

导入配置文件创建虚拟机

virsh define /backup/centos7-vm.xml(从备份文件恢复配置)

virsh edit

编辑虚拟机配置,自带语法检查(推荐)

virsh edit centos7-vm(自动用默认编辑器打开配置文件,修改后生效)

连接管理

命令

功能说明

实操示例

virsh vncdisplay

查询虚拟机 VNC 端口号

virsh vncdisplay centos7-vm

输出示例::1

(对应端口 5901,VNC 端口规则::N

→ 5900+N)

virsh console

宿主机直连虚拟机终端

virsh console centos7-vm(进入终端)退出方式:按下 Ctrl + ]

补充:配置 console 终端(解决无法进入的问题),若 virsh console 连接后无响应,需在虚拟机内添加内核参数或者在创建虚拟机的时候指定参数:

# 如果在使用iso镜像前,指定了--extra-args="console=ttyS0,115200n8",该步骤就不需要操作了
1. 进入虚拟机(VNC/SSH),添加console内核参数(适配ttyS0串口)
grubby --update-kernel=ALL --args="console=ttyS0,115200n8"

# 2. 如需删除该参数,执行:
grubby --update-kernel=ALL --remove-args="console=ttyS0,115200n8"

# 3. 重启虚拟机生效
reboot

自启管理

配置虚拟机开机自启动

命令

功能说明

实操示例

virsh autostart

开启虚拟机开机自启

virsh autostart centos7-vm

virsh autostart --disable

取消开机自启

virsh autostart --disable centos7-vm

磁盘管理

命令

功能说明

实操示例

qemu-img info

查看虚拟磁盘的格式、实际占用空间、总容量、快照信息等核心属性

qemu-img info /var/lib/libvirt/images/test.qcow2

qemu-img create

1. 不指定 -f默认为 raw格式

2. -f指定格式(常用 qcow2/raw) 容量支持 G/M/K 单位

1. qemu-img create test.raw 10G

2. qemu-img create -f qcow2 test.qcow2 10G

qemu-img resize

1. +5G表示在原有基础上加 5G

2. 15G表示直接调整总容量为 15G 注意:仅支持扩容,raw/qcow2 缩容需谨慎(易丢数据)

1. qemu-img resize test.qcow2 +5G

2. qemu-img resize test.qcow2 15G

qemu-img convert

1. -f指定源文件格式(可省略,工具自动识别)

2. -O指定目标文件格式 常用转换:raw → qcow2(支持快照、稀疏存储)

qemu-img convert -f raw -O qcow2 test.raw test.raw.qcow2

快照管理

kvm的快照是给当前磁盘做一个"只读备份点",后续新数据写在新的增量文件里,不改动原始磁盘,从而实现快速备份 / 回滚。

命令

核心说明

实操示例

virsh snapshot-list

列出虚拟机所有快照,显示名称、创建时间、状态

virsh snapshot-list centos7-vm

virsh snapshot-info

查看指定快照的详细信息(是否当前快照、存储位置、父子关系等)

virsh snapshot-info centos7-vm snap-20260318

virsh snapshot-create-as

仅创建磁盘快照,虚拟机可运行 / 关机,数据存在镜像文件内(内置快照)

virsh snapshot-create-as centos7-vm snap-init "系统初始化完成"

virsh snapshot-revert

恢复到指定快照状态,建议先关机;加 --running

可直接恢复运行状态

virsh snapshot-revert centos7-vm snap-20260318

virsh snapshot-delete

删除内置快照(含数据);外部快照加 --metadata

仅删元数据(保留文件)

virsh snapshot-delete centos7-vm snap-old

virsh snapshot-current

查看虚拟机当前使用的快照(确认是否在目标快照状态)

virsh snapshot-current centos7-vm

网络管理

生产环境中使用桥接网络,可通过如下方式创建桥接网络

命令

核心说明

基础语法

实操示例

virsh iface-bridge

创建网桥并将物理网卡桥接到网桥

virsh iface-bridge <物理网卡名> <网桥名> [--no-stp] [--delay <秒数>]

virsh iface-bridge eth0 br0 --no-stp --delay 2

virsh iface-unbridge

解绑网桥,恢复物理网卡独立工作

virsh iface-unbridge <网桥名>

virsh iface-unbridge br0

桥接网络原理:

  • 所有流量先到 br0,再转发
  • 虚拟机访问外部网络:走 br0 → eno1
  • 外部网络访问虚拟机:eno1 → br0 → 对应 vnet
  • 物理机自身访问网络:br0 → eth0

物理机的网卡eno1相当于是一根连接到外部网络的网线。

维护操作

热更新硬盘

常见维护操作:添加新硬盘,现有硬盘扩容

热添加新硬盘

# 创建硬盘
qemu-img create -f qcow2 /opt/ops-kvm/disk/web01-vdb.qcow2 5G
# 查看当前的target
virsh domblklist web01
# 临时添加,vda默认是系统盘,从vdb开始添加,使用virsh domblklist查看target,指定磁盘类型是qcow2
virsh attach-disk web01 /opt/ops-kvm/disk/web01-vdb.qcow2 vdb --subdriver qcow2
# 永久添加,写到配置文件中
virsh attach-disk web01 /opt/ops-kvm/disk/web01-vdb.qcow2 vdb --subdriver qcow2 --config --live
# 添加磁盘后进入虚拟机格式化,挂载
mkfs.ext4 /dev/vdb
mount /dev/vdb /data
# 卸载硬盘
virsh detach-disk web01 vdb --live --config 

硬盘扩容,包含在线扩容或离线扩容

# 关机扩容,停止虚拟机,给磁盘文件增加空间,对根分区扩容
virsh destroy test-kvm
qemu-img resize test.qcow2 +5G
# 进入虚拟机
dnf install -y cloud-utils-growpart
growpart /dev/vda 2
pvresize /dev/vda2
lvextend -l +100%FREE /dev/mapper/rl-root
xfs_growfs /

# 在线扩容,扩容到220G
virsh blockresize ops-kvm-01 /opt/ops-kvm/disk/ops-kvm-01_rocky9.6.qcow2 220G
growpart /dev/vda 2
pvresize /dev/vda2
lvextend -l +100%FREE /dev/mapper/rl-root
xfs_growfs /

热添加内存

需要设置最大内存,建议一开始就规划好,虚拟机的内存不能超过最大内存设置

# 设置最大内存为8G,--live临时调整,--config永久调整
virsh setmaxmem web04 8192M --live
virsh setmaxmem web04 8192M --config
# 假设虚拟机内存是500M,增加内容到1G,最大不能超过最大内存设置,--live --config可以同时使用
virsh setmem web04 1024M --live
virsh setmem web04 1024M --config

热更新CPU

需要设置最大vcpus数量,虚拟机的vcpus不能超过最大vcpus设置

# 调整vcpu个数为10,临时调整
virsh setvcpus web05 10 --live
# 调整vcpu个数为10,永久调整
virsh setvcpus web05 10 --config

热更新网卡

# 添加网卡,不加--config是临时生效
virsh attach-interface web04 --type bridge --source br0 --mode virtio --config
# 删除网卡
virsh detach-interface web04 --type bridge --mac mac地址

虚拟机克隆

完整克隆:互相独立,磁盘之间无依赖关系

# 完整克隆方式1,操作前关机/挂起
virsh shutdown web03
virt-clone -o web02 -n web03 --auto-clone
virt-clone -o web02 -n web03 -f /opt/ops-kvm/disk/web03.qcow2
# 完整克隆方式2
--> 拷贝磁盘镜像
--> 拷贝并修改配置,修改虚拟机名称,删除uuid和mac地址,磁盘文件,vnc端口
--> virsh define导入

# 链接克隆方式1,操作前关机/挂起
virsh shutdown web03
virt-clone \
  -o centos7-vm \
  -n centos7-vm-linked \
  -f /var/lib/libvirt/images/centos7-vm-linked.qcow2 \
  --force-copy=off  # 关键:禁用完整复制,使用链接模式
  
# 链接克隆方式2,操作前关机/挂起
virsh shutdown web03
qemu-img create -f qcow2 -b 源磁盘文件 新磁盘文件
# 用新的磁盘文件创建虚拟机即可
virt-install --disk path=新磁盘文件,format=qcow2,bus=virtio \

虚拟机快照

# 对centos7-vm虚拟机创建快照,名称为20260320-snap-init,备注为"系统初始化完成"
virsh snapshot-create-as centos7-vm 20260320-snap-init "系统初始化完成"
# 查看快照描述
virsh snapshot-dumpxml ops-kvm-01 snap-init |grep desc

常用脚本

创建虚拟机脚本,使用示例: sh vm_create.sh ops-agent-sts-02:5915

#!/bin/bash

ARGS="$1"

if [ "$#" = "0" ];then
    echo "Usage: sh $0 主机名:VNC端口号"
    echo "Example: sh $0 ops-agent-sts-02:5915"
    exit 1
fi

VIRTUAL_NAME=$(echo ${ARGS}|awk -F ':' '{print $1}')
VNC_PORT=$(echo ${ARGS}|awk -F ':' '{print $2}')

# 这里的目录需要替换,已经提前做好了qcow2模板,拷贝模板到新目录直接运行virt-install创建虚拟机
cp /opt/ops-kvm/images/rocky9-custom-template-final.qcow2 /opt/ops-kvm/disk/${VIRTUAL_NAME}_rocky9.6.qcow2
virt-install \
--name  ${VIRTUAL_NAME} \
--memory 16384,maxmemory=32768 \
--vcpus 8,maxvcpus=16 \
--virt-type kvm \
--os-type linux \
--os-variant rocky9 \
--import \
--disk path=/opt/ops-kvm/disk/${VIRTUAL_NAME}_rocky9.6.qcow2,format=qcow2,bus=virtio \
--network bridge=br0,model=virtio \
--graphics vnc,listen=0.0.0.0,port=${VNC_PORT} \
--noautoconsole

查看虚拟机信息脚本,脚本的IP和MAC地址基于arp协议,创建虚拟机后需要手动ping一下IP地址

#!/bin/bash
# 脚本名称:vm_info.sh
# 功能:批量获取KVM中名称包含"ops"的虚拟机的信息

# 定义颜色(可选,增强输出可读性)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # 重置颜色

# 标题输出
echo "-------------------------------------------------------------------------"
printf "%-20s %-20s %-20s %-20s\n" "HOSTNAME" "MAC ADDRESS" "VPC PORT"  "IP ADDRESS"
echo "-------------------------------------------------------------------------"

# 遍历名称包含"ops"的虚拟机
# 优化:用virsh list --name过滤,避免grep/awk处理表头
for vm_name in $(virsh list --name | grep "ops"); do
    # 跳过空值(避免无匹配时循环异常)
    if [ -z "$vm_name" ]; then
        continue
    fi
    vnc_port=$(virsh vncdisplay $vm_name|grep ':'|awk -F ':' '{print "59"$2}'|tr -d '\n')
    mac_addr=$(virsh domiflist "$vm_name" 2>/dev/null | grep -i "bridge" | awk '{print $NF}')
    ip=$(arp -an|grep $mac_addr|awk '{print $2}'|tr -d '()'|xargs) 
    # 异常处理:未找到桥接网卡
    if [ -z "$mac_addr" ]; then
        echo -e "${RED}  错误:未找到该虚拟机的桥接网卡MAC地址${NC}"
        continue
    fi

    # 格式化MAC地址(将:替换为-,兼容你的原始需求)
    mac_formatted=$(echo "$mac_addr" | sed 's/:/-/g')
    
    printf "%-20s %-20s %-20s %-0s\n" "$vm_name" "$mac_formatted" "$vnc_port" "$ip"
done

执行脚本的结果如下

-------------------------------------------------------------------------
HOSTNAME             MAC ADDRESS          VPC PORT             IP ADDRESS
-------------------------------------------------------------------------
ops-agent-dep-01     52-54-00-3b-5f-13    5914                 192.168.6.14
ops-agent-dep-02     52-54-00-4c-5a-11    5915                 192.168.6.15
ops-agent-dep-03     52-54-00-d8-b1-ca    5916                 192.168.6.16
ops-agent-sts-01     52-54-00-c8-c6-e8    5917                 192.168.6.17
ops-agent-sts-02     52-54-00-22-eb-ba    5918                 192.168.6.18
ops-agent-sts-03     52-54-00-55-31-21    5919                 192.168.6.19
ops-master-01        52-54-00-1e-3e-4b    5911                 192.168.6.11
ops-master-02        52-54-00-98-89-cf    5912                 192.168.6.12
ops-master-03        52-54-00-38-a7-74    5913                 192.168.6.13
ops-storage-01       52-54-00-5b-27-17    5920                 192.168.6.20
ops-storage-02       52-54-00-74-1d-8a    5921                 192.168.6.21
ops-storage-03       52-54-00-b5-ad-1c    5922                 192.168.6.22
ops-lb-01            52-54-00-97-fa-7b    5923                 192.168.6.23
ops-observe-01       52-54-00-20-1f-f0    5924                 192.168.6.24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值