クラスタの作成またはアップグレードのトラブルシューティング

このページでは、Google Distributed Cloud クラスタのインストールまたはアップグレードに関連する問題を解決する方法について説明します。

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

インストールに関する問題

以下のセクションでは、Google Distributed Cloud のインストールに関する問題のトラブルシューティングに役立つ情報を提供します。

一時的なエラー メッセージ

Google Distributed Cloud のインストール プロセスは継続的な調整ループです。そのため、インストール中に、一時的なエラー メッセージがログに表示されることがあります。

インストールが正常に完了している限り、これらのエラーは無視してかまいません。一般的な一時的エラーログ メッセージは次のとおりです。

  Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post
  https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Internal error occurred: failed calling webhook "vcluster.kb.io": Post
  https://webhook-service.kube-system.svc:443/validate-baremetal-cluster-gke-io-v1-cluster?timeout=30s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Failed to register cluster with GKE Hub; gcloud output: error running command
  'gcloud container fleet memberships register CLUSTER_NAME  --verbosity=error --quiet':
  error: exit status 1, stderr: 'ERROR: (gcloud.container.hub.memberships.register)
  Failed to check if the user is a cluster-admin: Unable to connect to the server: EOF
  Get
  https://127.0.0.1:34483/apis/infrastructure.baremetal.cluster.gke.io/v1/namespaces/cluster-
  cluster1/baremetalmachines: dial tcp 127.0.0.1:34483: connect: connection refused"
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout088683152\": no matches for kind \"NetworkLogging\" in version \"networking.gke.io/v1alpha1\""
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout869681888\": no matches for kind \"Provider\" in version \"clusterctl.cluster.x-k8s.io/v1alpha3\""

Google Cloud サービス アカウント キーの有効期限が切れている場合、bmctl から次のエラー メッセージが返されます。

Error validating cluster config: 3 errors occurred:
        * GKEConnect check failed: Get https://gkehub.googleapis.com/v1beta1/projects/project/locations/global/memberships/admin: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * ClusterOperations check failed: Post https://cloudresourcemanager.googleapis.com/v1/projects/project:testIamPermissions?alt=json&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * GCR pull permission for bucket: artifacts.anthos-baremetal-release.appspot.com failed: Get https://storage.googleapis.com/storage/v1/b/artifacts.anthos-baremetal-release.appspot.com/iam/testPermissions?alt=json&permissions=storage.objects.get&permissions=storage.objects.list&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}

新しいサービス アカウント キーを生成する必要があります。

ブートストラップ クラスタを使用して問題をデバッグする

Google Distributed Cloud で、セルフマネージド(管理、ハイブリッド、スタンドアロン)クラスタを作成する際には、Docker の Kubernetes(kind)クラスタがデプロイされ、Kubernetes コントローラが一時的にホストされます。この一時的なクラスタは、ブートストラップ クラスタと呼ばれます。ユーザー クラスタは、ブートストラップ クラスタを使用せずに、管理クラスタまたはハイブリッド クラスタを管理することによって作成およびアップグレードされます。

インストールする際、デプロイに kind クラスタがすでに存在していると、Google Distributed Cloud により既存の kind クラスタが削除されます。削除は、インストールまたはアップグレードが成功した場合にのみ行われます。成功後も既存の kind クラスタを保持するには、bmctl--keep-bootstrap-cluster フラグを使用します。

Google Distributed Cloud では、ブートストラップ クラスタの構成ファイルが WORKSPACE_DIR/.kindkubeconfig の下に作成されます。ブートストラップ クラスタへの接続は、クラスタの作成とアップグレード中のみ可能です。

ブートストラップ クラスタは、イメージを pull するために Docker リポジトリにアクセスする必要があります。非公開レジストリを使用しない場合は、レジストリがデフォルトで Container Registry に設定されます。クラスタの作成中、bmctl が次のファイルを作成します。

  • bmctl-workspace/config.json: レジストリ アクセス用の Google Cloud サービス アカウントの認証情報が含まれます。この認証情報は、クラスタ構成ファイルの gcrKeyPath フィールドから取得されます。

  • bmctl-workspace/config.toml: kind クラスタ内の containerd 構成が含まれます。

ブートストラップ クラスタのログを調べる

ブートストラップ クラスタをデバッグするには、次の操作を行います。

  • クラスタの作成またはアップグレード中に、ブートストラップ クラスタに接続します。
  • ブートストラップ クラスタのログを取得します。

