本文目录导读:

在Shell脚本中迁移虚拟机到其他宿主机,主要取决于你使用的虚拟化平台(如KVM/libvirt、VMware、Hyper-V等),以下针对最常见的 KVM/libvirt 环境提供几种主流迁移方式的 Shell 脚本实现。
基于 libvirt 的在线迁移(热迁移)
适用于需要零停机时间的场景,要求源和目标宿主机共享存储(NFS、iSCSI、GlusterFS等)。
#!/bin/bash
# live_migration.sh - 虚拟机在线迁移脚本
# 参数配置
VM_NAME=$1 # 虚拟机名称
TARGET_HOST=$2 # 目标宿主机IP或主机名
TARGET_SSH_USER=${3:-"root"} # 目标宿主机SSH用户
# 检查参数
if [ $# -lt 2 ]; then
echo "用法: $0 <虚拟机名称> <目标宿主机> [SSH用户]"
echo "示例: $0 web-server-01 192.168.1.102"
exit 1
fi
# 确认虚拟机存在
if ! virsh dominfo "$VM_NAME" &>/dev/null; then
echo "错误: 虚拟机 '$VM_NAME' 不存在"
exit 1
fi
# 检查目标主机连通性
if ! ping -c 1 "$TARGET_HOST" &>/dev/null; then
echo "错误: 无法连接到目标宿主机 $TARGET_HOST"
exit 1
fi
# 检查源和目标是否共享存储(通过检查同一路径是否存在)
TEST_PATH="/var/lib/libvirt/images/test_shared.tmp"
if ssh "$TARGET_SSH_USER@$TARGET_HOST" "touch $TEST_PATH" && rm -f "$TEST_PATH"; then
echo "存储共享检查通过"
else
echo "警告: 无法确认存储共享,请确保使用共享存储"
fi
# 执行在线迁移
echo "开始迁移虚拟机 '$VM_NAME' 到 $TARGET_HOST ..."
virsh migrate --live \
--verbose \
--persistent \
--undefinesource \
--domain "$VM_NAME" \
--desturi "qemu+ssh://$TARGET_SSH_USER@$TARGET_HOST/system" \
--migrateuri "tcp://$TARGET_HOST:49152"
# 检查迁移结果
if [ $? -eq 0 ]; then
echo "迁移成功完成!"
echo "虚拟机 '$VM_NAME' 现在运行在 $TARGET_HOST"
else
echo "迁移失败,请检查日志"
exit 1
fi
使用前提:
- 源和目标宿主机安装 libvirt 和 qemu-kvm
- 配置 SSH 密钥认证(免密登录)
- 启用 libvirt TCP 迁移(
/etc/libvirt/libvirtd.conf中设置listen_tls=0,listen_tcp=1)
离线迁移(冷迁移 + 文件复制)
适用于非关键业务,需要复制磁盘文件到目标宿主机。
#!/bin/bash
# cold_migration.sh - 虚拟机离线迁移脚本
VM_NAME=$1
TARGET_HOST=$2
TARGET_STORAGE=${3:-"/var/lib/libvirt/images"}
LOCAL_STORAGE=$(virsh dumpxml "$VM_NAME" | sed -n "s|.*source file='\([^']*\)'.*|\1|p")
# 关闭虚拟机
echo "正在关闭虚拟机 '$VM_NAME'..."
virsh shutdown "$VM_NAME"
while virsh domstate "$VM_NAME" | grep -q "running"; do
sleep 2
echo "等待虚拟机完全关闭..."
done
# 获取磁盘路径
echo "获取磁盘文件路径..."
DISK_FILES=()
while IFS= read -r line; do
DISK_FILES+=("$line")
done < <(virsh dumpxml "$VM_NAME" | grep "source file" | sed "s/.*'\([^']*\)'.*/\1/")
# 复制磁盘文件到目标主机
for DISK in "${DISK_FILES[@]}"; do
echo "复制磁盘文件: $DISK 到 $TARGET_HOST:$TARGET_STORAGE/"
scp "$DISK" "root@$TARGET_HOST:$TARGET_STORAGE/"
if [ $? -ne 0 ]; then
echo "磁盘复制失败,请检查网络和权限"
exit 1
fi
done
# 导出并修改XML配置文件
echo "导出并修改XML配置..."
virsh dumpxml "$VM_NAME" > /tmp/${VM_NAME}_migrate.xml
# 修改磁盘路径为目标路径
for DISK in "${DISK_FILES[@]}"; do
NEW_DISK_PATH="$TARGET_STORAGE/$(basename $DISK)"
sed -i "s|$DISK|$NEW_DISK_PATH|g" /tmp/${VM_NAME}_migrate.xml
done
# 将XML复制到目标主机
scp /tmp/${VM_NAME}_migrate.xml "root@$TARGET_HOST:/etc/libvirt/qemu/${VM_NAME}.xml"
# 在目标主机上定义并启动虚拟机
ssh "root@$TARGET_HOST" "virsh define /etc/libvirt/qemu/${VM_NAME}.xml && virsh start $VM_NAME"
# 在源主机上清除虚拟机定义
virsh undefine "$VM_NAME"
# 清理临时文件
rm -f /tmp/${VM_NAME}_migrate.xml
echo "迁移完成!虚拟机 '$VM_NAME' 已迁移到 $TARGET_HOST"
使用 virt-v2v 迁移到其他宿主机(异构环境)
适用于 KVM 到 KVM 或不同虚拟化平台间迁移。
#!/bin/bash
# virt_v2v_migration.sh - 使用virt-v2v工具迁移
SOURCE_VM=$1
TARGET_HOST=$2
# 安装必要工具
if ! command -v virt-v2v &>/dev/null; then
echo "安装 virt-v2v..."
yum install -y virt-v2v # 适用于 CentOS/RHEL
# apt install virt-v2v # 适用于 Ubuntu
fi
# 创建临时存储目录
TEMP_DIR="/tmp/v2v_${SOURCE_VM}"
mkdir -p "$TEMP_DIR"
# 执行转换迁移
echo "开始转换并迁移虚拟机..."
virt-v2v -i libvirt -ic "qemu:///system" \
-o libvirt -oc "qemu+ssh://root@$TARGET_HOST/system" \
-os "/var/lib/libvirt/images" \
-on "$SOURCE_VM" \
-of qcow2 \
-b br0 \
-n default \
"$SOURCE_VM" 2>&1 | tee "$TEMP_DIR/migration.log"
# 检查迁移结果
if [ $? -eq 0 ]; then
echo "迁移成功!请检查目标主机上的虚拟机状态"
else
echo "迁移失败,请查看日志: $TEMP_DIR/migration.log"
exit 1
fi
# 清理临时目录
rm -rf "$TEMP_DIR"
通用迁移检查脚本(先验证环境)
#!/bin/bash
# check_migration_env.sh - 迁移前环境检查
MIGRATION_METHOD=${1:-"live"}
SOURCE_HOST=$(hostname)
TARGET_HOST=$2
check_required_ports() {
echo "检查必要端口..."
for port in 22 16509 49152; do
nc -zv "$TARGET_HOST" "$port" &>/dev/null && \
echo " ✓ 端口 $port 可达" || \
echo " ✗ 端口 $port 不可达"
done
}
check_ssh_auth() {
echo "检查SSH密钥认证..."
ssh -o BatchMode=yes "root@$TARGET_HOST" "echo SSH_OK" &>/dev/null && \
echo " ✓ SSH密钥认证正常" || \
echo " ✗ SSH密钥认证失败,请配置免密登录"
}
check_shared_storage() {
echo "检查共享存储..."
if df -h | grep -qE "(nfs|glusterfs|ceph)"; then
echo " ✓ 检测到共享存储"
else
echo " ! 未检测到共享存储,只能执行离线迁移"
fi
}
# 主检查流程
echo "======= 迁移环境检查 ======="
echo "源宿主机: $SOURCE_HOST"
echo "目标宿主机: $TARGET_HOST"
echo "迁移方式: $MIGRATION_METHOD"
echo "============================"
check_required_ports
check_ssh_auth
check_shared_storage
echo "============================"
echo "环境检查完成"
使用注意事项
-
网络要求:
- 所有宿主机之间需要网络互通
- 热迁移需要至少 1Gbps 网络带宽
- 配置合适的防火墙规则
-
存储要求:
- 热迁移必须使用共享存储
- 冷迁移需要足够磁盘空间和网络传输时间
-
版本兼容性:
- 源和目标宿主机libvirt版本尽量一致
- CPU特性要兼容(可使用CPU模式
host-model)
-
调用示例:
# 热迁移 ./live_migration.sh myvm 192.168.1.101
冷迁移
./cold_migration.sh myvm 192.168.1.101 /data/images
环境检查
./check_migration_env.sh live 192.168.1.101
根据实际环境选择合适的迁移方式,生产环境建议先在测试环境验证。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播