Config Sync のトラブルシューティング

このページには、Config Sync のインストールに関するトラブルシューティングを実施する際に有用な情報を掲載しています。

Config Sync が常に機能するよう努めていますが、セットアップのトラブルシューティングが必要となる場合もあります。このガイドでは、発生した問題の解決に役立つ一般的なメカニズムについて説明します。

一般的に推奨される利用方法

nomos status が助けになります

Google は、nomos status コマンドを使用して手元のデータを最大限活用できるようにすることに注力しています。nomos status は、Config Sync のインストールで起きていることを把握するために役立つ、集計データとエラーを提供します。次の情報は nomos status で使用できます。

  • クラスタあたりのインストール ステータス
  • 同期エラー(Git からの読み取りと変更の調整の両方)

高度な用途の kubectl get KRM リソース

Config Sync は、複数のカスタム リソースで構成されており、kubectl を使用して個別にクエリして、各オブジェクトのステータスを正確に把握できます。

Config Sync が管理する Kubernetes のリソースについて、次の重要な点に留意してください。

  • config-management-system は、Config Sync のすべてのコアシステム コンポーネントの実行に使用する名前空間です。
  • configmanagement.gke.io/v1configsync.gke.io は、すべてのカスタム リソースに使用するバージョン プレフィックスです。

カスタム リソースの全一覧を取得するには、次のコマンドを実行します。

kubectl api-resources | grep -E "configmanagement.gke.io|configsync.gke.io"

個別のカスタム リソースを使用するには、kubectl get RESOURCE -o yaml を実行します。

たとえば、次のコマンドの出力から、RootSync オブジェクトを確認できます。

kubectl get rootsync -n config-management-system -o yaml

詳細については、RootSync オブジェクトと RepoSync オブジェクトの確認をご覧ください。

監査ログの使用

監査ログは有用なデバッグツールです。

Cloud Console または gcloud コマンドライン ツールを使用して Config Sync をインストールした場合は、次の手順で監査ログを使用して、Config Sync の調査を行います。

Console

  1. GKE Connect / Hub API 監査ログを有効にします。

    1. Cloud Console で IAM の [監査ログ] ページに移動します。

      [監査ログ] ページに移動

    2. 表で [GKE Connect / Hub API] チェックボックスをオンにします。

    3. 次のチェックボックスをオンにします。

      • 管理読み取り
      • データ読み取り
      • データ書き込み
    4. [保存] をクリックします。

  2. [ログ エクスプローラ] ページに移動します。

    [ログ エクスプローラ] ページに移動

  3. [クエリビルダー] テキスト ボックスに次のフィルタを追加します。

    resource.type="audited_resource" resource.labels.service="gkehub.googleapis.com"
    
  4. [実行] をクリックします。

  5. [クエリ結果] セクションで、エントリを選択してイベントの詳細を確認します。

CPU の不足

kubectl get events の出力に、タイプが FailedScheduling のイベントが含まれる場合があります。このイベントは次のようになります。

LAST SEEN   TYPE      REASON              OBJECT                                       MESSAGE
9s          Warning   FailedScheduling    pod/config-management-operator-74594dc8f6    0/1 nodes are available: 1 Insufficient cpu.

このエラーを修正するには、次のいずれかのオプションを選択します。

  • 既存の GKE ノードプールにノードを追加する。
  • より大きなノードでノードプールを作成する。

有効であるが正しくない ConfigManagement オブジェクト

YAML または JSON 構文エラーに起因しない ConfigManagement オブジェクトの問題によってインストールが失敗した場合、ConfigManagement オブジェクトはクラスタでインスタンス化されますが、正しく動作しない可能性があります。この場合、nomos status コマンドを使用して ConfigManagement オブジェクトのエラーを確認できます。

問題のない有効なインストールのステータスは、PENDING または SYNCED になります。

無効なインストールのステータスは NOT CONFIGURED であり、次のいずれかのエラーが表示されます。

  • missing git-creds Secret
  • missing required syncRepo field
  • git-creds Secret is missing the key specified by secretType

問題を解決するには、構成エラーを修正してください。エラーのタイプに応じて、ConfigManagement マニフェストをクラスタに再適用する必要があります。

