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

このページでは、Config Sync に関する問題を解決する方法について説明します。

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

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

Config Sync のステータスを確認する

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

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

nomos status を使用するには、nomos コマンドをインストールします。

gcloud alpha anthos config sync repo コマンドを使用して、リポジトリごとに Config Sync のステータスを取得することもできます。詳細については、複数のクラスタの Config Sync のステータスを表示するをご覧ください。

kubectl を使用してリソースを調べる

Config Sync は、kubectl コマンドでクエリ可能な複数のカスタム リソースで構成されています。次のコマンドを使用すると、Config Sync の各オブジェクトのステータスを確認できます。

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

gcloud alpha anthos config sync resources コマンドを使用して Config Sync マネージド リソースを取得することもできます。詳細については、Config Sync のマネージド リソースを表示するをご覧ください。

RootSync オブジェクトと RepoSync オブジェクトを確認する

kubectl を使用して Config Sync をインストールする場合は、ルート リポジトリの構成に関する詳細を含む RootSync オブジェクトを作成します。Google Cloud Console または Google Cloud CLI を使用して Config Sync をインストールすると、Config Sync によって RootSync オブジェクトが自動的に作成されます。複数のリポジトリから同期を構成するときに、名前空間リポジトリの構成情報を含む RepoSync オブジェクトを作成します。

これらのオブジェクトを調べると、Config Sync の状態に関する貴重な情報が得られます。詳細については、RootSync オブジェクトと RepoSync オブジェクトをモニタリングするをご覧ください。

監査ログを使用する

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

Cloud Console または Google Cloud CLI を使用して Config Sync をインストールした場合は、次の手順で監査ログを使用して Config Sync を調査します。

コンソール

  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. [クエリ結果] セクションで、エントリを選択してイベントの詳細を確認します。

FailedScheduling のイベント

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.

このイベントは、ノードで Pod をスケジュールできない場合に発生します。通常は、ノード上の CPU またはメモリが不足していることを示します。このエラーを修正するには、次のいずれかのオプションを選択します。

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

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

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

問題のない有効なインストールのステータスは 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 を追加する方法についての詳細は、複数のリポジトリからの同期の構成をご覧ください。

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

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

RootSync オブジェクト、RepoSync オブジェクト、または調整ツールのログから次のエラーが表示された場合、ResourceGroup リソースが etcd オブジェクト サイズの上限を超えていることを意味します。

KNV2009: etcdserver: request is too large

手順に沿って Git リポジトリを複数のリポジトリに分割することをおすすめします。Git リポジトリの分割ができない場合は、Config Sync v1.11.0 以降では、表示するステータス データを無効にすることで、これを回避できます。これを行うには、RootSync オブジェクトまたは RepoSync オブジェクトの .spec.override.statusMode フィールドを disabled に設定します。この操作を行うと、Config Sync が ResourceGroup オブジェクトのマネージド リソース ステータスの更新を停止します。ResourceGroup オブジェクトのサイズが小さくなります。ただし、nomos status または gcloud alpha anthos config sync からのマネージド リソースのステータスも表示できなくなります。

RootSync オブジェクトまたは RepoSync オブジェクトからエラーがまったく表示されない場合は、Git リポジトリがクラスタに同期されていることを意味します。ResourceGroup リソースが etcd オブジェクトのサイズ上限を超えているかどうかを確認するには、ResourceGroup リソースのステータスと ResourceGroup コントローラのログの両方を確認します。

  1. ResourceGroup のステータスを確認します。

    • RootSync オブジェクトを確認するには、次のコマンドを実行します。
     kubectl get resourcegroup.kpt.dev root-sync -n config-management-system
    
    • 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 つのルート リポジトリを複数のルート リポジトリに分割できます。

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 フィールドの更新が必要になることがあります。

削除された RootSync / RepoSync によって管理されていたリソースを更新または削除するリクエストを Webhook が拒否する

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'

必要な権限があることを確認するには、必要な IAM ロールが付与されていることを確認してください。

エラー: アドミッション 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 タイムアウト

Reconciler がクラスタに構成を適用しようとしたときに次のエラーが発生した場合、ファイアウォールにより、アドミッション Webhook ポート 8676 でコントロール プレーン ネットワークへの通信がブロックされることがあります。

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

この問題を解決するには、ポート 8676 を許可するファイアウォール ルールを追加します。これは、Config Sync アドミッション Webhook がドリフト防止に使用するポートです。

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

Reconciler が構成をクラスタに適用しようとしたときに次のエラーが発生した場合、アドミッション 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

これは、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 と同期しようとしたときに次のエラーが発生した場合、Git Secret が git-sync コンテナに正常にマウントされません。

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 リポジトリの認証タイプを 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

reconcilerhydration-controller、または git-sync コンテナ、あるいはそのすべてで OOMKilled が発生する

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

次の例は、reconciler コンテナの CPU とメモリの制限と、ルート Reconciler の git-sync コンテナの CPU リクエストとメモリの上限をオーバーライドする方法を示しています。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: "800m"
      memoryLimit: "500Mi"
    - containerName: "git-sync"
      cpuRequest: "100m"
      memoryLimit: "400Mi"
  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 リポジトリのシャロー クローンを作成します。まれに、Config Sync がシャロー クローンから commit を見つけられない場合があります。この場合、Config Sync は取得する Git commit の数を増やします。

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

  • このフィールドを指定しない場合は、Config Sync によって自動的に構成されます。
  • このフィールドが 0 の場合、Config Sync はフルクローンを実行します。このフィールドが 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 が発生している場合は、そのリソースの上限を引き上げます

エラー: Stackdriver / GoogleCloud エクスポータを作成できない

Open Telemetry Collector のコンポーネントが同じ Namespace のデフォルトのサービス アカウントにアクセスできない場合、config-management-monitoringotel-collector Pod が CrashLoopBackoff ステータスになっていることがあります。また、次のようなエラー メッセージが表示されることもあります。

Error: cannot build exporters: error creating stackdriver exporter: cannot configure Google Cloud metric exporter: stackdriver: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.

この問題は通常、クラスタで Workload Identity が有効になっている場合に発生します。

この問題を解決するには、Config Sync のモニタリングの手順に沿って、デフォルトのサービス アカウントに指標の書き込み権限を付与します。

IAM を設定してもエラーが解決しない場合は、otel-collector Pod を再起動して変更を有効にします。