仮想マシンのトラブルシューティング

このページでは、Google Distributed Cloud(GDC)エアギャップ アプライアンスの Application Operator(AO)の仮想マシン(VM)のトラブルシューティングについて説明します。

ブートディスクがいっぱいの VM を復元する

たとえば、アプリケーションがブートディスク パーティションをログで埋め尽くすなど、VM のブートディスクの容量が不足すると、VM の重要な機能が動作しなくなります。VirtualMachineAccessRequest リソースを使用して新しい SSH 認証鍵を追加したり、既存の鍵を使用して VM への SSH 接続を確立したりできない場合があります。

このページでは、新しい VM を作成し、ディスクをアタッチして、コンテンツを追加ディスクとして新しい VM に復元する手順について説明します。これらの手順は、次のことを示しています。

  • 新しい VM への SSH 接続が成功していること。
  • ディスクをマウントして不要なデータを復元して削除し、容量を増やします。
  • 新しい VM を削除し、元のディスクを元の VM に置き換えます。

始める前に

続行する前に、プロジェクト レベルの VM アクセスをリクエストしてください。手順に沿って、プロジェクト仮想マシン管理者(project-vm-admin)ロールを割り当てます。

gdcloud CLI を使用した VM オペレーションの場合は、プロジェクト IAM 管理者に、プロジェクト VirtualMachine 管理者ロールとプロジェクト閲覧者(project-viewer)ロールの両方を割り当てるよう依頼してください。

gdcloud コマンドライン インターフェース(CLI)コマンドを使用するには、gdcloud CLI をダウンロード、インストール、構成していることを確認してください。GDC エアギャップ アプライアンスのすべてのコマンドは gdcloud または kubectl CLI を使用し、オペレーティング システム(OS)環境が必要です。

kubeconfig ファイルのパスを取得する

Management API サーバーに対してコマンドを実行するには、次のリソースがあることを確認します。

  1. Management API サーバー名を確認するか、プラットフォーム管理者(PA)にサーバー名を確認します。

  2. Management API サーバーの kubeconfig ファイルがない場合は、ログインして生成します。

  3. この手順では、パスを使用して MANAGEMENT_API_SERVER{"</var>"}} を置き換えます。

ディスクの空き容量が不足している VM ディスクを復元する

容量不足の VM ブートディスクを復元する手順は次のとおりです。

  1. VM を停止するの手順に沿って、既存の VM を停止します。

  2. 既存の VM を編集します。

    kubectl --kubeconfig ADMIN_KUBECONFIG edit \
        virtualmachine.virtualmachine.gdc.goog -n PROJECT VM_NAME
    

    spec フィールドの既存の VM ディスク名を新しいプレースホルダ名に置き換えます。

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME
    
  3. 元の VM と異なるイメージ オペレーティング システム(OS)を使用して新しい VM を作成します。たとえば、元のディスクが OS ubuntu-2004 を使用している場合は、rocky-8 を使用して新しい VM を作成します。

  4. 元のディスクを新しい VM に追加ディスクとしてアタッチします。

    ...
    spec:
      disks:
      - boot: true
        autoDelete: true
        virtualMachineDiskRef:
          name: NEW_VM_DISK_NAME
      - virtualMachineDiskRef:
          name: ORIGINAL_VM_DISK_NAME
    

    次のように置き換えます。

    • NEW_VM_DISK_NAME: 新しい VM ディスクに付ける名前。
    • ORIGINAL_VM_DISK_NAME: 元の VM ディスクの名前。
  5. VM を作成して実行したら、VM に接続するの手順に沿って VM への SSH 接続を確立します。

  6. ディレクトリを作成し、元のディスクをマウント ポイントにマウントします。例: /mnt/disks/new-disk

  7. 追加のスペースを使用して、マウント ディレクトリ内のファイルとディレクトリを確認します。

    cd /mnt/disks/MOUNT_DIR
    du -hs -- * | sort -rh | head -10
    

    MOUNT_DIR は、元のディスクをマウントしたディレクトリの名前に置き換えます。

    出力は次のようになります。

    18G   home
    1.4G  usr
    331M  var
    56M   boot
    5.8M  etc
    36K   snap
    24K   tmp
    16K   lost+found
    16K   dev
    8.0K  run
    
  8. 各ファイルとディレクトリを確認して、それぞれが使用している容量を確認します。この例では、home ディレクトリが 18G の容量を使用していることを確認します。

    cd home
    du -hs -- * | sort -rh | head -10
    

    出力は次のようになります。

    17G   log_file
    ...
    4.0K  readme.md
    4.0K  main.go
    

    たとえば、log_file17G の容量を消費しており、不要なため、クリアするファイルです。

  9. 余分な容量を消費している不要なファイルを削除するか、新しい VM ブートディスクにファイルをバックアップします。

    • 保存するファイルを移動します。

      mv /mnt/disks/MOUNT_DIR/home/FILENAME/home/backup/
      
    • 余分な容量を消費しているファイルを削除します。

      rm /mnt/disks/MOUNT_DIR/home/FILENAME
      

      FILENAME は、移動または削除するファイルの名前に置き換えます。

  10. 新しい VM からログアウトし、VM を停止します。

  11. 新しい VM を編集して、spec フィールドから元のディスクを削除します。

    kubectl --kubeconfig ADMIN_KUBECONFIG \
        edit virtualmachine.virtualmachine.gdc.goog -n PROJECT NEW_VM_NAME
    

    元の VM ディスク名を含む virtualMachineDiskRef リストを削除します。

    spec:
      disks:
      - autoDelete: true
        boot: true
        virtualMachineDiskRef:
          name: NEW_VM_DISK_NAME
      - virtualMachineDiskRef: # Remove this list
          name: ORIGINAL_VM_DISK_NAME # Remove this disk name
    
  12. 元の VM を編集し、ステップ 2 で設定した VM_DISK_PLACEHOLDER_NAME を前の名前に置き換えます。

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME # Replace this name with the previous VM name
    
  13. 元の VM を起動します。十分な空き容量を確保すると、VM が正常に起動します。

  14. 新しい VM が不要になった場合は、VM を削除します。

    kubectl --kubeconfig ADMIN_KUBECONFIG \
        delete virtualmachine.virtualmachine.gdc.goog -n PROJECT NEW_VM_NAME
    

