教程:使用 GDC 上的虚拟机运行时在 GKE on Bare Metal 集群中部署现有虚拟机


本文档提供了使用 VM Runtime on GDC 将基于虚拟机 (VM) 的工作负载部署到 GKE on Bare Metal 的分步指南。该指南中使用的工作负载是示例销售终端应用。此应用代表在零售店的本地硬件上运行的典型销售终端

在本文档中,您需要将此应用从虚拟机迁移到 GKE on Bare Metal 集群,并访问应用的 Web 前端。如需将现有虚拟机迁移到集群中,必须先创建该虚拟机的磁盘映像。然后,该映像必须托管在集群可以访问的代码库中。最后,该映像的网址可用于创建虚拟机。GDC 上的 VM Runtime 要求映像采用 qcow2 格式。如果您提供其他映像类型,则会自动转换为 qcow2 格式。为避免重复转换并启用重复使用功能,您可以转换虚拟磁盘映像并托管 qcow2 映像。

本文档使用预先准备的 Compute Engine 虚拟机实例映像,其中工作负载以 systemd 服务的形式运行。您可以按照相同的步骤部署自己的应用。

目标

准备工作

如需完成本文档,您需要以下资源:

  • 访问 GKE on Bare Metal 1.12.0 版或更高版本的集群,这是按照使用手动负载平衡器在 Compute Engine 虚拟机上运行 GKE on Bare Metal 指南创建的。本文档会设置网络资源,以便您可以通过浏览器访问虚拟机内运行的工作负载。如果您不需要该行为,则可以使用任何 GKE on Bare Metal 来按照本文档进行操作。
  • 满足以下要求的工作站:
    • 有权使用 bmctl CLI 访问集群。
    • 有权使用 kubectl CLI 访问集群。

在 GDC 上启用虚拟机运行时并安装“virtctl”插件

从 1.10 版开始,GDC 上的虚拟机运行时自定义资源定义 (CRD) 是所有 GKE on Bare Metal 集群的一部分。安装时,系统已创建一个 VMRuntime 自定义资源的实例。但默认处于停用状态。

  1. 在 GDC 上启用虚拟机运行时:

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH:GKE on Bare Metal 用户集群的 Kubernetes 配置文件的路径
  2. 验证 VMRuntime 是否已启用:

    kubectl wait --for=jsonpath='{.status.ready}'=true vmruntime vmruntime
    

    VMRuntime 可能需要几分钟才能准备就绪。如果不可用,请在短暂延迟后多检查几次。以下示例输出显示 VMRuntime 已准备就绪:

    vmruntime.vm.cluster.gke.io/vmruntime condition met
    
  3. kubectl 安装 virtctl 插件:

    sudo -E bmctl install virtctl
    

    以下示例输出显示 virtctl 插件安装过程已完成:

    Please check the logs at bmctl-workspace/log/install-virtctl-20220831-182135/install-virtctl.log
    [2022-08-31 18:21:35+0000] Install virtctl succeeded
    
  4. 验证 virtctl 插件的安装:

    kubectl virt
    

    以下示例输出显示 virtctl 插件可用于 kubectl

    Available Commands:
      addvolume         add a volume to a running VM
      completion        generate the autocompletion script for the specified shell
      config            Config subcommands.
      console           Connect to a console of a virtual machine instance.
      create            Create subcommands.
      delete            Delete  subcommands.
    ...
    

部署基于虚拟机的工作负载

将虚拟机部署到 GKE on Bare Metal 时,GDC 上的 VM Runtime 需要虚拟机映像。此映像用作已部署虚拟机的启动磁盘。

在本教程中,您需要将基于 Compute Engine 虚拟机的工作负载迁移到 GKE on Bare Metal 集群。此 Compute Engine 虚拟机已创建,并且示例销售终端 (PoS) 应用已配置为作为 systemd 服务运行。在 Google Cloud 中创建了此虚拟机的磁盘映像以及 PoS 应用工作负载。然后,此映像作为 qcow2 映像导出到 Cloud Storage 存储桶。您将在以下步骤中使用预先准备好的 qcow2 映像。

