前言
虚拟化基础篇讲了 KVM 原理,这篇进入实战进阶:用 cloud-init 云镜像几分钟拉起一台可 SSH 的虚拟机,玩转快照、克隆、桥接——自建小私有云/Malloc 一套测试环境的完整技能。
一、环境准备(宿主机)
dnf install -y qemu-kvm libvirt virt-install virt-top libguestfs-tools
systemctl enable --now libvirtd
lsmod | grep kvm # kvm_intel / kvm_amd 已加载
# 默认 NAT 网络(192.168.122.0/24, 自带 DHCP)
virsh net-start default
virsh net-autostart default
二、cloud-init:告别装系统
传统 virt-install 挂 ISO 装系统要 20 分钟;云镜像(Cloud Image)自带 cloud-init,首次开机自动完成:扩盘、设密码、注入密钥、改主机名——1 分钟出机。
# 1. 下载云镜像(以 Rocky 9 为例)
cd /var/lib/libvirt/images
wget https://mirrors.nju.edu.cn/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2
# 2. 准备"启动配置"
cat > /root/seed.iso.cmd <<'EOF'
cloud-localds /var/lib/libvirt/images/seed.img /root/user-data
EOF
/root/user-data(cloud-init 配置):
#cloud-config
hostname: vm-lab01
users:
- name: zy
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAAC3... your@laptop
ssh_pwauth: true
chpasswd:
expire: false
users:
- name: zy
password: Passw0rd!
type: text
runcmd:
- dnf install -y nginx
- systemctl enable --now nginx
growpart:
mode: auto
devices: ['/']
# 3. 生成 seed 盘(需要 cloud-utils 软件包)
dnf install -y cloud-utils
cloud-localds /var/lib/libvirt/images/seed.img /root/user-data
# 4. 从云镜像启动虚拟机(注意: 用副本, 别直接用原镜像)
cp Rocky-9-GenericCloud-Base.latest.x86_64.qcow2 vm-lab01.qcow2
virt-install \
--name vm-lab01 \
--vcpus 2 --memory 2048 \
--disk vm-lab01.qcow2,bus=virtio,format=qcow2 \
--disk seed.img,device=cdrom \
--network network=default,model=virtio \
--os-variant rocky9 \
--import --noautoconsole # --import: 不装系统直接启动
# 5. 一分钟后拿到 IP 并登录
virsh domifaddr vm-lab01
ssh zy@192.168.122.xxx
# nginx 都已经装好了 —— runcmd 的功劳
三、日常生命周期管理
virsh start vm-lab01 / shutdown / destroy # 优雅关 / 拔电源
virsh reboot vm-lab01
virsh list --all
virsh autostart vm-lab01 # 宿主机开机自启
# 进控制台(没网络时的救命稻草, 退出 Ctrl+])
virsh console vm-lab01
# 删除虚拟机(先 undefine 再删盘)
virsh undefine vm-lab01 --nvram
rm /var/lib/libvirt/images/vm-lab01.qcow2
四、资源调整
# ---- 内存 ----
virsh setmem vm-lab01 4G --config # 下次启动生效
virsh setmem vm-lab01 2G --live # 立即生效(在线! 只能调小于分配值)
# ---- CPU ----
virsh setvcpus vm-lab01 4 --maximum --config # 上限
virsh setvcpus vm-lab01 2 --live # 在线减少
# ---- 磁盘扩容三步走 ----
# 1. 扩 qcow2 文件
qemu-img resize vm-lab01.qcow2 +20G
# 2. 通知虚拟机重读磁盘(或重启)
virsh blockresize vm-lab01 /path/vm-lab01.qcow2 40G
# 3. 进虚拟机扩分区和文件系统
growpart /dev/vda 1 && xfs_growfs / # cloud 镜像自带 growpart
五、快照:虚拟机的"存档点"
# 创建(拍快照前磁盘会自动暂停一下, 建议关机时拍更稳)
virsh snapshot-create-as vm-lab01 before-upgrade "升级前存档"
# 查看 / 恢复 / 删除
virsh snapshot-list vm-lab01
virsh snapshot-revert vm-lab01 before-upgrade # 时光倒流
virsh snapshot-delete vm-lab01 before-upgrade
# qcow2 快照链原理
qemu-img info vm-lab01.qcow2
# backing file: Rocky-9-GenericCloud...qcow2 ← 我们 cp 出来的其实是"基于模板的差分盘"
注意快照链会让性能下降,重要数据别依赖快照当天备份,还是要走外部备份(qemu-img convert 导出)。
六、模板与克隆:批量开机房
# 1. 把一台调好的机器做成模板(先关机)
virsh shutdown vm-template
virt-sysprep -d vm-template # 清洗机器指纹(ssh host key、machine-id、日志)
# 2. 基于模板克隆(差分盘, 秒级, 几乎不占空间)
virt-clone \
--original vm-template \
--name vm-web01 \
--file /var/lib/libvirt/images/vm-web01.qcow2
# 3. 改主机名/IP(避免克隆冲突)
virt-customize -a /var/lib/libvirt/images/vm-web01.qcow2 \
--hostname vm-web01 \
--run-command 'nmcli con mod eth0 ipv4.addresses 192.168.122.101/24'
virsh start vm-web01
# 重复 2-3 步, 5 分钟拉起一个 10 台机器的实验集群
七、桥接网络:让虚拟机进物理网络
默认 NAT 网络下虚拟机只能"单向出";桥接后虚拟机与宿主机同网段平级,外部可直接访问:
# 宿主机建网桥 br0(把物理网卡 eth0 挂上去)
nmcli con add type bridge ifname br0 ipv4.method auto
nmcli con add type bridge-slave ifname eth0 master br0
nmcli con up br0
# 虚拟机用桥接
virt-install ... --network bridge=br0,model=virtio
# 或修改现有机器: virsh edit vm-lab01 把 interface source 改为 bridge
八、性能观测与常见坑
virt-top # 虚拟机版 top(CPU/内存实时)
virsh dominfo vm-lab01 # 配置详情
virsh domstats vm-lab01 --cpu-total
virsh cpu-stats vm-lab01 | head
qemu-img check vm-lab01.qcow2 # 磁盘一致性检查
| 坑 | 解 |
|---|---|
domain is already running |
virsh destroy 后再 start |
| cloud-init 没生效 | 看 /var/log/cloud-init.log;seed 盘必须是 device=cdrom |
| 虚拟机时间漂移 | 装 chrony;virsh edit 确认 <clock offset='utc'/> |
| 克隆机网络起不来 | machine-id 重复,virt-sysprep 或手动 truncate |
| 性能差 | 确认 virtio 磁盘/网卡、KVM 嵌套没开虚拟化 |
小结
| 任务 | 命令 |
|---|---|
| 快速建机 | 云镜像 + cloud-localds + --import |
| 快照 | snapshot-create-as / revert |
| 批量 | virt-sysprep 模板 + virt-clone |
| 桥接 | nmcli bridge + --network bridge=br0 |
| 观测 | virt-top / domstats |
本文是「云计算」系列第 4 篇。