云镜像使用
Enterprise Linux 发行版(AlmaLinux、Rocky Linux)提供预构建的云镜像(Cloud Image),这些镜像以 qcow2 格式分发,体积小、启动快,预装了 Cloud-Init,非常适合在 KVM/libvirt、OpenStack 或其他虚拟化平台上快速部署虚拟机。
下载官方云镜像
Section titled “下载官方云镜像”AlmaLinux 云镜像
Section titled “AlmaLinux 云镜像”# AlmaLinux 9 GenericCloud 镜像wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2
# AlmaLinux 8 GenericCloud 镜像wget https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2
# 验证下载完整性wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/CHECKSUMsha256sum -c CHECKSUM --ignore-missingRocky Linux 云镜像
Section titled “Rocky Linux 云镜像”# Rocky Linux 9 GenericCloud 镜像wget https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
# Rocky Linux 8 GenericCloud 镜像wget https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2
# 验证校验和wget https://download.rockylinux.org/pub/rocky/9/images/x86_64/CHECKSUMsha256sum -c CHECKSUM --ignore-missing查看镜像信息
Section titled “查看镜像信息”# 安装 qemu-img 工具sudo dnf install -y qemu-img
# 查看镜像信息qemu-img info AlmaLinux-9-GenericCloud-latest.x86_64.qcow2输出示例:
image: AlmaLinux-9-GenericCloud-latest.x86_64.qcow2file format: qcow2virtual size: 10 GiB (10737418240 bytes)disk size: 582 MiBcluster_size: 65536Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false使用 virt-customize 定制镜像
Section titled “使用 virt-customize 定制镜像”virt-customize 是 libguestfs-tools 提供的工具,可以在不启动虚拟机的情况下修改磁盘镜像。
sudo dnf install -y libguestfs-tools基本定制操作
Section titled “基本定制操作”# 复制一份镜像用于定制(保留原始镜像)cp AlmaLinux-9-GenericCloud-latest.x86_64.qcow2 almalinux9-custom.qcow2
# 设置 root 密码sudo virt-customize -a almalinux9-custom.qcow2 \ --root-password password:YourSecurePassword123
# 安装软件包sudo virt-customize -a almalinux9-custom.qcow2 \ --install vim-enhanced,htop,tmux,git,wget,curl
# 启用服务sudo virt-customize -a almalinux9-custom.qcow2 \ --run-command 'systemctl enable firewalld'
# 写入文件sudo virt-customize -a almalinux9-custom.qcow2 \ --write '/etc/motd:Welcome to Custom AlmaLinux 9 Image'
# 上传本地文件到镜像sudo virt-customize -a almalinux9-custom.qcow2 \ --upload /path/to/local/sshd_config:/etc/ssh/sshd_config
# 设置主机名sudo virt-customize -a almalinux9-custom.qcow2 \ --hostname custom-server
# 设置时区sudo virt-customize -a almalinux9-custom.qcow2 \ --timezone Asia/Shanghai
# 运行自定义脚本sudo virt-customize -a almalinux9-custom.qcow2 \ --run-command 'echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-custom.conf'
# 设置 SELinux 重新标记(修改文件后建议执行)sudo virt-customize -a almalinux9-custom.qcow2 \ --selinux-relabel完整的镜像定制流程
Section titled “完整的镜像定制流程”#!/bin/bash# customize-image.sh - 批量定制云镜像
SOURCE_IMAGE="AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"CUSTOM_IMAGE="almalinux9-production.qcow2"
# 复制原始镜像cp "${SOURCE_IMAGE}" "${CUSTOM_IMAGE}"
# 扩展磁盘到 30GBqemu-img resize "${CUSTOM_IMAGE}" 30G
# 执行定制sudo virt-customize -a "${CUSTOM_IMAGE}" \ --root-password password:TempPassword123 \ --timezone Asia/Shanghai \ --install epel-release \ --install vim-enhanced,htop,tmux,git,wget,curl,net-tools,bind-utils \ --install firewalld,fail2ban,chrony \ --run-command 'systemctl enable firewalld' \ --run-command 'systemctl enable fail2ban' \ --run-command 'systemctl enable chronyd' \ --write '/etc/sysctl.d/99-custom.conf:net.core.somaxconn = 65535net.ipv4.tcp_max_syn_backlog = 65535vm.swappiness = 10' \ --run-command 'echo "PermitRootLogin prohibit-password" >> /etc/ssh/sshd_config.d/99-custom.conf' \ --selinux-relabel
echo "镜像定制完成: ${CUSTOM_IMAGE}"qemu-img info "${CUSTOM_IMAGE}"使用 virt-sysprep 清理镜像
Section titled “使用 virt-sysprep 清理镜像”在分发自定义镜像之前,应清理掉特定于实例的信息:
# 清理镜像(移除 SSH 密钥、机器 ID、日志等)sudo virt-sysprep -a almalinux9-custom.qcow2
# 指定要执行的清理操作sudo virt-sysprep -a almalinux9-custom.qcow2 \ --operations defaults,-ssh-userdir
# 查看所有可用的清理操作sudo virt-sysprep --list-operations使用 virt-install 创建云实例
Section titled “使用 virt-install 创建云实例”安装虚拟化工具
Section titled “安装虚拟化工具”# 安装 KVM 和管理工具sudo dnf install -y @virtualizationsudo systemctl enable --now libvirtd
# 验证虚拟化支持virt-host-validate准备 Cloud-Init 配置
Section titled “准备 Cloud-Init 配置”# 创建工作目录mkdir -p /var/lib/libvirt/cloud-init
# 创建 meta-datacat > /var/lib/libvirt/cloud-init/meta-data << 'EOF'instance-id: vm-001local-hostname: web-server-01EOF
# 创建 user-datacat > /var/lib/libvirt/cloud-init/user-data << 'EOF'#cloud-config
hostname: web-server-01fqdn: web-server-01.example.com
users: - default - name: admin groups: wheel sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh_authorized_keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@workstation
package_update: truepackages: - vim-enhanced - htop - nginx
runcmd: - systemctl enable --now nginxEOF
# 创建 network-config(可选,配置静态 IP)cat > /var/lib/libvirt/cloud-init/network-config << 'EOF'version: 2ethernets: eth0: dhcp4: trueEOF生成 Cloud-Init ISO
Section titled “生成 Cloud-Init ISO”# 安装 genisoimagesudo dnf install -y genisoimage
# 生成 seed ISOgenisoimage -output /var/lib/libvirt/cloud-init/seed.iso \ -volid cidata \ -joliet -rock \ /var/lib/libvirt/cloud-init/user-data \ /var/lib/libvirt/cloud-init/meta-data \ /var/lib/libvirt/cloud-init/network-config# 准备磁盘镜像(复制云镜像作为虚拟机磁盘)VM_NAME="web-server-01"IMAGE_DIR="/var/lib/libvirt/images"
sudo cp almalinux9-custom.qcow2 "${IMAGE_DIR}/${VM_NAME}.qcow2"
# 调整磁盘大小sudo qemu-img resize "${IMAGE_DIR}/${VM_NAME}.qcow2" 30G
# 使用 virt-install 创建虚拟机sudo virt-install \ --name "${VM_NAME}" \ --memory 2048 \ --vcpus 2 \ --disk "${IMAGE_DIR}/${VM_NAME}.qcow2",format=qcow2 \ --disk /var/lib/libvirt/cloud-init/seed.iso,device=cdrom \ --os-variant almalinux9 \ --network bridge=virbr0,model=virtio \ --graphics none \ --console pty,target_type=serial \ --import \ --noautoconsole
# 查看虚拟机状态sudo virsh list --all
# 查看虚拟机 IP 地址sudo virsh domifaddr "${VM_NAME}"批量创建虚拟机
Section titled “批量创建虚拟机”#!/bin/bash# create-vms.sh - 批量创建虚拟机
BASE_IMAGE="/var/lib/libvirt/images/almalinux9-custom.qcow2"IMAGE_DIR="/var/lib/libvirt/images"CI_DIR="/var/lib/libvirt/cloud-init"SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@workstation"
VMS=("web-01" "web-02" "db-01")MEMORY=2048VCPUS=2DISK_SIZE="30G"
for VM_NAME in "${VMS[@]}"; do echo "=== 创建虚拟机: ${VM_NAME} ==="
# 准备磁盘 sudo cp "${BASE_IMAGE}" "${IMAGE_DIR}/${VM_NAME}.qcow2" sudo qemu-img resize "${IMAGE_DIR}/${VM_NAME}.qcow2" "${DISK_SIZE}"
# 生成 cloud-init 配置 WORK_DIR="${CI_DIR}/${VM_NAME}" mkdir -p "${WORK_DIR}"
cat > "${WORK_DIR}/meta-data" << METAEOFinstance-id: ${VM_NAME}local-hostname: ${VM_NAME}METAEOF
cat > "${WORK_DIR}/user-data" << USEREOF#cloud-confighostname: ${VM_NAME}users: - default - name: admin groups: wheel sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh_authorized_keys: - ${SSH_KEY}package_update: truepackages: - vim-enhanced - htopUSEREOF
# 生成 ISO genisoimage -output "${WORK_DIR}/seed.iso" \ -volid cidata -joliet -rock \ "${WORK_DIR}/user-data" \ "${WORK_DIR}/meta-data"
# 创建虚拟机 sudo virt-install \ --name "${VM_NAME}" \ --memory ${MEMORY} \ --vcpus ${VCPUS} \ --disk "${IMAGE_DIR}/${VM_NAME}.qcow2",format=qcow2 \ --disk "${WORK_DIR}/seed.iso",device=cdrom \ --os-variant almalinux9 \ --network bridge=virbr0,model=virtio \ --graphics none \ --console pty,target_type=serial \ --import \ --noautoconsole
echo "${VM_NAME} 创建完成"done
echo ""echo "=== 所有虚拟机状态 ==="sudo virsh list --all调整镜像大小
Section titled “调整镜像大小”扩展磁盘容量
Section titled “扩展磁盘容量”# 查看当前大小qemu-img info /var/lib/libvirt/images/web-server-01.qcow2
# 扩展到 50GB(虚拟机需要关机)sudo virsh shutdown web-server-01sudo qemu-img resize /var/lib/libvirt/images/web-server-01.qcow2 50Gsudo virsh start web-server-01虚拟机启动后,还需要扩展分区和文件系统:
# 登录到虚拟机后执行# 查看磁盘布局lsblk
# 如果使用 LVM(云镜像通常的方式)sudo growpart /dev/vda 4 # 扩展分区(分区号视实际情况)sudo pvresize /dev/vda4 # 扩展 PVsudo lvextend -l +100%FREE /dev/mapper/almalinux-root # 扩展 LVsudo xfs_growfs / # 扩展 XFS 文件系统# 或 sudo resize2fs /dev/mapper/almalinux-root # 如果是 ext4
# 如果不使用 LVM(简单分区)sudo growpart /dev/vda 1sudo xfs_growfs /# 关闭虚拟机sudo virsh shutdown web-server-01
# 压缩 qcow2 镜像(去除稀疏空间)sudo qemu-img convert -O qcow2 -c \ /var/lib/libvirt/images/web-server-01.qcow2 \ /var/lib/libvirt/images/web-server-01-compressed.qcow2
# 用 virt-sparsify 更彻底地压缩sudo virt-sparsify --in-place /var/lib/libvirt/images/web-server-01.qcow2# qcow2 转为 raw 格式qemu-img convert -f qcow2 -O raw image.qcow2 image.raw
# raw 转为 qcow2 格式qemu-img convert -f raw -O qcow2 image.raw image.qcow2
# qcow2 转为 vmdk(VMware 格式)qemu-img convert -f qcow2 -O vmdk image.qcow2 image.vmdk
# qcow2 转为 vdi(VirtualBox 格式)qemu-img convert -f qcow2 -O vdi image.qcow2 image.vdi虚拟机管理常用命令
Section titled “虚拟机管理常用命令”# 列出所有虚拟机sudo virsh list --all
# 启动/关机/重启sudo virsh start web-server-01sudo virsh shutdown web-server-01sudo virsh reboot web-server-01
# 强制关机sudo virsh destroy web-server-01
# 连接到虚拟机控制台sudo virsh console web-server-01# 退出控制台: Ctrl+]
# 查看虚拟机信息sudo virsh dominfo web-server-01sudo virsh domifaddr web-server-01
# 创建快照sudo virsh snapshot-create-as web-server-01 \ --name "before-upgrade" \ --description "升级前快照"
# 列出快照sudo virsh snapshot-list web-server-01
# 恢复快照sudo virsh snapshot-revert web-server-01 before-upgrade
# 删除虚拟机(保留磁盘)sudo virsh undefine web-server-01
# 删除虚拟机(连同磁盘一起删除)sudo virsh undefine web-server-01 --remove-all-storage使用官方云镜像配合 Cloud-Init 和 virt-install,可以在本地 KVM 环境中快速创建标准化的虚拟机实例,这与公有云上创建 ECS 实例的体验非常接近,是搭建私有云和开发测试环境的理想方案。