跳到主要内容

第9章 KVM迁移

虚拟机迁移是虚拟化环境中的重要功能,允许将虚拟机从一台物理主机迁移到另一台,实现负载均衡、硬件维护和灾难恢复等目的。

迁移类型概述

迁移分类

迁移类型停机时间应用场景优缺点
冷迁移需要停机硬件维护、长期迁移简单可靠,但有停机时间
热迁移(在线迁移)几乎无停机负载均衡、无缝迁移复杂度高,需要共享存储
存储迁移视情况存储设备更换可独立迁移存储
P2V迁移需要停机物理机转虚拟机可将物理服务器虚拟化
迁移要求

冷迁移要求

  • 目标主机有足够资源
  • 网络连通性

热迁移要求

  • 共享存储(NFS、iSCSI等)
  • 相同的CPU架构
  • 网络连通性良好
  • 时间同步

冷迁移

方法一:复制磁盘文件

# 1. 关闭虚拟机
virsh shutdown web01

# 2. 导出虚拟机配置
virsh dumpxml web01 > /tmp/web01.xml

# 3. 复制磁盘文件到目标主机
scp /data/web01.qcow2 root@target-host:/data/
scp /tmp/web01.xml root@target-host:/tmp/

# 4. 在目标主机导入
# 登录目标主机
ssh root@target-host

# 导入虚拟机定义
virsh define /tmp/web01.xml

# 启动虚拟机
virsh start web01

方法二:使用virsh migrate(离线)

# 离线迁移到目标主机
virsh migrate --offline --persistent \
--undefinesource \
web01 qemu+ssh://root@target-host/system

方法三:导出导入方式

# 1. 导出虚拟机
virsh shutdown web01
virsh dumpxml web01 > web01.xml
cp /data/web01.qcow2 /backup/

# 2. 打包传输
tar czf web01-vm.tar.gz web01.xml /backup/web01.qcow2
scp web01-vm.tar.gz root@target-host:/tmp/

# 3. 在目标主机解压导入
tar xzf /tmp/web01-vm.tar.gz
virsh define web01.xml

热迁移(在线迁移)

环境准备

1. 配置共享存储

# 配置NFS共享存储(在存储服务器上)
mkdir -p /nfs/kvm
echo "/nfs/kvm *(rw,sync,no_root_squash)" >> /etc/exports
systemctl start nfs-server
systemctl enable nfs-server
exportfs -r

# 在所有KVM主机上挂载
mkdir -p /shared-storage
mount -t nfs storage-server:/nfs/kvm /shared-storage
echo "storage-server:/nfs/kvm /shared-storage nfs defaults 0 0" >> /etc/fstab

2. 配置主机间免密访问

# 在源主机生成密钥
ssh-keygen -t rsa -N ""

# 复制到目标主机
ssh-copy-id root@target-host

# 测试连接
ssh root@target-host hostname

3. 时间同步

# 配置NTP服务
yum install -y chrony
systemctl start chronyd
systemctl enable chronyd

# 验证时间同步
chronyc sources

执行热迁移

基本热迁移命令

# 简单热迁移
virsh migrate --live web01 \
qemu+ssh://root@target-host/system

# 详细参数热迁移
virsh migrate --live \
--persistent \
--undefinesource \
--verbose \
--compressed \
web01 qemu+ssh://root@target-host/system

高级迁移选项

# 指定迁移带宽(限制为100MB/s)
virsh migrate --live \
--bandwidth 100 \
web01 qemu+ssh://root@target-host/system

# 使用隧道加密
virsh migrate --live \
--tunnelled \
web01 qemu+ssh://root@target-host/system

# 自动收敛(加速迁移)
virsh migrate --live \
--auto-converge \
web01 qemu+ssh://root@target-host/system

监控迁移进度

# 查看迁移进度
virsh domjobinfo web01

# 取消迁移
virsh domjobabort web01

# 查看迁移统计
virsh domjobinfo web01 --completed

存储迁移

在线存储迁移

# 将虚拟机磁盘从本地迁移到共享存储
virsh blockcopy web01 vda \
/shared-storage/web01.qcow2 \
--wait --verbose --pivot

