教學課程:使用 VM Runtime on GDC 在叢集中部署現有 VM


本文提供逐步指南,說明如何使用 GDC 的 VM Runtime,在裸機上安裝的 Google Distributed Cloud (僅限軟體) 中,部署以虛擬機器 (VM) 為基礎的工作負載。本指南使用的工作負載是銷售點應用程式範例。這項應用程式代表典型的銷售點終端機,在零售商店的內部部署硬體上執行。

本文將說明如何將這個應用程式從 VM 遷移至叢集,並存取應用程式的網頁前端。如要將現有 VM 遷移至叢集,請先建立該 VM 的磁碟映像檔。然後,映像檔必須託管在叢集可存取的存放區中。最後,您可以使用該映像檔的網址建立 VM。GDC 上的 VM Runtime 支援 qcow2 格式的映像檔。如果提供其他類型的圖片,系統會自動轉換成 qcow2 格式。為避免重複轉換,並啟用重複使用功能,您可以轉換虛擬磁碟映像檔,並代管 qcow2 映像檔。

本文使用預先準備的 Compute Engine VM 執行個體映像檔,其中工作負載會以 systemd 服務的形式執行。您可以按照相同的步驟部署自己的應用程式。

目標

事前準備

如要完成本文件,您需要下列資源:

  • 存取版本 1.12.0 以上的裸機叢集,該叢集是按照「使用手動 Loadbalancer 安裝」指南建立。本文會設定網路資源,讓您透過瀏覽器存取在 VM 中執行的工作負載。如果不需要這種行為,您可以使用任何安裝在裸機上的 Google Distributed Cloud,按照本文操作。
  • 符合下列條件的工作站:
    • 使用 bmctl CLI 存取叢集。
    • 使用 kubectl CLI 存取叢集。

在 GDC 上啟用 VM Runtime,並安裝 virtctl 外掛程式

自 1.10 版起,GDC 自訂資源定義中的 VM 執行階段已成為所有裸機叢集的一部分。安裝時,系統會建立 VMRuntime 自訂資源的執行個體。不過,這項功能預設為停用。

  1. 在 GDC 上啟用 VM 執行階段:

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH使用者叢集 kubeconfig 檔案的路徑。
  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.
    ...
    

部署 VM 型工作負載

在 Bare Metal 上部署 Google Distributed Cloud (僅限軟體) 安裝項目時,GDC 的 VM Runtime 會預期使用 VM 映像檔。這個映像檔會做為部署的 VM 的開機磁碟。

在本教學課程中,您會將以 Compute Engine VM 為基礎的工作負載遷移至叢集。這個 Compute Engine VM 已建立,且銷售點 (PoS) 應用程式範例已設定為以 systemd 服務的形式執行。已建立這個 VM 的磁碟映像檔,以及 PoS 應用程式工作負載 Google Cloud。然後匯出至 Cloud Storage bucket,並儲存為 qcow2 圖片。您會在後續步驟中使用這個預先準備的 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 映像檔部署 VM 工作負載:

    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
    

    這個指令會建立以 VM 命名的 YAML 檔案 (google-virtctl/pos-vm.yaml)。您可以檢查該檔案,查看 VirtualMachineVirtualMachineDisk 的定義。您可以使用 Kubernetes 資源模型 (KRM) 定義部署 VM 工作負載,而不必使用 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. 檢查 VM 建立狀態。

    VirtualMachine 資源是由 VM Runtime on GDC 中的 vm.cluster.gke.io/v1.VirtualMachine 資源所識別。簡短形式為 gvm

    建立 VM 時,系統會建立下列兩項資源:

    • VirtualMachineDisk 是永久磁碟,VM 映像檔的內容會匯入其中。
    • VirtualMachine 是指 VM 執行個體本身。DataVolume 會在 VM 啟動前掛接到 VirtualMachine

    檢查 VirtualMachineDisk 的狀態。VirtualMachineDisk 會在內部建立 DataVolume 資源。VM 映像檔會匯入 DataVolume,並掛接至 VM:

    kubectl get datavolume
    

    以下範例輸出內容顯示圖片匯入作業的開始時間:

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. 檢查 VirtualMachine 的狀態。DataVolume 完全匯入前,VirtualMachine 會處於 Provisioning 狀態:

    kubectl get gvm
    

    以下範例輸出內容顯示正在佈建 VirtualMachine

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. 等待 VM 映像檔完全匯入 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 後,以下範例輸出內容會顯示 SucceededPHASE

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. 確認 VirtualMachine 是否已建立成功:

    kubectl get gvm
    

    如果建立成功,STATUS 會顯示 RUNNING,如下列範例所示,以及 VM 的 IP 位址:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