仮想マシンをプロビジョニングする

このセクションでは、Google Distributed Cloud(GDC)エアギャップ アプライアンスで新しい仮想マシン(VM)をプロビジョニングする際に発生する可能性のある問題のトラブルシューティング方法について説明します。

アプリケーション オペレーター(AO)は、デフォルトのユーザー クラスタに対してすべてのコマンドを実行する必要があります。

ディスクを作成できません

PersistentVolumeClaim(PVC)が Pending 状態の場合は、次の代替案を確認して状態を解決します。

  • ストレージ クラスは、ReadWriteMany アクセスモードで PVC を作成することをサポートしていません。

    1. ReadWriteMany アクセスモードをサポートし、Container Storage Interface(CSI)ドライバをストレージ プロビジョナーとして使用するストレージ クラスを使用して、仮想マシンの spec.dataVolumeTemplate.spec.pvc.storageClassName 値を更新します。

    2. クラスタ上の他のストレージ クラスが ReadWriteMany 機能を提供できない場合は、spec.dataVolumeTemplate.spec.pvc.accessMode 値を更新して ReadWriteOnce アクセスモードを含めます。

  • CSI ドライバが PersistentVolume をプロビジョニングできない:

    1. エラー メッセージを確認します。

      kubectl describe pvc VM_NAME-boot-dv -n NAMESPACE_NAME
      

      次の変数を置き換えます。

      • VM_NAME: 仮想マシンの名前。
      • NAMESPACE_NAME: Namespace の名前。
    2. エラーを解決するようにドライバを構成します。PersistentVolume プロビジョニングが機能することを確認するには、dataVolumeTemplate.spec.pvc で指定された名前とは異なる名前で、新しい spec にテスト PVC を作成します。

      cat <<EOF | kubectl apply -
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: test-pvc
        namespace: NAMESPACE_NAME
      spec:
        storageClassName: standard-rwx
        accessModes:
        - ReadWriteMany
        resources:
          requests:
            storage: 10Gi
      EOF
      
    3. PersistentVolume オブジェクトのプロビジョニングが成功したら、検証後にテスト PVC を削除します。

      kubectl delete pvc test-pvc -n NAMESPACE_NAME
      

仮想マシンを作成できない

仮想マシン リソースが適用されても Running 状態にならない場合は、次の手順を行います。

  1. 仮想マシンのログを確認します。

    kubectl get vm VM_NAME -n NAMESPACE_NAME
    
  2. 仮想マシンの対応する Pod のステータスを確認します。

    kubectl get pod -l kubevirt.io/vm=VM_NAME
    

    出力に Pod のステータスが表示されます。使用できるオプションは次のとおりです。

ContainerCreating 状態

Pod が ContainerCreating 状態の場合は、次の手順を行います。

  1. Pod の状態に関する詳細情報を取得します。

    kubectl get pod -l kubevirt.io/vm=VM_NAME
    
  2. ボリュームがマウント解除されている場合は、spec.volumes フィールドで指定されたすべてのボリュームが正常にマウントされていることを確認します。ボリュームがディスクの場合は、ディスクのステータスを確認します。

  3. spec.accessCredentials フィールドは、SSH 公開鍵をマウントする値を指定します。Secret が仮想マシンと同じ Namespace に作成されていることを確認します。

Pod を作成するのに十分なリソースがクラスタにない場合は、次の操作を行います。

  1. クラスタに仮想マシン Pod をスケジュールするのに十分なコンピューティング リソースがない場合は、他の不要な Pod を削除して、リソースの解放を試みます。

  2. 仮想マシンの spec.domain.resources.requests.cpu 値と spec.domain.resources.requests.memory 値を減らします。

