首页 / 平台管理 / 虚拟化管理 / 虚拟机热迁移

虚拟机热迁移

概述

虚拟机热迁移技术允许在不关闭或中断虚拟机的情况下,将虚拟机从一台物理服务器移动到另一台物理服务器上。平台的虚拟机解决方案基于开源组件 KubeVirt 实现,而 KubeVirt 默认采用名为 ProCopy 的模式执行热迁移。

ProCopy

ProCopy(Pre-Copy Memory Migration) 是一种常用的虚拟机迁移技术,通过预先复制虚拟机的内存数据,确保迁移过程中服务的连续性。具体过程如下:

  1. 初始阶段:在迁移开始时,源主机会将虚拟机的内存页复制到目标主机,同时虚拟机继续运行。由于虚拟机继续运行,部分内存页在复制过程中可能会被修改。
  2. 迭代复制:源主机会多次复制修改过的内存页到目标主机,直到修改的页数减少到一个可以接受的水平。每一轮复制称为一个迭代,每次迭代后未被修改的内存页数逐渐减少。
  3. 停止并复制:当剩余未复制的内存页数足够少时,虚拟机会短暂暂停(通常只有几秒到十几秒),在暂停期间,最后的内存页被复制到目标主机,并将虚拟机的 CPU 和设备状态同步到目标主机。
  4. 恢复运行:虚拟机在目标主机上恢复运行。

约束与限制

进行热迁移操作的两台物理机建议使用相同的硬件配置,若配置不一致(例如 CPU 型号不同),可能会导致迁移失败。

操作步骤

注意:下述所有命令均需在虚拟机所在集群的 master 节点上执行。

部署 kubevirt-operator

提示:具体步骤及参数说明请参考 部署 Operator

  1. 进入 平台管理

  2. 在左侧导航栏中,单击 应用商店管理 > Operators

  3. 单击页面最上方的 集群,切换至需要部署 Operator 的集群。

  4. 在 OperatorHub 页签中,单击 KubeVirt HyperConverged Cluster Operator 卡片上的 部署

  5. 按需配置参数并单击 部署,可在 已部署 页签中查看 Operator 部署状态。

创建 HyperConverged 实例

具体创建步骤请参考 创建 HyperConverged 实例

更新配置

注意:执行此步骤前需确保已成功部署 kubevirt-operator。

  1. 在 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
  2. 执行下述命令更新脚本配置。需要将当前环境的镜像仓库地址作为参数传递给脚本。

    chmod +x kubevirt-config-update.sh
    ./kubevirt-config-update.sh <Registry Address>  #需使用当前环境的镜像仓库地址替换 <Registry Address> 部分内容
  3. 脚本执行成功后,Operator 会自动更新 virt-controller 等 Kubevirt 组件。

    注意:脚本执行完成后,请等待 10 分钟后再进行后续操作。

准备虚拟机

说明:推荐使用 Kube-OVN Underlay 网络,具体配置请参考 创建子网(Kube-OVN Underlay 网络)

  1. 进入 Container Platform

  2. 在左侧导航栏中,单击 虚拟化 > 虚拟机

  3. 单击 创建虚拟机

  4. 单击 基本信息 区域的 更多 展开更多配置项,并单击 注解 对应的 添加,按照下述键值添加注解。

    注意:由于表单中的限制,请先填写注解的 后,再填写注解的

    注解
    true
    kubevirt.io/allow-pod-bridge-network-live-migration
  5. 按需配置其他虚拟机参数,具体参数说明请参考相应产品文档。

    参数 说明
    卷模式 必须使用 块模式
    存储类 必须使用 CephRBD 块存储类型的存储类
    网络模式 推荐使用 桥接
  6. 单击 创建

  7. 当虚拟机正常运行后,查看虚拟机的 YAML 文件,若 status.conditions 字段中已经存在 type: LiveMigratable 的条件,且此条件下的 status 为 True,表示该虚拟机已经可以启动热迁移。

启动热迁移

注意:下述命令均需在虚拟机所在集群的 Master 节点执行。

  1. 在 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
  2. 执行下述命令查看迁移状态。

    kubectl get -n <namespace> vmi <vm-name> -o yaml # 使用虚拟机所在命名空间替换 <namespace> 部分,使用虚拟机的名称替换 <vm-name> 部分
  3. 通过查看 status.migrationState 字段可以监控迁移进度和状态。关于 migrationState 字段的详细说明请参考 官方网站文档