ユーザーが git-creds Secret の作成を失念したために問題が発生した場合は、Secret を作成すると Config Sync によって即時に検出されるため、構成を再適用する必要はありません。

ResourceGroup フィールドが変わり続ける

クラスタと同期された Git リポジトリの場合は、すべてのリソースの調整ステータスが ResourceGroup というリソースに集約されます。RootSync オブジェクトや RepoSync オブジェクトごとに ResourceGroup が生成され、クラスタに適用される一連のリソースを取り込んで、それらのステータスを集約します。

場合によっては、ResourceGroup が、ResourceGroup の spec を更新し続けるループに陥ることがあります。この現象が起きると、次のような問題が発生する可能性があります。

  • ResourceGroup の metadata.generation が、短時間で増加し続ける。
  • ResourceGroup spec が変わり続ける。
  • ResourceGroup spec に、クラスタに同期されているリソースの status.resourceStatuses が含まれない。

こうした問題が見られる場合は、Git リポジトリの一部のリソースがクラスタに適用されていないことを意味します。この問題の原因は、そのリソースを適用するために必要な権限がないことです。

権限がないことは、RepoSync リソースのステータスを取得することで確認できます。

kubectl get reposync repo-sync -n NAMESPACE -o yaml

NAMESPACE は、名前空間リポジトリを作成した名前空間に置き換えます。

nomos status を使用することもできます。

ステータスに次のメッセージが確認される場合は、NAMESPACE の調整ツールに、リソースを適用するために必要な権限がないことを意味します。

errors:
  - code: "2009"
    errorMessage: |-
      KNV2009: deployments.apps "nginx-deployment" is forbidden: User "system:serviceaccount:config-management-system:ns-reconciler-     default" cannot get resource "deployments" in API group "apps" in the namespace "default"

      For more information, see https://g.co/cloud/acm-errors#knv2009

この問題を解決するには、対象の Namespace でエラーが発生したリソースを管理する権限を ns-reconciler-NAMESPACE サービス アカウントに付与する RoleBinding 構成を宣言する必要があります。RoleBinding を追加する方法についての詳細は、Namespace リポジトリからの同期の構成セクションをご覧ください。

Git リポジトリにリソースが多い

RepoSync オブジェクトや RootSync オブジェクトによって同期された Git リポジトリに数千を超えるリソースの構成が含まれていると、ResourceGroup で etcd オブジェクトのサイズ上限を超える可能性があります。この状態になると、Git リポジトリ内のリソースの集約ステータスを表示できません。集約されたステータスを表示できませんが、リポジトリは引き続き同期されます。RepoSync オブジェクトや RootSync オブジェクト内にエラーが表示されない場合は、Git リポジトリがクラスタに正常に同期されています。

ResourceGroup リソースが etcd オブジェクトのサイズ上限を超えているかどうかを確認するには、ResourceGroup リソースのステータスと ResourceGroup コントローラのログの両方を確認する必要があります。

  1. ResourceGroup のステータスは、次のコマンドを使用して確認します。

    • RootSync を確認するには、次のコマンドを実行します。
     kubectl get resourcegroup.kpt.dev root-sync -n config-management-system
    
    • RepoSync を確認するには、次のコマンドを実行します。
    # For the RepoSync:
    kubectl get resourcegroup.kpt.dev repo-sync -n NAMESPACE
    

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

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    RECONCILING 列の値が True の場合は、ResourceGroup リソースが、まだ調整中であることを意味します。

  2. ResourceGroup コントローラのログは、次のコマンドを使用して確認します。

    kubectl logs deployment/resource-group-controller-manager -c manager -n resource-group-system
    

    出力に次のエラーが表示される場合は、ResourceGroup リソースのサイズが大きすぎ、etcd オブジェクトのサイズ上限を超えています。

    "error":"etcdserver: request is too large"
    

ResourceGroup が大きくなりすぎることを防ぐには、Git リポジトリ内のリソース数を減らします。たとえば、1 つの RootSync オブジェクトですべてのリソースを同期するのではなく、リポジトリを分割して、複数の RepoSync オブジェクトで 1 つの RootSync オブジェクトを使用します。

Git リポジトリと同期されていない