# 使用--blockdev选项进行块设备迁移
virsh blockcopy web01 vda \
--dest /new-storage/web01.qcow2 \
--wait --verbose --pivot --shallow

离线存储迁移

# 1. 关闭虚拟机
virsh shutdown web01

# 2. 转换并移动磁盘
qemu-img convert -f qcow2 -O qcow2 \
/local-storage/web01.qcow2 \
/shared-storage/web01.qcow2

# 3. 更新虚拟机配置
virsh edit web01
# 修改磁盘路径指向新位置

# 4. 启动虚拟机
virsh start web01

P2V迁移(物理机到虚拟机)

使用virt-p2v工具

# 1. 创建virt-p2v启动介质
# 下载virt-p2v ISO或创建
virt-p2v-make-disk -o /tmp/virt-p2v.img

# 2. 在物理机上启动virt-p2v
# 使用USB或网络启动

# 3. 配置转换参数
# - 目标KVM主机地址
# - SSH连接信息
# - 磁盘和网络映射

手动P2V迁移

# 1. 在物理机上创建磁盘镜像
dd if=/dev/sda | ssh root@kvm-host \
"dd of=/data/physical-server.img"

# 2. 转换为qcow2格式
qemu-img convert -f raw -O qcow2 \
/data/physical-server.img \
/data/physical-server.qcow2

# 3. 创建虚拟机使用该磁盘
virt-install \
--name physical-migrated \
--memory 4096 \
--vcpus 4 \
--disk /data/physical-server.qcow2 \
--import \
--network bridge=br0 \
--graphics vnc

跨版本迁移

CPU兼容性配置

# 查看CPU模型
virsh capabilities | grep -A5 "host"

# 配置CPU兼容模式
virsh edit web01
<!-- 修改CPU配置为兼容模式 -->
<cpu mode='custom' match='exact'>
<model fallback='allow'>Westmere</model>
<feature policy='disable' name='rdtscp'/>
</cpu>

使用CPU主机直通

<!-- 最大性能但限制迁移 -->
<cpu mode='host-passthrough'>
<cache mode='passthrough'/>
</cpu>

<!-- 或使用host-model平衡性能和兼容性 -->
<cpu mode='host-model'>
<model fallback='allow'/>
</cpu>

批量迁移

迁移脚本

#!/bin/bash
# batch-migrate.sh - 批量迁移虚拟机

TARGET_HOST="target-host"
VMS="web01 web02 db01"

for VM in $VMS; do
echo "迁移虚拟机: $VM"

# 检查虚拟机状态
STATE=$(virsh domstate $VM)

if [ "$STATE" == "running" ]; then
# 热迁移
virsh migrate --live --persistent \
$VM qemu+ssh://root@$TARGET_HOST/system
else
# 冷迁移
virsh migrate --offline --persistent \
$VM qemu+ssh://root@$TARGET_HOST/system
fi

if [ $? -eq 0 ]; then
echo "$VM 迁移成功"
else
echo "$VM 迁移失败"
fi
done

并行迁移

# 使用GNU parallel并行迁移
parallel -j 3 virsh migrate --live {} \
qemu+ssh://root@target-host/system ::: web01 web02 web03

迁移优化

网络优化

# 1. 使用专用迁移网络
virsh migrate --live \
--migrate-uri tcp://migration-network:49152 \
web01 qemu+ssh://root@target-host/system

# 2. 配置迁移端口范围
echo "migration_port_min = 49152" >> /etc/libvirt/qemu.conf
echo "migration_port_max = 49215" >> /etc/libvirt/qemu.conf
systemctl restart libvirtd

性能调优

# 1. 增加迁移并发度
virsh migrate-setmaxdowntime web01 500

# 2. 启用多线程压缩
virsh migrate --live \
--compressed \
--comp-methods mt \
--comp-mt-level 5 \
--comp-mt-threads 4 \
web01 qemu+ssh://root@target-host/system

预拷贝优化

# 使用postcopy模式(减少停机时间)
virsh migrate --live \
--postcopy \
--postcopy-after-precopy \
web01 qemu+ssh://root@target-host/system

故障处理