bmctl の実行に使用するマシンのログは、次のフォルダにあります。

  • bmctl-workspace/CLUSTER_NAME/log/create-cluster-TIMESTAMP/bootstrap-cluster/
  • bmctl-workspace/CLUSTER_NAME/log/upgrade-cluster-TIMESTAMP/bootstrap-cluster/

CLUSTER_NAMETIMESTAMP は、クラスタの名前と対応するシステムの時刻に置き換えます。

ブートストラップ クラスタから直接ログを取得するには、クラスタの作成またはアップグレード中に次のコマンドを実行します。

docker exec -it bmctl-control-plane bash

このコマンドにより、ブートストラップ クラスタで実行される bmctl コントロール プレーン コンテナ内でターミナルが起動します。

kubelet ログと containerd ログを検査するには、次のコマンドを使用して、出力でエラーや警告を探します。

journalctl -u kubelet
journalctl -u containerd

クラスタ アップグレードの問題

Google Distributed Cloud クラスタをアップグレードすると、進行状況をモニタリングし、クラスタとノードのステータスを確認できます。

次のガイダンスは、アップグレードが正常に行われているか、問題が発生しているかを判断する際に役立ちます。

アップグレードの進行状況をモニタリングする

アップグレード プロセス中のクラスタのステータスを確認するには、kubectl describe cluster コマンドを使用します。

kubectl describe cluster CLUSTER_NAME \
    --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

次の値を置き換えます。

  • CLUSTER_NAME: クラスタの名前。
  • CLUSTER_NAMESPACE: クラスタの Namespace。
  • ADMIN_KUBECONFIG: 管理 kubeconfig ファイル。
    • デフォルトでは、管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタはインプレース アップグレードを使用します。bmctl upgrade コマンドに --use-bootstrap=true フラグを使用すると、アップグレード オペレーションでブートストラップ クラスタが使用されます。ブートストラップ クラスタの使用時にアップグレードの進行状況をモニタリングするには、ブートストラップ クラスタの kubeconfig ファイルのパス(.kindkubeconfig)を指定します。このファイルはワークスペース ディレクトリにあります。

出力の Status セクションを確認します。ここには、クラスタのアップグレード ステータスの集計が表示されます。クラスタがエラーを報告した場合は、次の各セクションを使用してトラブルシューティングを行います。

ノードの準備が完了しているかどうかを確認する

アップグレード プロセス中にクラスタ内のノードのステータスを表示するには、kubectl get nodes コマンドを使用します。

kubectl get nodes --kubeconfig KUBECONFIG

ノードでアップグレード プロセスが正常に完了したかどうかを確認するには、コマンド レスポンスの VERSION 列と AGE 列を確認します。VERSION は、クラスタの Kubernetes バージョンです。特定の Google Distributed Cloud バージョンの Kubernetes バージョンを確認するには、バージョニングをご覧ください。

ノードに NOT READY が表示されている場合は、ノードを接続して kubelet のステータスを確認してください。

systemctl status kubelet

kubelet ログを確認することもできます。

journalctl -u kubelet

kubelet のステータスとログの出力を確認し、ノードに問題がある理由を示すメッセージを探します。

アップグレード中のノードを確認する

クラスタ内のどのノードがアップグレード中かを確認するには、kubectl get baremetalmachines コマンドを使用します。

kubectl get baremetalmachines --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG

次の値を置き換えます。

  • CLUSTER_NAMESPACE: クラスタの Namespace。
  • ADMIN_KUBECONFIG: 管理 kubeconfig ファイル。
    • ブートストラップ クラスタが管理、ハイブリッド、スタンドアロンのアップグレードに使用される場合は、ブートストラップ クラスタの kubeconfig ファイル(bmctl-workspace/.kindkubeconfig)を指定します。

次の出力例は、アップグレードされるノードに DESIRED ABM VERSION とは異なる ABM VERSION があることを示しています。

NAME         CLUSTER    READY   INSTANCEID               MACHINE      ABM VERSION   DESIRED ABM VERSION
10.200.0.2   cluster1   true    baremetal://10.200.0.2   10.200.0.2   1.13.0        1.14.0
10.200.0.3   cluster1   true    baremetal://10.200.0.3   10.200.0.3   1.13.0        1.13.0

ドレイン中のノードを確認する

