在 GKE on Bare Metal 中创建和管理虚拟磁盘

本文档适用于运行 GKE on Bare Metal 的应用所有者。本文档介绍了如何为在 GDC 上使用虚拟机运行时的虚拟机创建和管理磁盘资源。

准备工作

要完成本文档,您需要拥有以下资源的访问权限:

使用挂接磁盘创建虚拟机

创建虚拟机时,您可以挂接现有的启动磁盘或数据磁盘,通过映像(包括启动磁盘)创建磁盘,或者创建空白磁盘。

空白磁盘

在此情况下,您将创建一个空白磁盘并将其挂接到虚拟机。在此场景中,您可以创建数据磁盘来存储应用数据。

  1. 在您选择的编辑器中创建定义 VirtualMachineDiskVirtualMachine 的清单(例如 my-vm.yaml):

    nano my-vm.yaml
    
  2. 复制并粘贴以下 YAML 定义:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: DISK_NAME
    spec:
      size: 10Gi
    ---
    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      interfaces:
        - name: eth0
          networkName: pod-network
          default: true
      disks:
        - boot: true
          virtualMachineDiskName: VM_NAME-boot-dv
        - virtualMachineDiskName: DISK_NAME
    

    替换以下内容:

    • DISK_NAME:您要创建并挂接到虚拟机的空白磁盘的名称。

    • VM_NAME:您要创建的虚拟机的名称。

      本示例会创建一个名为 DISK_NAME 的空白 10Gi(10 吉比字节)磁盘。在虚拟机的 spec.disks 部分中,您还必须挂接启动磁盘,例如下一部分所示的映像。

  3. 在编辑器中保存并关闭清单文件。

  4. 使用 kubectl 创建虚拟机和磁盘:

    kubectl apply -f my-vm.yaml --kubeconfig KUBECONFIG
    

    KUBECONFIG 替换为集群 kubeconfig 文件的路径。

来源映像

在此场景中,您通过映像创建磁盘并将其挂接到虚拟机。在此场景中,您可以通过映像创建启动磁盘。您还可以通过映像创建和挂接数据磁盘。

支持的映像来源

GDC 上的 VM Runtime 支持多种映像格式,并且支持三种类型的映像来源(可在 VirtualMachineDisk 规范中指定)。以下每个示例都会通过不同的受支持映像来源创建 20 GiB 磁盘。

  • 超文本传输协议 (HTTP)

    以下 VirtualMachineDisk 示例显示了 HTTP 映像来源的基本结构。url 字段需要 HTTP 或 HTTPS 网址。

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: my-disk
    spec:
      source:
        http:
          url: https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img
      size: 20GiB
      storageClassName: local-shared
    
  • Cloud Storage

    以下示例展示了如何通过 Cloud Storage 存储桶中的映像创建磁盘。如果机器上的应用默认凭据不足以访问 Cloud Storage 网址,您必须提供凭据。在以下示例中,my-gcs 是包含 base64 编码的服务账号密钥的 Secret。

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: my-disk
    spec:
      source:
        gcs:
          url: gs://kubevirt-ci-vm-images/rhel8.2/rhel8_2_cloud.qcow2
          secretRef: my-gcs
      size: 20GiB
      storageClassName: local-shared
    

    如果您使用下载的服务账号密钥创建集群,则可以使用 Container Registry 服务账号密钥访问 Cloud Storage。如果创建单独的服务账号以访问 Cloud Storage,请参阅配置可访问 Cloud Storage 存储桶的服务账号

    使用以下命令从下载的服务账号密钥文件创建 Kubernetes Secret:

    kubectl create secret generic SECRET_NAME --from-file=KEY_FILE --namespace default \
        --kubeconfig KUBECONFIG
    

    替换以下内容:

    • SECRET_NAME:Secret 的名称。
    • KEY_FILE:下载的服务账号密钥 JSON 文件的路径。例如 bmctl-workspace/.sa-keys/my-project-anthos-baremetal-gcr.json
    • KUBECONFIG:集群 kubeconfig 文件的路径。

    如需详细了解如何使用凭据访问 Cloud Storage,请参阅创建和使用凭据从 Cloud Storage 导入映像

  • Container Registry 示例

    支持符合 Open Container Initiative (OCI) distribution-spec 的 Container Registry。以下示例通过存储在 Docker 存储库中的映像创建磁盘。

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: my-disk
    spec:
      source:
        registry:
          url: docker://kubevirt/fedora-cloud-registry-disk-demo
      size: 20GiB
      storageClassName: local-shared
    

有效的映像格式

