チュートリアル: GDC 上の VM ランタイムを使用して既存の VM をクラスタにデプロイする


このドキュメントでは、GDC 上の VM ランタイムを使用して、ベアメタル上の Google Distributed Cloud(ソフトウェアのみ)のインストールに仮想マシン(VM)ベースのワークロードをデプロイする手順を説明します。このガイドで使用するワークロードは、POS アプリケーションのサンプルです。このアプリケーションは、小売店のオンプレミス ハードウェアで動作する一般的なPOS 端末です。

このドキュメントでは、アプリケーションを VM からクラスタに移行し、アプリケーションのウェブ フロントエンドにアクセスします。既存の VM をクラスタに移行するには、まずその VM のディスク イメージを作成する必要があります。次に、クラスタがアクセスできるリポジトリでイメージをホストします。最後に、そのイメージの URL を使用して VM を作成します。GDC 上の VM ランタイムでは、イメージが qcow2 形式であることを前提としています。別のイメージタイプを指定すると、自動で qcow2 形式に変換されます。何度も変換するのではなく再利用できるようにするには、仮想ディスク イメージを変換して qcow2 イメージをホストします。

このドキュメントでは、ワークロードが systemd サービスとして実行される Compute Engine VM インスタンスの事前に準備されたイメージを使用します。独自のアプリケーションをデプロイするために、同じ手順を実行できます。

目標

始める前に

このドキュメントの内容を実施するには、次のリソースが必要です。

  • 手動ロードバランサを使用してインストールするの手順で作成されたバージョン 1.12.0 以降のベアメタル クラスタへのアクセス権。このドキュメントでは、VM 内で実行されているワークロードにブラウザからアクセスできるようにネットワーキング リソースを設定しています。この設定が必要ない場合、こベアメタルの任意の Google Distributed Cloud を使用できます。
  • 次の要件を満たすワークステーション。
    • bmctl CLI を使用してクラスタにアクセスできる。
    • kubectl CLI を使用してクラスタにアクセスできる。

GDC 上の VM ランタイムを有効にして virtctl プラグインをインストールする

GDC のカスタム リソース定義上の VM ランタイムは、バージョン 1.10 以降のすべてのベアメタル クラスタの一部です。カスタム リソース 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 ベースのワークロードをデプロイする

ベアメタル上の Google Distributed Cloud(ソフトウェアのみ)のインストールに VM をデプロイする場合、GDC 上の VM ランタイムは VM イメージを必要とします。このイメージは、デプロイされた VM のブートディスクとして機能します。

このチュートリアルでは、Compute Engine の VM ベースのワークロードをクラスタに移行します。Compute Engine のこの VM は、サンプル POS(PoS)アプリケーションが systemd サービスとして実行されるように作成および構成されています。 Google Cloudでは、この VM のディスク イメージと PoS アプリケーション ワークロードが作成されました。その後、このイメージは qcow2 イメージとして Cloud Storage バケットにエクスポートされました。この準備済みの qcow2 イメージを、以下の手順で使用します。

このドキュメントのソースコードは、anthos-samples GitHub リポジトリで入手できます。このリポジトリのリソースを使用して次の手順を実施します。

  1. MySQL StatefulSet をデプロイします。POS アプリケーションは、在庫とお支払い情報を格納するために MySQL データベースに接続されることを想定しています。POS リポジトリには、MySQL StatefulSet をデプロイし、関連する ConfigMap と Kubernetes Service を構成するサンプル マニフェストがあります。ConfigMap は、MySQL インスタンスの認証情報を定義します。これは、POS アプリケーションに渡されるものと同じ認証情報です。

    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(google-virtctl/pos-vm.yaml)の名前が付いた YAML ファイルが作成されます。ファイルを調べると、VirtualMachineVirtualMachineDisk の定義を確認できます。virtctl プラグインを使用する代わりに、作成した YAML ファイルに記載されている Kubernetes リソースモデル(KRM)定義を使用して VM ワークロードをデプロイすることもできます。

    コマンドが正常に実行されると、作成されたさまざまなリソースを説明する次の例のような出力が生成されます。

    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 リソースは、GDC 上の VM ランタイムの vm.cluster.gke.io/v1.VirtualMachine リソースで識別されます。短縮形式は gvm です。

    VM の作成時に、次の 2 つのリソースが作成されます。

    • VirtualMachineDisk は、VM イメージのコンテンツがインポートされる永続ディスクです。
    • VirtualMachine は、VM インスタンスそのものです。VM が起動する前に、DataVolumeVirtualMachine にマウントされます。

    VirtualMachineDisk のステータスを確認します。VirtualMachineDisk では、内部に DataVolume リソースが作成されます。VM イメージは、VM にマウントされている DataVolume にインポートされます。

    kubectl get datavolume
    

    次の出力例は、イメージのインポートの開始を示しています。

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. VirtualMachine のステータスを確認します。DataVolume が完全にインポートされるまで、VirtualMachineProvisioning 状態になります。

    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
    

    作成が成功した場合、VM の IP アドレスとともに、次の例に示すように、STATUSRUNNINGを示します。

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