本文档中的源代码可在 anthos-samples GitHub 代码库中找到。您可以使用此代码库中的资源来完成后续步骤。

  1. 部署 MySQL StatefulSet。销售终端应用应连接到 MySQL 数据库以存储库存和付款信息。销售终端代码库包含一个示例清单,该清单会部署 MySQL StatefulSet、配置关联的 ConfigMap 和 Kubernetes ServiceConfigMap 定义了 MySQL 实例的凭据,这些凭据与传递到销售终端应用的凭据相同

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. 使用预先准备的 qcow2 映像部署虚拟机工作负载:

    kubectl virt create vm pos-vm \
        --boot-disk-size=80Gi \
        --memory=4Gi \
        --vcpu=2 \
        --image=https://storage.googleapis.com/pos-vm-images/pos-vm.qcow2
    

    此命令会创建以虚拟机 (google-virtctl/pos-vm.yaml) 命名的 YAML 文件。您可以检查该文件,以查看 VirtualMachineVirtualMachineDisk 的定义。您可以使用 Kubernetes 资源模型 (KRM) 定义部署虚拟机工作负载,而不是使用 virtctl 插件,如已创建的 YAML 文件中所示。

    此命令成功运行后,会生成如下例所示的输出,其中说明了已创建的不同资源:

    Constructing manifest for vm "pos-vm":
    Manifest for vm "pos-vm" is saved to /home/tfadmin/google-virtctl/pos-vm.yaml
    Applying manifest for vm "pos-vm"
    Created gvm "pos-vm"
    
  3. 检查虚拟机创建状态。

    VirtualMachine 资源由 GDC 上的虚拟机运行时中的 vm.cluster.gke.io/v1.VirtualMachine 资源标识。简写形式为 gvm

    创建虚拟机时,系统会创建以下两个资源:

    • VirtualMachineDisk 是在其中导入虚拟机映像内容的永久性磁盘。
    • VirtualMachine 是虚拟机实例本身。DataVolume 会在虚拟机启动之前装载到 VirtualMachine 中。

    检查 VirtualMachineDisk 的状态。VirtualMachineDisk 会在内部创建 DataVolume 资源。虚拟机映像会导入装载到虚拟机中的 DataVolume:

    kubectl get datavolume
    

    以下示例输出显示映像导入的开始:

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. 检查 VirtualMachine 的状态。VirtualMachine 处于 Provisioning 状态,直到 DataVolume 完全导入为止:

    kubectl get gvm
    

    以下示例输出显示正在预配 VirtualMachine

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. 等待虚拟机映像完全导入到 DataVolume。在映像导入期间,继续查看进度:

    kubectl get datavolume -w
    

    以下示例输出显示正在导入磁盘映像:

    NAME              PHASE              PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv   ImportInProgress   0.00%                 14s
    ...
    ...
    pos-vm-boot-dv   ImportInProgress   0.00%                 31s
    pos-vm-boot-dv   ImportInProgress   1.02%                 33s
    pos-vm-boot-dv   ImportInProgress   1.02%                 35s
    ...
    

    导入完成且 DataVolume 创建后,以下示例输出会显示 PHASESucceeded

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. 确认 VirtualMachine 已成功创建:

    kubectl get gvm
    

    如果创建成功,则 STATUS 会显示 RUNNING(如以下示例所示),虚拟机的 IP 地址也会显示:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

连接到虚拟机并检查应用状态

用于虚拟机的映像包含销售终端示例应用。该应用配置为在启动时作为 systemd 服务自动启动。您可以在 pos-systemd-services 目录中查看 systemd 服务的配置文件。

  1. 连接到虚拟机控制台。运行以下命令,并在看到 Successfully connected to pos-vm… 消息后按 Enter⏎ 键:

    kubectl virt console pos-vm
    

    此命令会生成以下示例输出,提示您输入登录详细信息:

    Successfully connected to pos-vm console. The escape sequence is ^]
    
    pos-from-public-image login:
    

    使用以下用户账号和密码。此帐号是在创建 GDC VirtualMachine 上的虚拟机运行时映像的原始虚拟机内设置的。

    • 登录用户名:abmuser
    • 密码:abmworks
  2. 检查销售终端应用服务的状态。销售终端应用包括三项服务:API、商品目录和付款。这些服务都作为系统服务运行。

    这三项服务都通过 localhost 相互连接。但是,该应用会使用在上一步中创建的 mysql-db Kubernetes 服务连接到 MySQL 数据库。此行为意味着虚拟机会自动连接到 PodsServices 所在的网络,从而实现虚拟机工作负载与其他容器化应用之间的无缝通信。您无需执行任何额外操作,即可从 GDC 上的虚拟机运行时部署的虚拟机访问 Kubernetes Services

    sudo systemctl status pos*
    

    以下示例输出显示这三项服务和根系统服务 pos.service 的状态:

    ● pos_payments.service - Payments service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_payments.service; enabled; vendor >
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 750 (payments.sh)
          Tasks: 27 (limit: 4664)
        Memory: 295.1M
        CGroup: /system.slice/pos_payments.service
                ├─750 /bin/sh /pos/scripts/payments.sh
                └─760 java -jar /pos/jars/payments.jar --server.port=8083
    
    ● pos_inventory.service - Inventory service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_inventory.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 749 (inventory.sh)
          Tasks: 27 (limit: 4664)
        Memory: 272.6M
        CGroup: /system.slice/pos_inventory.service
                ├─749 /bin/sh /pos/scripts/inventory.sh
                └─759 java -jar /pos/jars/inventory.jar --server.port=8082
    
    ● pos.service - Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos.service; enabled; vendor preset: e>
        Active: active (exited) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 743 (code=exited, status=0/SUCCESS)
          Tasks: 0 (limit: 4664)
        Memory: 0B
        CGroup: /system.slice/pos.service
    
    Jun 21 18:55:30 pos-vm systemd[1]: Starting Point of Sale Application...
    Jun 21 18:55:30 pos-vm systemd[1]: Finished Point of Sale Application.
    
    ● pos_apiserver.service - API Server of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_apiserver.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:31 UTC; 1h 10min ago
      Main PID: 751 (api-server.sh)
          Tasks: 26 (limit: 4664)
        Memory: 203.1M
        CGroup: /system.slice/pos_apiserver.service
                ├─751 /bin/sh /pos/scripts/api-server.sh
                └─755 java -jar /pos/jars/api-server.jar --server.port=8081
    
  3. 退出虚拟机。如需退出控制台连接,请按 Ctrl + ] 使用转义序列 ^]