アップグレード プロセスでは、ノードが Pod からドレインされ、ノードが正常にアップグレードされるまでスケジューリングが無効になります。ドレインされているノードを確認するには、kubectl get nodes コマンドを使用します。

kubectl get nodes --kubeconfig USER_CLUSTER_KUBECONFIG | grep "SchedulingDisabled"

USER_CLUSTER_KUBECONFIG は、ユーザー クラスタ kubeconfig ファイルのパスに置き換えます。

STATUS 列は grep でフィルタされ、SchedulingDisabled を報告するノードのみが表示されます。このステータスは、ノードがドレイン中であることを示します。

管理クラスタからノードのステータスを確認することもできます。

kubectl get baremetalmachines -n CLUSTER_NAMESPACE \
  --kubeconfig ADMIN_KUBECONFIG

次の値を置き換えます。

  • CLUSTER_NAMESPACE: クラスタの Namespace。
  • ADMIN_KUBECONFIG: 管理 kubeconfig ファイル。
    • ブートストラップ クラスタが管理、ハイブリッド、スタンドアロンのアップグレードに使用される場合は、ブートストラップ クラスタの kubeconfig ファイル(bmctl-workspace/.kindkubeconfig)を指定します。

ドレインされるノードのステータスは、MAINTENANCE 列に表示されます。

ノードが長期間ドレインされている理由を確認する

前のセクションで説明した方法のいずれかで、kubectl get nodes コマンドを使用して、ドレインされているノードを特定します。kubectl get pods コマンドを使用して、このノード名でフィルタし、詳細を表示します。

kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME

NODE_NAME は、ドレインされているノードの名前に置き換えます。停止している、またはドレインの速度の遅い Pod のリストが返されます。ノードのドレインに 20 分以上かかる場合は、停止した Pod が存在していてもアップグレードが続行されます。

リリース 1.29 以降では、ノードドレイン プロセスPodDisruptionBudgets(PDB)を優先する Eviction API が使用されています。

次の PDB 設定により、ノードのドレインで問題が発生する可能性があります。

  • 複数の PDB によって管理される Pod

  • 次のような PDB 静的構成:

    • maxUnavailable == 0
    • minUnavailable >= 合計レプリカ

    合計レプリカ数は、DeploymentReplicaSetStatefulSet などの上位レベルのリソースで定義されるため、PDB リソースから判断することは困難です。PDB は、構成内のセレクタに基づいて Pod と照合されます。静的 PDB 構成が問題の原因かどうかを診断するには、まず pdb.Status.ExpectPodspdb.Status.DesiredHealthy 以下であるかどうかを調べ、前述の静的構成のいずれが原因となっているかどうか確認することをおすすめします。

ランタイム違反(計算済みファイルなど)DisruptionsAllowed PDB リソースの 0 ノードのドレインをブロックすることもあります。追加の中断を許可できない PodDisruptionBudget オブジェクトが構成されている場合、ノードのアップグレードを繰り返し試行しても、コントロール プレーン バージョンへのアップグレードが失敗する可能性があります。このエラーを回避するには、Deployment または HorizontalPodAutoscaler をスケールアップして、PodDisruptionBudget 構成を維持しながらノードをドレインすることをおすすめします。

中断を許可しないすべての PodDisruptionBudget オブジェクトを表示するには、次のコマンドを使用します。

kubectl get poddisruptionbudget --all-namespaces \
    -o jsonpath='{range .items[?(@.status.disruptionsAllowed==0)]}{.metadata.name}/{.metadata.namespace}{"\n"}{end}'

Pod が異常な状態である理由を確認する

Pod に upgrade-first-node または upgrade-node のコントロール プレーンの IP アドレスが含まれている場合は、アップグレードが失敗する可能性があります。この動作は、通常、静的 Pod が正常でないために発生します。

  1. crictl ps -a コマンドを使用して静的 Pod を確認し、クラッシュしている Kubernetes Pod または etcd Pod を探します。失敗した Pod がある場合は、Pod のログを調べて、クラッシュした理由を確認します。

    クラッシュループが発生する理由としては、次のようなことが考えられます。

    • 静的 Pod にマウントされたファイルの権限または所有権が正しくない。
    • 仮想 IP アドレスへの接続が機能しない。
    • etcd に問題がある。
  2. crictl ps コマンドが機能しないか、何も返されない場合は、kubeletcontainerd のステータスを確認します。systemctl status SERVICE コマンドと journalctl -u SERVICE コマンドを使用して、ログを確認します。

次のステップ