VM に接続してアプリケーションのステータスを確認する

VM に使用されるイメージには、POS サンプル アプリケーションが含まれています。 アプリケーションは、起動時に systemd サービスとして自動的に開始するように構成されています。systemd サービスの構成ファイルは、pos-systemd-services ディレクトリにあります。

  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:
    

    次のユーザー アカウントとパスワードを使用します。このアカウントは、GDC 上の VM ランタイム VirtualMachine のイメージが作成された元の VM 内で設定されたものです。

    • ログイン ユーザー名: abmuser
    • パスワード: abmworks
  2. POS アプリケーション サービスのステータスを確認します。POS アプリケーションには、API、在庫、支払いの 3 つのサービスが含まれています。これらのサービスはすべてシステム サービスとして実行されます。

    3 つのサービスはすべてローカルホストを介して相互に接続されます。ただし、アプリケーションは、前の手順で作成した mysql-db Kubernetes Service を使用して MySQL データベースに接続されます。この動作は、VM が PodsServices と同じネットワークに自動的に接続され、VM ワークロードと他のコンテナ化されたアプリケーション間でシームレスな通信が可能になることを意味します。GDC 上の VM ランタイムを使用してデプロイされた VM から Kubernetes Services にアクセスできるようにするために、追加の操作は必要ありません。

    sudo systemctl status pos*
    

    次の出力例では、3 つのサービスとルートシステム サービス 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-ingress という名前の Ingress リソースがすでに作成されています。このリソースは、Ingress ロードバランサの外部 IP アドレスから、POS サンプル アプリケーションの 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. VM にトラフィックをルーティングする 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 ロードバランサは、Ingress リソースルールに基づいてトラフィックを転送します。API サーバー Service にリクエストを転送するための pos-ingress ルールはすでに存在します。この 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 アドレスを使用して、アプリケーションにアクセスします。次のスクリーンショットが示すのは、2 つの商品を含むシンプルな POS キオスクの例です。商品を複数注文する場合は、商品を複数回クリックして [支払う] ボタンで注文を実行します。この例では、GDC 上の VM ランタイムを使用して VM ベースのワークロードをクラスタに正常にデプロイできたことがわかります。

POS アプリケーションの UI
POS アプリケーションの UI(イメージをクリックして拡大する)

クリーンアップ

このチュートリアルで作成したすべてのリソースは削除することも、VM のみを削除して再利用可能なリソースを保持することもできます。VM を削除するで、使用可能なオプションについて詳しく説明します。

すべてを削除する

  • GDC 上の VM ランタイム 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".
    

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 インスタンスです。この VM のイメージは、pos-vm-images Cloud Storage バケットから一般公開されています。どのように VM が構成されイメージが作成されたかについては、POS リポジトリの手順をご覧ください。
  • コマンド kubectl virt create vm pos-vm を使用してクラスタに VM を作成すると、VM にちなんで名付けられた(google-virtctl/pos-vm.yaml)YAML ファイルが作成されます。このファイルを調べると、VirtualMachineVirtualMachineDisk の定義を確認できます。virtctl プラグインを使用する代わりに、作成した YAML ファイルに記載されている KRM 定義を使用して VM をデプロイできます。