访问基于虚拟机的工作负载

如果您的集群是按照在具有手动负载平衡器的 Compute Engine 虚拟机上运行 GKE on Bare Metal 指南设置的,则已经创建了名为 pos-ingressIngress 资源。此资源会将来自 Ingress 负载平衡器的外部 IP 地址的流量路由到销售终端示例应用的 API 服务器服务。

  1. 如果您的集群没有此 Ingress 资源,请通过应用以下清单来创建该集群:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-bm-gcp-terraform/resources/manifests/pos-ingress.yaml
    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: pos-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-server-svc
                port:
                  number: 8080
  2. 创建一个 Kubernetes Service 以将流量路由到虚拟机。Ingress 资源会将流量路由到此 Service

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-vmruntime/pos-service.yaml
    

    以下示例输出会确认 Service 的创建:

    service/api-server-svc created
    
    apiVersion: v1
    kind: Service
    metadata:
      name: api-server-svc
    spec:
      selector:
        kubevirt/vm: pos-vm
      ports:
      - protocol: TCP
        port: 8080
        targetPort: 8081
  3. 获取 Ingress 负载均衡器的外部 IP 地址。Ingress Loadbalancer 会根据 Ingress 资源规则路由流量。您已创建一条 pos-ingress 规则,可将请求转发到 API 服务器 Service。此 Service 会将请求转发到虚拟机:

    INGRESS_IP=$(kubectl get ingress/pos-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $INGRESS_IP
    

    以下示例输出显示 Ingress 负载均衡器的 IP 地址:

    172.29.249.159 # you might have a different IP address
    
  4. 在浏览器中使用 Ingress Loadbalancer IP 地址来访问应用。以下示例屏幕截图显示了包含两件商品的简单销售终端 kiosk。您可以点击商品(如果您想订购多件商品,可以多次点击),然后使用付款按钮下单。此体验表明,您已成功使用 GDC 上的 VM Runtime 将基于虚拟机的工作负载部署到 GKE on Bare Metal 集群。

销售终端应用界面
销售终端应用界面(点击图片可放大)

清理

您可以删除本教程中创建的所有资源,也可以仅删除虚拟机并保留可重复使用的资源。在 GKE on Bare Metal 中删除虚拟机详细介绍了可用选项。

全部删除

  • 删除 GDC 上的虚拟机运行时 VirtualMachine 以及所有资源:

    kubectl virt delete vm pos-vm --all
    

    以下示例输出会确认删除:

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
        Deleted VirtualMachineDisk "pos-vm-boot-dv".
    

仅删除虚拟机

  • 仅删除虚拟机会保留创建的 VirtualMachineDisk。这样可以重复使用虚拟机映像,并节省在创建新虚拟机时导入映像所花费的时间。

    kubectl virt delete vm pos-vm
    

    以下示例输出会确认删除:

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
    

后续步骤

  • 本指南中使用的原始虚拟机是运行 Ubuntu 20.04 LTS 的 Compute Engine 实例。此虚拟机的映像可通过 pos-vm-images Cloud Storage 存储桶公开访问。如需详细了解如何配置虚拟机及其映像的创建方式,请参阅销售终端代码库中的说明。
  • 使用 kubectl virt create vm pos-vm 命令在 GKE on Bare Metal 集群中创建虚拟机时,系统会创建一个以虚拟机 (google-virtctl/pos-vm.yaml) 命名的 YAML 文件。您可以检查该文件,以查看 VirtualMachineVirtualMachineDisk 的定义。您可以使用 KRM 定义部署虚拟机,而不是使用 virtctl 插件,如已创建的 YAML 文件中所示。