新しい commit が Git リポジトリに push されているにもかかわらず、クラスタの Config Sync ステータスが長時間(spec.git.period 以上)、古い commit と Synced 状態になっている場合は、git-sync コンテナのログを確認する必要があります。

# check git-sync logs for a root reconciler
kubectl logs -n config-management-system deployment/root-reconciler -c git-sync

# check git-sync logs for a namespace reconciler
kubectl logs -n config-management-system deployment/ns-reconciler-NAMESPACE -c git-sync

git-sync が Git リポジトリとの同期に失敗していて、Reconciler が以前に同期した commit との同期を継続している可能性があります。次の出力例は、git-sync に問題があることを示しています。

"msg"="unexpected error syncing repo, will retry" "error"="Run(git fetch -f --tags --depth 1 origin develop): exit status 128: { stdout: "", stderr: "fatal: couldn't find remote ref develop\n" }"

これは、Config Sync バージョン 1.8.1 以前の既知の問題です。この問題を修正するには、ログ内のエラー メッセージに従う必要があります。Git リポジトリ、または RootSync オブジェクトまたは RepoSync オブジェクトの spec.git フィールドの更新が必要になることがあります。

admission-webhook.configsync.gke.io が、すでに削除された RootSync/RepoSync によって管理されていたリソースを更新 / 削除するリクエストを拒否する

RootSync オブジェクトまたは RepoSync オブジェクトを削除しても、Config Sync のアノテーションとラベルがクリーンアップされません。クラスタで Config Sync がまだ有効になっている場合、Config Sync アドミッション Webhook は、これらのリソースを変更または削除するリクエストを拒否します。

これらのマネージド リソースを維持する場合は、Git リポジトリ内で宣言されているマネージド リソースごとに、configmanagement.gke.io/managed アノテーションを disabled設定し、これらのリソースを管理対象外にします。Config Sync のアノテーションとラベルはマネージド リソースから削除されますがこれらのリソースは削除されません。同期の完了後、RootSync オブジェクトまたは RepoSync オブジェクトを削除できます。

これらのマネージド リソースを削除する場合は、まず、空の Git ディレクトリから同期するように RootSync または RepoSync オブジェクトを変更して、マネージド リソースを削除します。同期の完了後、RootSync オブジェクトまたは RepoSync オブジェクトを削除できます。

マネージド リソースを管理対象にする前または削除する前に RootSync オブジェクトまたは RepoSync オブジェクトを削除した場合は、RootSync オブジェクトまたは RepoSync オブジェクトを再度追加し、マネージド リソースを管理対象外にするか削除してから、RootSync オブジェクトまたは RepoSync オブジェクトを再度削除します。

エラー メッセージのトラブルシューティング

エラー: アクセスが拒否された

Config Sync を構成しようとしたときに、次の例のようなエラーが表示された場合は、GKE Hub 管理者ロールが割り当てられていない可能性があります。

Permission 'gkehub.features.create' denied on 'projects/PROJECT_ID/locations/global/features/configmanagement'

必要な権限があることを確認するには、権限の準備をご覧ください。

エラー: アドミッション Webhook によりリクエストが拒否された

Config Sync で管理されているフィールドに変更を適用しようとして次のエラーが発生した場合は、競合が生じる変更を行った可能性があります。

error: OBJECT could not be patched: admission webhook "v1.admission-webhook.configsync.gke.io"
denied the request: fields managed by Config Sync can not be modified

構成ファイルでフィールドを宣言し、リポジトリがクラスタに同期されると、そのフィールドは Config Sync が管理します。そのフィールドを変更しようとすることは、競合する変更に該当します。

たとえば、リポジトリに environment:prod のラベルが付いた Deployment 構成ファイルがあり、クラスタ内でそのラベルを environment:dev に変更しようとすると、それは競合する変更となり、このエラー メッセージが表示されます。ただし、新しいラベル(tier:frontend など)を Deployment に追加することでは、競合は発生しません。

Config Sync でオブジェクトへの変更が無視されるようにするには、オブジェクトのミューテーションを無視するで説明されているアノテーションを追加します。

エラー: アドミッション Webhook リクエストの I/O タイムアウト

