虚拟机热迁移
概述
虚拟机热迁移技术允许在不关闭或中断虚拟机的情况下,将虚拟机从一台物理服务器移动到另一台物理服务器上。平台的虚拟机解决方案基于开源组件 KubeVirt 实现,而 KubeVirt 默认采用名为 ProCopy 的模式执行热迁移。
ProCopy
ProCopy(Pre-Copy Memory Migration) 是一种常用的虚拟机迁移技术,通过预先复制虚拟机的内存数据,确保迁移过程中服务的连续性。具体过程如下:
- 初始阶段:在迁移开始时,源主机会将虚拟机的内存页复制到目标主机,同时虚拟机继续运行。由于虚拟机继续运行,部分内存页在复制过程中可能会被修改。
- 迭代复制:源主机会多次复制修改过的内存页到目标主机,直到修改的页数减少到一个可以接受的水平。每一轮复制称为一个迭代,每次迭代后未被修改的内存页数逐渐减少。
- 停止并复制:当剩余未复制的内存页数足够少时,虚拟机会短暂暂停(通常只有几秒到十几秒),在暂停期间,最后的内存页被复制到目标主机,并将虚拟机的 CPU 和设备状态同步到目标主机。
- 恢复运行:虚拟机在目标主机上恢复运行。
约束与限制
进行热迁移操作的两台物理机建议使用相同的硬件配置,若配置不一致(例如 CPU 型号不同),可能会导致迁移失败。
操作步骤
注意:下述所有命令均需在虚拟机所在集群的 master 节点上执行。
部署 kubevirt-operator
提示:具体步骤及参数说明请参考 部署 Operator 。
-
进入 平台管理。
-
在左侧导航栏中,单击 应用商店管理 > Operators。
-
单击页面最上方的 集群,切换至需要部署 Operator 的集群。
-
在 OperatorHub 页签中,单击 KubeVirt HyperConverged Cluster Operator 卡片上的 部署。
-
按需配置参数并单击 部署,可在 已部署 页签中查看 Operator 部署状态。
创建 HyperConverged 实例
具体创建步骤请参考 创建 HyperConverged 实例 。
更新配置
注意:执行此步骤前需确保已成功部署 kubevirt-operator。
-
在 Kubevirt 所在集群的 Master 节点上创建名称为 kubevirt-config-update.sh 的脚本文件,并将下述命令复制到此脚本文件中。
#!/bin/bash # Check if the image repository address is provided if [ -z "$1" ]; then echo "Please provide the image repository address as a parameter, e.g., ./script.sh 192.168.1.100:10443" exit 1 fi IMAGE_REPO=$1 # Get the name of the first virt-operator pod POD_NAME=$(kubectl get pods -n kubevirt -l name=virt-operator -o jsonpath='{.items[0].metadata.name}') if [ -z "$POD_NAME" ]; then echo "Failed to get the name of the virt-operator pod. Please check if kubevirt-operator is running properly." exit 1 fi # Get the Launcher image information VIRT_LAUNCHER_IMAGE=$(kubectl get pod $POD_NAME -n kubevirt -o yaml | grep -A1 VIRT_LAUNCHER_IMAGE | grep value | awk '{print $2}') if [ -z "$VIRT_LAUNCHER_IMAGE" ]; then echo "Failed to get VIRT_LAUNCHER_IMAGE. Please check if kubevirt-operator is running properly." exit 1 fi # Replace build-harbor.alauda.cn with the provided IMAGE_REPO in VIRT_LAUNCHER_IMAGE NEW_VIRT_LAUNCHER_IMAGE=$(echo $VIRT_LAUNCHER_IMAGE | sed "s|build-harbor.alauda.cn|$IMAGE_REPO|") # Create patch.json file cat <<EOF > patch.json [ { "op": "add", "path": "/spec/config", "value": { "env": [] } }, { "op": "add", "path": "/spec/config/env/-", "value": { "name": "VIRT_LAUNCHER_IMAGE", "value": "$NEW_VIRT_LAUNCHER_IMAGE" } } ] EOF # Execute kubectl patch command kubectl patch subscriptions.operators.coreos.com kubevirt-operator -n kubevirt --type='json' -p "$(cat patch.json)" # Check if the command was successful if [ $? -eq 0 ]; then echo "Successfully updated VIRT_LAUNCHER_IMAGE to $NEW_VIRT_LAUNCHER_IMAGE" else echo "Update failed. Please check the configuration and commands." exit 1 fi -
执行下述命令更新脚本配置。需要将当前环境的镜像仓库地址作为参数传递给脚本。
chmod +x kubevirt-config-update.sh ./kubevirt-config-update.sh <Registry Address> #需使用当前环境的镜像仓库地址替换 <Registry Address> 部分内容 -
脚本执行成功后,Operator 会自动更新 virt-controller 等 Kubevirt 组件。
注意:脚本执行完成后,请等待 10 分钟后再进行后续操作。
准备虚拟机
说明:推荐使用 Kube-OVN Underlay 网络,具体配置请参考 创建子网(Kube-OVN Underlay 网络) 。
-
进入 Container Platform。
-
在左侧导航栏中,单击 虚拟化 > 虚拟机。
-
单击 创建虚拟机。
-
单击 基本信息 区域的 更多 展开更多配置项,并单击 注解 对应的 添加,按照下述键值添加注解。
注意:由于表单中的限制,请先填写注解的 值 后,再填写注解的 键。
注解 值 true 键 kubevirt.io/allow-pod-bridge-network-live-migration -
按需配置其他虚拟机参数,具体参数说明请参考相应产品文档。
参数 说明 卷模式 必须使用 块模式。 存储类 必须使用 CephRBD 块存储类型的存储类。 网络模式 推荐使用 桥接。 -
单击 创建。
-
当虚拟机正常运行后,查看虚拟机的 YAML 文件,若
status.conditions字段中已经存在type: LiveMigratable的条件,且此条件下的status为 True,表示该虚拟机已经可以启动热迁移。
启动热迁移
注意:下述命令均需在虚拟机所在集群的 Master 节点执行。
-
在 CLI 工具中执行下述命令进行热迁移,此命令会触发虚拟机从当前节点迁移到目标节点。
kubectl create -f - << EOF apiVersion: kubevirt.io/v1 kind: VirtualMachineInstanceMigration metadata: name: migrate-vm namespace: <namespace> # 使用虚拟机所在命名空间替换 <namespace> 部分 spec: vmiName: <vm-name> # 使用虚拟机的名称替换 <vm-name> 部分 EOF -
执行下述命令查看迁移状态。
kubectl get -n <namespace> vmi <vm-name> -o yaml # 使用虚拟机所在命名空间替换 <namespace> 部分,使用虚拟机的名称替换 <vm-name> 部分 -
通过查看
status.migrationState字段可以监控迁移进度和状态。关于 migrationState 字段的详细说明请参考 官方网站文档 。