从映像创建磁盘时,可以使用以下任何映像格式:

  • GNU zip (gzip) 归档 (.gz)
  • RAW(.raw.img
  • QEMU Copy On Write 版本 2 (qcow2) 磁盘映像 (.qcow2)
  • XZ 压缩归档 (.xz)
  • 虚拟机磁盘 (VMDK) 文件 (.vmdk)
  • VirtualBox Virtual Disk Image (VDI) 文件 (.vdi)
  • Virtual Hard Disk (VHD) 映像文件 (.vdh)
  • Virtual Hard Disk 版本 2 (VDHX) 文件 (.vdhx)
  • ISO 磁盘映像文件 (.iso)

通过 HTTP 映像创建的磁盘示例

以下步骤通过 Ubuntu 映像创建启动磁盘:

  1. 在您选择的编辑器中创建定义 VirtualMachineDiskVirtualMachine(例如 my-vm.yaml,)的清单:

    nano my-vm.yaml
    
  2. 复制并粘贴以下 YAML 定义:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_NAME-boot-dv
    spec:
      size: 20Gi
      source:
        http:
          url: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img
    ---
    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      interfaces:
        - name: eth0
          networkName: pod-network
          default: true
      disks:
        - boot: true
          virtualMachineDiskName: VM_NAME-boot-dv
    

    本示例会使用公共 Ubuntu 映像创建一个名为 VM_NAME-boot-dv20Gi(20 吉比字节)磁盘。在虚拟机的 spec.disks 部分中,磁盘设置为 boot: true

  3. 在编辑器中保存并关闭清单。

  4. 使用 kubectl 创建虚拟机和磁盘:

    kubectl apply -f my-vm.yaml --kubeconfig KUBECONFIG
    

    KUBECONFIG 替换为集群 kubeconfig 文件的路径。

现有磁盘

在此情况下,您将创建一个空白磁盘并将其挂接到虚拟机。在此场景中,您可以创建数据磁盘来存储应用数据。

  1. 在您选择的编辑器中创建 VirtualMachine 清单,例如 my-vm.yaml,

    nano my-vm.yaml
    
  2. 复制并粘贴以下 YAML 定义:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      interfaces:
        - name: eth0
          networkName: pod-network
          default: true
      disks:
        - boot: true
          virtualMachineDiskName: VM_NAME-boot-dv
        - virtualMachineDiskName: EXISTING_DISK_NAME
    

    此示例挂接了名为 EXISTING_DISK_NAME 的现有磁盘。

    在虚拟机的 spec.disks 部分中,您还必须挂接启动磁盘,例如上一部分所示的映像。

  3. 在编辑器中保存并关闭虚拟机清单。

  4. 使用 kubectl 创建虚拟机:

    kubectl apply -f my-vm.yaml --kubeconfig KUBECONFIG
    

    KUBECONFIG 替换为集群 kubeconfig 文件的路径。

查找磁盘

从 GKE on Bare Metal 版本 1.13.0 开始,当您创建虚拟机时,VM Runtime on GDC 会使用您在虚拟机资源中指定的磁盘名称来设置磁盘序列号。具体而言,您在 VirtualMachine 自定义资源中使用 spec.disks.virtualMachineDiskName 指定的名称将在磁盘序列号中使用。此功能可让您在需要执行磁盘操作(例如格式化或装载)时更轻松地在虚拟机中找到磁盘。

例如,如果您创建了虚拟机并指定了名为 sample-boot-dv 的启动磁盘,则 VirtualMachine 自定义资源如下所示:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: sample-vm
spec:
  osType: Linux
  compute:
    cpu:
      vcpus: 2
    memory:
      capacity: 4Gi
  interfaces:
    - name: eth0
      networkName: pod-network
      default: true
  disks:
    - boot: true
      virtualMachineDiskName: sample-vm-boot-dv
    - virtualMachineDiskName: attached-disk

对于 Linux 虚拟机,当您登录虚拟机时,可以运行以下命令来按磁盘序列号列出磁盘:

ls -l /dev/disk/by-id/

您的响应应类似于以下示例输出,其中磁盘名称显示为序列号:

total 0
lrwxrwxrwx 1 root root  9 Oct 19 17:17 ata-QEMU_HARDDISK_agentInstallation -> ../../sdb
lrwxrwxrwx 1 root root  9 Oct 19 17:17 ata-QEMU_HARDDISK_agentSADisk -> ../../sda
lrwxrwxrwx 1 root root  9 Oct 19 17:17 virtio-sample-boot-dv -> ../../vda
lrwxrwxrwx 1 root root 10 Oct 19 17:17 virtio-sample-boot-dv-part1 -> ../../vda1
lrwxrwxrwx 1 root root 11 Oct 19 17:17 virtio-sample-boot-dv-part14 -> ../../vda14
lrwxrwxrwx 1 root root 11 Oct 19 17:17 virtio-sample-boot-dv-part15 -> ../../vda15
lrwxrwxrwx 1 root root 11 Oct 19 17:17 virtio-attached-disk -> ../../vdb

请注意以下环境特征行为:

  • 如果 virtualMachineDiskName 值超过 20 个字符,GDC 上的 VM Runtime 仅使用前 20 个字符作为序列号。
  • 如果两个磁盘的前 20 个字符相同,则只有第一个磁盘具有序列号。

创建磁盘并将其挂接到现有虚拟机

如果您已有虚拟机,则可以创建并挂接磁盘以支持您的应用生命周期。虚拟机必须处于停止状态,才能挂接磁盘。

空白磁盘

在此情况下,您将创建一个空白磁盘并将其挂接到虚拟机。在此场景中,您可以创建数据磁盘来存储应用数据。

  1. 如果需要,请使用 kubectl 停止虚拟机:

    kubectl virt stop vm VM_NAME --kubeconfig KUBECONFIG
    

    替换以下内容:

    • VM_NAME:您要停止的虚拟机的名称。
    • KUBECONFIG:集群 kubeconfig 文件的路径。
  2. 修改现有虚拟机资源,例如 my-vm

    kubectl edit gvm VM_NAME --kubeconfig KUBECONFIG
    
  3. 更新 VirtualMachine YAML 清单以在顶部添加 VirtualMachineDisk 部分,然后在虚拟机的 spec.disks 部分的末尾挂接磁盘:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: DISK_NAME
    spec:
      size: 10Gi
    ---
    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      interfaces:
        - name: eth0
          networkName: pod-network
          default: true
      disks:
        - boot: true
          virtualMachineDiskName: VM_NAME-boot-dv
        - virtualMachineDiskName: DISK_NAME
    

    本示例会创建一个名为 DISK_NAME 的空白 10Gi(10 吉比字节)磁盘。

  4. 在编辑器中保存并关闭更新后的虚拟机清单。

  5. 使用 kubectl 启动虚拟机:

    kubectl virt start vm VM_NAME --kubeconfig KUBECONFIG
    

来源映像

在此场景中,您通过来源映像创建磁盘并将其挂接到虚拟机。

  1. 如果需要,请使用 kubectl 停止虚拟机:

    kubectl virt stop vm VM_NAME --kubeconfig KUBECONFIG
    

    替换以下内容:

    • VM_NAME:您要停止的虚拟机的名称。
    • KUBECONFIG:集群 kubeconfig 文件的路径。
  2. 修改现有虚拟机资源,例如 my-vm

    kubectl edit gvm VM_NAME --kubeconfig KUBECONFIG
    
  3. 更新 VirtualMachine 清单以在顶部添加 VirtualMachineDisk 部分,然后将磁盘挂接到虚拟机的 spec.disks 部分的末尾:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: DISK_NAME
    spec:
      size: 10Gi
      source:
        http:
          url: http://example.com/my-disk-img.qcow2
    ---
    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      interfaces:
        - name: eth0
          networkName: pod-network
          default: true
      disks:
        - boot: true
          virtualMachineDiskName: VM_NAME-boot-dv
        - virtualMachineDiskName: DISK_NAME
    

    本示例会从 http://example.com/my-disk-img.qcow2 HTTP 来源创建一个名为 DISK_NAME10Gi(10 吉比字节)磁盘。

  4. 在编辑器中保存并关闭更新后的虚拟机清单。

  5. 使用 kubectl 启动虚拟机:

    kubectl virt start vm VM_NAME --kubeconfig KUBECONFIG
    

创建磁盘

在此场景中,您可以独立于虚拟机资源创建磁盘资源。通过这种场景,您可以提前创建磁盘,然后根据需要挂接到虚拟机。

空白磁盘

如需创建空白磁盘,请完成以下步骤。

  1. 在您选择的编辑器中创建 VirtualMachineDisk 清单,例如 my-disk.yaml,

    nano my-disk.yaml
    
  2. 复制并粘贴以下 YAML 定义:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: DISK_NAME
    spec:
      size: 10Gi
    

    本示例会创建一个名为 DISK_NAME 的空白 10Gi(10 吉比字节)磁盘。

  3. 在编辑器中保存并关闭磁盘清单。

  4. 使用 kubectl 创建磁盘:

    kubectl apply -f my-disk.yaml --kubeconfig KUBECONFIG
    

    KUBECONFIG 替换为集群 kubeconfig 文件的路径。

来源映像

如需通过映像创建磁盘,请完成以下步骤。

  1. 在您选择的编辑器中创建 VirtualMachineDisk 清单,例如 my-disk.yaml

    nano my-disk.yaml
    
  2. 复制并粘贴以下 YAML 定义:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineDisk
    metadata:
      name: DISK_NAME
    spec:
      size: 20Gi
      source:
        http:
          url: https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img
    

    本示例会使用公共 Ubuntu 映像创建一个名为 DISK_NAME20Gi(20 吉比字节)磁盘。

  3. 在编辑器中保存并关闭磁盘清单。

  4. 使用 kubectl 创建磁盘:

    kubectl apply -f my-disk.yaml --kubeconfig KUBECONFIG
    

    KUBECONFIG 替换为集群 kubeconfig 文件的路径。

后续步骤