連線至 VM 並檢查應用程式狀態

VM 使用的映像檔包含銷售點範例應用程式。應用程式已設為在開機時自動啟動,做為 systemd 服務。您可以在 pos-systemd-services 目錄中查看 systemd 服務的設定檔。

  1. 連線至 VM 控制台。看到 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:
    

    請使用以下使用者帳戶和密碼。這個帳戶是在原始 VM 內設定,而該 VM 是用來建立 GDC VirtualMachine 上 VM Runtime 的映像檔。

    • 登入使用者名稱:abmuser
    • 密碼:abmworks
  2. 檢查銷售點應用程式服務的狀態。銷售點應用程式包含三項服務:API、Inventory 和 Payments。這些服務都會以系統服務的形式執行。

    這三項服務都會透過 localhost 彼此連線。不過,應用程式會使用在先前步驟中建立的 mysql-db Kubernetes 服務連線至 MySQL 資料庫。這表示 VM 會自動連線至與 PodsServices 相同的網路,讓 VM 工作負載和其他容器化應用程式之間的通訊暢行無阻。如要讓 Kubernetes Services 可從使用 VM Runtime on GDC 部署的 VM 存取,您不需要進行任何額外操作。

    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. 退出 VM。如要結束主控台連線,請按下 Ctrl + ],使用逸出序列 ^]

存取 VM 型工作負載

如果您的叢集是按照「使用手動負載平衡器安裝」指南設定,則已建立名為 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,將流量轉送至 VM。Ingress 資源會將流量導向這個 Service

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

    下列範例輸出內容會確認服務已建立:

    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負載平衡器會根據 Ingress 資源規則轉送流量。您已具備 pos-ingress 規則,可將要求轉送至 API 伺服器 Service。這個 Service 會將要求轉送至 VM:

    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 負載平衡器 IP 位址存取應用程式。以下螢幕截圖範例顯示銷售點資訊亭,其中有兩項商品。你可以點選項目 (如要訂購多個項目,請點選多次),然後按一下「付款」按鈕下單。這項體驗顯示您已成功使用 GDC 上的 VM 執行階段,將以 VM 為基礎的工作負載部署至叢集。

銷售點應用程式 UI
銷售點應用程式 UI (按一下圖片即可放大)

清除所用資源

您可以刪除本教學課程中建立的所有資源,也可以只刪除 VM,並保留可重複使用的資源。「刪除 VM」一文會詳細說明可用的選項。

刪除所有

  • 刪除 GDC VirtualMachine 上的 VM Runtime 和所有資源:

    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".
    

僅刪除 VM

  • 只刪除 VM 會保留建立的 VirtualMachineDisk。 這樣一來,您就能重複使用這個 VM 映像檔,並在建立新 VM 時節省匯入映像檔的時間。

    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".
    

後續步驟

  • 本指南使用的原始 VM 是執行 Ubuntu 20.04 LTS 的 Compute Engine 執行個體。您可以透過 pos-vm-images Cloud Storage bucket 公開存取這個 VM 的映像檔。如要進一步瞭解 VM 的設定方式和映像檔的建立方式,請參閱銷售點存放區中的操作說明。
  • 使用 kubectl virt create vm pos-vm 指令在叢集中建立 VM 時,系統會建立以 VM 命名的 YAML 檔案 (google-virtctl/pos-vm.yaml)。您可以檢查檔案,查看 VirtualMachineVirtualMachineDisk 的定義。您可以使用 KRM 定義 (如建立的 YAML 檔案所示) 部署 VM,而不必使用 virtctl 外掛程式。