調整ツールが構成ファイルをクラスタに適用するときに、次のエラーが発生することがあります。

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s: dial tcp 10.1.1.186:8676: i/o timeout

原因としては、コントロール プレーン ネットワークのファイアウォールで、アドミッション Webhook ポート 8676 がブロックされていることが考えられます。この問題を解決するには、ポート 8676 を許可するファイアウォール ルールを追加します。これは、Config Sync アドミッション Webhook がドリフト防止に使用するポートです。

エラー: アドミッション Webhook の接続が拒否された

調整ツールが構成ファイルをクラスタに適用するときに、次のエラーが発生することがあります。

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post "https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s": dial tcp 10.92.2.14:8676: connect: connection refused

これは、アドミッション Webhook の準備がまだできていないことを意味します。これは、Config Sync のブートストラップ時に発生する一時的なエラーです。

この問題が繰り返し発生する場合は、アドミッション Webhook Deployment を調べて、Pod がスケジュール可能で正常な状態かどうかを確認します。

kubectl describe deploy admission-webhook -n config-management-system

kubectl get pods -n config-management-system -l app=admission-webhook

エラー: Git Secret をマウントできない

git-sync コンテナがリポジトリと Secret を同期しようとすると、次のエラーが発生することがあります。

KNV2004: unable to sync repo Error in the git-sync container: ERROR: can't configure SSH: can't access SSH key: stat /etc/git-secret/ssh: no such file or directory: lstat /repo/root/rev: no such file or directory

つまり、Git Secret が git-sync コンテナにマウントされていません。これは、Git リポジトリの認証タイプを nonegcenode、または gcpserviceaccount から Secret を必要とするタイプに切り替えると発生する可能性があります。この問題を解決するには、次のコマンドを実行して Reconciler Manager と Reconciler を再起動します。

# Stop the reconciler-manager Pod. The reconciler-manager Deployment will spin
# up a new Pod which can pick up the latest `spec.git.auth`.
kubectl delete po -l app=reconciler-manager -n config-management-system

# Delete the reconciler Deployments. The reconciler-manager will recreate the
# reconciler Deployments with correct volume mount.
kubectl delete deployment -l app=reconciler -n config-management-system

reconciler または git-sync コンテナ、あるいはこの両方で OOMKilled が発生する

Anthos Config Management バージョン 1.8.2 以降では、kubectl を使用して複数のリポジトリから同期を構成するときに、ルートや名前空間リポジトリの CPU とメモリの上限をオーバーライドできます。これらの値をオーバーライドするには、RootSync や RepoSync オブジェクトの spec.override.resources フィールドを使用します。

次の例では、reconciler コンテナの CPU とメモリの上限と、ルート Reconciler の git-sync コンテナのメモリ上限をオーバーライドする方法を示します。git-sync コンテナと reconciler コンテナのみオーバーライドできます。リソース上限のオーバーライド値が指定されていない場合は、部分的なオーバーライドが許可され、デフォルトのリソース上限が使用されます。

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  sourceFormat: "unstructured"
  override:
    resources:
    - containerName: "reconciler"
      cpuLimit: "888m"
      memoryLimit: "444Mi"
    - containerName: "git-sync"
      memoryLimit: "333Mi"
  git:
     ...

次のコマンドを実行して、新しいリソース上限が有効であることを確認します。

kubectl get deployment.apps/root-reconciler -n config-management-system -o yaml

同様に、名前空間 Reconciler のリソース上限をオーバーライドできます。

KNV2004: git-sync コンテナでリポジトリを同期できないエラー(git fetchremote did not send all necessary objects エラーで失敗)

Config Sync は Git リポジトリのシャロー クローンを作成します。まれに、シャロー クローンから commit が見つからなくなり、取得する Git commit の増加が必要になることがあります。

Anthos Config Management バージョン 1.8.2 以降では、RootSync または RepoSync オブジェクトの spec.override.gitSyncDepth フィールドを設定することで、取得する Git commit の数を設定できます。

  • このフィールドを指定しない場合は、Config Sync によって自動的に構成されます。
  • Config Sync は、このフィールドが 0 の場合はフルクローンを実行し、このフィールドが 0 より大きい場合はシャロー クローンを実行します。
  • このフィールドに負の値を設定することはできません。