常见问题

  1. 迁移失败:CPU不兼容

    # 解决方案:使用CPU兼容模式
    virsh edit web01
    # 修改CPU mode为custom或host-model
  2. 迁移超时

    # 增加超时时间
    virsh migrate-setmaxdowntime web01 2000

    # 或调整迁移速度
    virsh migrate-setspeed web01 1000
  3. 存储路径不一致

    # 使用--migrate-disks指定磁盘
    virsh migrate --live \
    --migrate-disks vda,vdb \
    web01 qemu+ssh://root@target-host/system

迁移回滚

# 如果迁移失败,虚拟机仍在源主机
# 检查状态
virsh list --all

# 如果需要,重新启动
virsh start web01

# 清理目标主机的残留定义
ssh root@target-host "virsh undefine web01"

日志分析

# 查看迁移日志
tail -f /var/log/libvirt/qemu/web01.log

# 查看libvirtd日志
journalctl -u libvirtd -f

# 启用调试日志
echo 'log_level = 1' >> /etc/libvirt/libvirtd.conf
echo 'log_outputs = "1:file:/var/log/libvirt/libvirtd.log"' >> /etc/libvirt/libvirtd.conf
systemctl restart libvirtd

迁移验证

迁移后检查清单

#!/bin/bash
# post-migration-check.sh

VM_NAME=$1
echo "=== 迁移后验证:$VM_NAME ==="

# 1. 检查虚拟机状态
echo -n "虚拟机状态: "
virsh domstate $VM_NAME

# 2. 检查网络连接
echo -n "网络连接: "
virsh domifaddr $VM_NAME

# 3. 检查磁盘
echo "磁盘信息:"
virsh domblklist $VM_NAME

# 4. 检查性能
echo "性能统计:"
virsh domstats $VM_NAME

# 5. 连接测试
echo "控制台连接测试:"
timeout 5 virsh console $VM_NAME

自动化迁移

使用迁移策略

# migration-policy.yaml
migration_policy:
load_threshold: 80
target_hosts:
- host1
- host2
- host3
rules:
- condition: "cpu_usage > 80%"
action: "migrate_to_least_loaded"
- condition: "memory_usage > 90%"
action: "migrate_memory_intensive"

迁移调度脚本

#!/usr/bin/env python3
# auto-migrate.py - 自动迁移调度器

import libvirt
import statistics

def get_host_load(conn):
"""获取主机负载"""
stats = conn.getCPUStats(libvirt.VIR_NODE_CPU_STATS_ALL_CPUS)
return stats['user'] + stats['system']

def find_best_target(exclude_host):
"""找到负载最低的目标主机"""
hosts = ['kvm1', 'kvm2', 'kvm3']
loads = {}

for host in hosts:
if host != exclude_host:
conn = libvirt.open(f'qemu+ssh://root@{host}/system')
loads[host] = get_host_load(conn)
conn.close()

return min(loads, key=loads.get)

def migrate_vm(vm_name, source_host, target_host):
"""执行迁移"""
source = libvirt.open(f'qemu+ssh://root@{source_host}/system')
target = libvirt.open(f'qemu+ssh://root@{target_host}/system')

vm = source.lookupByName(vm_name)
vm.migrate(target, libvirt.VIR_MIGRATE_LIVE |
libvirt.VIR_MIGRATE_PERSIST_DEST |
libvirt.VIR_MIGRATE_UNDEFINE_SOURCE)

source.close()
target.close()

最佳实践

迁移最佳实践
  1. 规划先行:评估网络带宽、存储性能和CPU兼容性
  2. 测试环境:先在测试环境验证迁移流程
  3. 监控为主:全程监控迁移进度和系统状态
  4. 备份重要:迁移前备份关键数据和配置
  5. 时间选择:选择业务低峰期进行迁移
  6. 回滚方案:准备好快速回滚计划

总结

本章详细介绍了KVM虚拟机迁移的各种方式:

  • ✅ 冷迁移和热迁移的实施方法
  • ✅ 存储迁移和P2V迁移技术
  • ✅ 跨版本和批量迁移方案
  • ✅ 迁移优化和故障处理
  • ✅ 自动化迁移和最佳实践

掌握这些迁移技术,可以实现虚拟化环境的灵活管理和高可用性。下一章将介绍KVM图形化管理工具。