Error 状態または CrashLoopBackoff 状態

Error 状態または CrashLoopBackoff 状態の Pod を解決するには、仮想マシン コンピューティング Pod からログを取得します。

kubectl logs -l  kubevirt.io/vm=VM_NAME  -c compute

Running 状態と仮想マシンの障害

Pod が Running 状態でも仮想マシン自体が失敗した場合は、次の操作を行います。

  1. 仮想マシンログ Pod のログを表示します。

    kubectl logs -l  kubevirt.io/vm=VM_NAME  -c log
    
  2. ログに仮想マシンの起動エラーが表示された場合は、仮想マシンの正しい起動デバイスを確認します。プライマリ ブートディスクの spec.domain.devices.disks.bootOrder 値を 1 の値に設定します。次の例を参考にしてください。

      spec:
          domain:
            devices:
              disks:
              - bootOrder: 1
                disk:
                  bus: virtio
                name: VM_NAME-boot-dv
      

仮想マシン イメージの構成に関する問題のトラブルシューティングを行うには、別のイメージを使用して別の仮想マシンを作成します。

シリアル コンソールにアクセスする

このセクションでは、VM インスタンスのシリアル コンソールを使用して、起動やネットワークの問題のデバッグ、不具合のあるインスタンスのトラブルシューティング、Grand Unified Bootloader(GRUB)の操作、その他のトラブルシューティングを実行する方法について説明します。

シリアルポートの操作は、入力と出力がテキストモードになり、グラフィカル ユーザー インターフェースに対応していないという点で、ターミナル ウィンドウを使用する場合に似ています。インスタンスのオペレーティング システム(OS)、基本入出力(BIOS)は、多くの場合、出力をシリアルポートに書き込み、コマンドなどの入力を受け入れます。

シリアル コンソールにアクセスするには、次のセクションをご覧ください。

ユーザー名とパスワードを構成する

デフォルトでは、GDC Linux システム イメージは、ローカル ユーザーにパスワード ベースのログインを許可するように構成されていません。

シリアル コンソールのログインが事前に構成されたイメージを VM で実行している場合は、VM にローカル パスワードを設定して、シリアル コンソールからログインできます。GDC Linux VM では、VM の作成中または作成後に Kubernetes Secret として保存された起動スクリプトを使用して、ユーザー名とパスワードを構成します。

以下では、VM の作成後にローカル パスワードを設定する方法について説明します。ユーザー名とパスワードを構成する手順は次のとおりです。

  1. テキスト ファイルを作成します。
  2. テキスト ファイルで、ユーザー名とパスワードを構成します。

    #!/bin/bash
    username="USERNAME"
    password="PASSWORD"
    sudo useradd -m -s /bin/bash "$username"
    echo "$username:$password" | sudo chpasswd
    sudo usermod -aG sudo "$username"
    

    次のように置き換えます。

    • USERNAME: 追加するユーザー名。
    • PASSWORD: ユーザー名のパスワード。一部の OS では最小限のパスワードの長さと複雑さが必要になることがあるため、基本的なパスワードは使用しないでください。
  3. 起動スクリプトを Kubernetes Secret として作成します。

    kubectl --kubeconfig=ADMIN_KUBECONFIG create secret \
    generic STARTUP_SCRIPT_NAME -n PROJECT_NAMESPACE \
    --from-file=STARTUP_SCRIPT_PATH
    

    次のように置き換えます。

    • PROJECT_NAMESPACE: VM が存在するプロジェクトの Namespace。
    • STARTUP_SCRIPT_NAME: the name you give to the startup script. For example,configure-credentials`。
    • STARTUP_SCRIPT_PATH: 構成したユーザー名とパスワードを含む起動スクリプトのパス。
  4. VM を停止します

  5. VM の仕様を編集します。

    kubectl --kubeconfig=ADMIN_KUBECONFIG edit gvm \
    -n PROJECT_NAMESPACE VM_NAME
    

    VM_NAME は、起動スクリプトに追加する VM の名前に置き換えます。

  6. startupScripts フィールドに、手順 3 で作成した Kubernetes Secret 参照を追加します。

    spec:
      compute:
        memory: 8Gi
        vcpus: 8
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: disk-name 
      startupScripts:
      - name: STARTUP_SCRIPT_NAME
        scriptSecretRef:
          name: STARTUP_SCRIPT_NAME
    
  7. VM を起動します

    • 新しい VM を操作している場合は、この手順をスキップします。

VM シリアル コンソールにアクセスする

VM シリアル コンソールへのアクセスを開始する手順は次のとおりです。

  1. シリアル コンソールに接続します。

    gdcloud compute connect-to-serial-port VM_NAME \
    --project PROJECT_NAMESPACE
    
  2. プロンプトが表示されたら、ユーザー名とパスワードを構成するで定義したユーザー名とパスワードを入力します。