88 に取得する Git commit の数の設定例を次に示します。

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  override:
    gitSyncDepth: 88
  git:
    ...

次のコマンドを実行して、変更が有効になったことを確認します(root-reconciler-git-sync ConfigMap の data フィールドで GIT_SYNC_DEPTH88 に設定します)。

kubectl get cm root-reconciler-git-sync -n config-management-system -o yaml

同様に、名前空間 Reconciler で取得する Git commit の数をオーバーライドできます。

エラー: Reconciler デプロイメントをアップグレードできない

Config Sync をバージョン 1.6.2~1.7.0 からバージョン 1.7.x~1.8.x にアップグレードすると、Reconciler Deployment のイメージ バージョンが更新されないことがあります。これは、Deployment テンプレートの .spec.selector.labels フィールドに変更された場合に発生します。新しい matchLabel は 1.6.2 で追加され、1.7.0 で削除されました。ラベルセレクタは不変であるため、Reconciler Manager は Reconciler をアップグレードできません。

エラーを確認するには、reconciler-manager ログを調べます。

kubectl logs -n config-management-system deployment/reconciler-manager -c reconciler-manager

ログに含まれるエラーの例を次に示します。

Deployment.apps "root-reconciler" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"reconciler"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

この問題を解決するには、現在の Reconciler を削除します。

kubectl delete deployment -n config-management-system -l app=reconciler

エラー: 名前空間が Terminating フェーズでスタックする

次の条件が発生すると、Terminating フェーズで名前空間がスタックします。

    message: 'Failed to delete all resource types, 1 remaining: admission webhook
      "v1.admission-webhook.configsync.gke.io" denied the request: system:serviceaccount:kube-system:namespace-controller
      is not authorized to delete managed resource "_configmap_bookstore_cm1"'
    reason: ContentDeletionFailed
    status: "True"
    type: NamespaceDeletionContentFailure

これは、ルート リポジトリから名前空間を削除しようとしたときに、その名前空間の下にある一部のオブジェクトが名前空間 Reconciler によってアクティブに管理されていると発生します。名前空間が削除されると、名前空間コントローラ(サービス アカウントが system:serviceaccount:kube-system:namespace-controller)は、その名前空間にあるすべてのオブジェクトを削除しようとします。ただし、Config Sync アドミッション Webhook は、ルートまたは名前空間の Reconciler にのみこれらのオブジェクトの削除を許可し、名前空間コントローラによる削除を拒否します。

これを回避するには、Config Sync アドミッション Webhook を削除します。

kubectl delete deployment.apps/admission-webhook -n config-management-system

Config Management Operator が Config Sync アドミッション Webhook を再作成します。

この回避策で解決しない場合は、Config Sync の再インストールが必要になることがあります。

エラーの再発を防ぐには、名前空間を削除する前に、名前空間リポジトリが削除されていることを確認する必要があります(こちらの名前空間リポジトリを削除する手順をご覧ください)。

エラー: ValidatingWebhookConfiguration に webhooks フィールドが見つからない

kubectl logs -n config-management-system -l app=admission-webhook の実行時に、Config Sync アドミッション Webhook ログに次のエラーが記録されている場合があります。

cert-rotation "msg"="Unable to inject cert to webhook." "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "gvk"={"Group":"admissionregistration.k8s.io","Version":"v1","Kind":"ValidatingWebhookConfiguration"} "name"="admission-webhook.configsync.gke.io"
controller-runtime/manager/controller/cert-rotator "msg"="Reconciler error" "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "name"="admission-webhook-cert" "namespace"="config-management-system"

これは、root-reconciler がクラスタにリソースを同期していないことを意味します。原因としては、root-reconciler の準備ができていないか、Git リポジトリから同期されているものがないこと(同期ディレクトリが空になっているなど)が考えられます。問題が解決しない場合は、root-reconciler のヘルスチェックを行います。

kubectl get pods -n config-management-system -l configsync.gke.io/reconciler=root-reconciler

root-reconciler がクラッシュ ループしているか、OOMKilled が発生している場合は、そのリソース上限を引き上げる必要があります。