特権 Autopilot ワークロードと許可リストのトラブルシューティング

Google Kubernetes Engine(GKE)Autopilot クラスタの特権ワークロードは正しく構成して、問題を回避する必要があります。構成ミスは、許可リストとの同期の失敗や、ワークロードの拒否につながる可能性があります。これらの問題により、必要な権限で重要なエージェントやサービスを実行できなくなる可能性があります。

このドキュメントでは、Autopilot で特権ワークロードをデプロイする際の問題をトラブルシューティングする方法について説明します。許可リストの同期エラーを解決し、特権ワークロードが拒否される理由を診断するためのガイダンスを確認します。

この情報は、Autopilot クラスタで昇格した権限を持つワークロードをデプロイするプラットフォーム管理者、オペレーター、セキュリティ チームにとって重要です。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

許可リストの同期に関する問題

AllowlistSynchronizer をデプロイすると、GKE は指定した許可リスト ファイルをインストールして同期しようとします。この同期が失敗した場合、AllowlistSynchronizer の status フィールドにエラーが報告されます。

AllowlistSynchronizer オブジェクトのステータスを取得します。

kubectl get allowlistsynchronizer ALLOWLIST_SYNCHRONIZER_NAME -o yaml

ALLOWLIST_SYNCHRONIZER_NAME は、AllowlistSynchronizer の名前に置き換えます。

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

...
status:
  conditions:
  - type: Ready
    status: "False"
    reason: "SyncError"
    message: "some allowlists failed to sync: example-allowlist-1.yaml"
    lastTransitionTime: "2024-10-12T10:00:00Z"
    observedGeneration: 2
  managedAllowlistStatus:
    - filePath: "gs://path/to/allowlist1.yaml"
      generation: 1
      phase: Installed
      lastSuccessfulSync: "2024-10-10T10:00:00Z"
    - filePath: "gs://path/to/allowlist2.yaml"
      phase: Failed
      lastError: "Initial install failed: invalid contents"
      lastSuccessfulSync: "2024-10-08T10:00:00Z"

conditions.message フィールドと managedAllowlistStatus.lastError フィールドには、エラーの詳細情報が表示されます。以下の情報を参考にして問題を解決してください。

複数の AllowlistSynchronizer

1.33.4-gke.1035000 より前のバージョンの GKE クラスタでは、複数の AllowlistSynchronizer が存在する場合、WorkloadAllowlists のインストールが失敗することがあります。

この問題を解決するには、複数の allowlistPaths を含む単一の AllowlistSynchronizer のみを使用します。

または、クラスタを新しいバージョンにアップグレードすることもできます。

ワークロード コンテナの並べ替え

1.34.0-gke.0000000 より前のバージョンの GKE クラスタでは、1 つ以上のワークロード コンテナ イメージがクラスタ内 WorkloadAllowlist で指定されたコンテナ イメージと一致する場合、ワークロード コンテナが作成され、逆アルファベット順に並べ替えられることがあります。

この問題を解決するには、次のことをお試しください。

  • クラスタをバージョン 1.34.0-gke.0000000 以降にアップグレードします。
  • ワークロードのコンテナの名前を変更して、正しい順序で並べ替えられるようにします。

特権ワークロードのデプロイに関する問題

許可リストのインストールが正常に完了したら、対応する特権ワークロードをクラスタにデプロイします。場合によっては、GKE がワークロードを拒否することがあります。

次の解決方法を試します。

  • クラスタの GKE バージョンがワークロードのバージョン要件を満たしていることを確認します。
  • デプロイするワークロードが、許可リストのファイルが適用されるワークロードであることを確認します。

特権ワークロードが拒否された理由を確認するには、許可リスト違反に関する詳細情報を GKE にリクエストします。

  1. クラスタにインストールされている許可リストのリストを取得します。

    kubectl get workloadallowlist
    

    特権ワークロードに適用する許可リストの名前を確認します。

  2. 特権ワークロードの YAML マニフェストをテキスト エディタで開きます。ワークロードのデプロイ プロセスで他のツールを使用している場合など、YAML マニフェストにアクセスできない場合は、ワークロード プロバイダに連絡して問題を報告してください。以降の手順はスキップします。

  3. 特権ワークロード Pod 仕様の spec.metadata.labels セクションに次のラベルを追加します。

    labels:
      cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    

    ALLOWLIST_NAME は、前の手順で取得した許可リストの名前に置き換えます。許可リスト ファイルのパスではなく、kubectl get workloadallowlist コマンドの出力から名前を使用します。

  4. マニフェストを保存し、ワークロードをクラスタに適用します。

    kubectl apply -f WORKLOAD_MANIFEST_FILE
    

    WORKLOAD_MANIFEST_FILE は、マニフェスト ファイルのパスに置き換えます。

    出力には、ワークロード内のどのフィールドが指定された許可リストと一致しなかったかに関する詳細情報が示されます。次の例をご覧ください。

    Error from server (GKE Warden constraints violations): error when creating "STDIN": admission webhook "warden-validating.common-webhooks.networking.gke.io" denied the request:
    
    ===========================================================================
    Workload Mismatches Found for Allowlist (example-allowlist-1):
    ===========================================================================
    HostNetwork Mismatch: Workload=true, Allowlist=false
    HostPID Mismatch: Workload=true, Allowlist=false
    Volume[0]: data
             - data not found in allowlist. Verify volume with matching name exists in allowlist.
    Container[0]:
    - Envs Mismatch:
            - env[0]: 'ENV_VAR1' has no matching string or regex pattern in allowlist.
            - env[1]: 'ENV_VAR2' has no matching string or regex pattern in allowlist.
    - Image Mismatch: Workload=k8s.gcr.io/diff/image, Allowlist=k8s.gcr.io/pause2. Verify that image string or regex match.
    - SecurityContext:
            - Capabilities.Add Mismatch: the following added capabilities are not permitted by the allowlist: [SYS_ADMIN SYS_PTRACE]
    - VolumeMount[0]: data
            - data not found in allowlist. Verify volumeMount with matching name exists in allowlist.
    

    この例では、次の違反が発生します。

    • ワークロードで hostNetwork: true が指定されていますが、許可リストで hostNetwork: true が指定されていません。
    • ワークロードで hostPID: true が指定されていますが、許可リストで hostPID: true が指定されていません。
    • ワークロードでは data という名前のボリュームが指定されていますが、許可リストでは data という名前のボリュームが指定されていません。
    • コンテナは ENV_VAR1ENV_VAR2 という名前の環境変数を指定していますが、許可リストにはこれらの環境変数は指定されていません。
    • コンテナではイメージ k8s.gcr.io/diff/image が指定されていますが、許可リストでは k8s.gcr.io/pause2 が指定されています。
    • コンテナは SYS_ADMIN 機能と SYS_PTRACE 機能を追加しますが、許可リストではこれらの機能の追加が許可されていません。
    • コンテナは data という名前のボリューム マウントを指定していますが、許可リストには data という名前のボリューム マウントが指定されていません。

サードパーティ プロバイダが所有するワークロードをデプロイしている場合は、そのプロバイダに問題を報告して違反を解決します。問題の前のステップの出力を提提供します。

GKE バージョンの非互換性

許可リストで、クラスタの GKE バージョンよりも新しい最小 GKE バージョンが指定されている場合、GKE はワークロードを拒否することがあります。

  1. 許可リストで最小 GKE バージョンが指定されているかどうかを確認します。

    kubectl describe workloadallowlist ALLOWLIST_NAME | grep "minGKEVersion"
    

    ALLOWLIST_NAME は、許可リストの名前に置き換えます。

    出力が空の場合、許可リストで最小 GKE バージョンが指定されていません。このセクションはスキップしてください。出力が値の場合、許可リストで最小 GKE バージョンが指定されています。

  2. クラスタの GKE バージョンを確認します。

    gcloud container clusters describe CLUSTER_NAME \
        --location=CLUSTER_LOCATION \
        --format="value(currentMasterVersion)"
    

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

    • CLUSTER_NAME: クラスタの名前。
    • CLUSTER_LOCATION: クラスタの Google Cloud ロケーション 。

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

    1.32.3-gke.1006000
    
  3. クラスタの GKE バージョンが許可リストの最小 GKE バージョンよりも古い場合は、クラスタを許可リストの最小 GKE バージョン以降にアップグレードします。詳細については、 クラスタのアップグレードをご覧ください。

アップグレードが完了したら、ワークロードをクラスタにデプロイします。

文字列の不一致

WorkloadAllowlist 仕様の特定のフィールドは、ワークロード仕様の対応するフィールドと完全に一致する文字列である必要があります。

  1. WorkloadAllowlist CustomResourceDefinition(CRD)のリファレンス ページを開きます
  2. WorkloadAllowlist 仕様の各フィールドについて、CRD で完全一致する文字列が必要かどうかを確認します。
  3. 完全一致する文字列が必要なフィールドごとに、WorkloadAllowlist 仕様の値がワークロード仕様の対応する値と一致しているかどうかを確認します。

    たとえば、コンテナが実行するすべてのコマンドは、許可リスト内のコマンドと完全に一致する必要があります。コマンドが完全に一致しない場合は、拒否されます。

不一致がある場合は、ワークロード仕様と一致するように WorkloadAllowlist 仕様を更新します。

正規表現の不一致

WorkloadAllowlist 仕様の特定のフィールドは、正規表現の一致をサポートしています。

  1. WorkloadAllowlist 仕様で、正規表現を指定するフィールドを見つけます。
  2. 正規表現の構文が正しいことを確認します。WorkloadAllowlist CRD は、 Google RE2 正規表現構文をサポートしています。 式に次のプロパティがあることを確認します。

    • 正規表現は ^ 文字で始まり、$ 文字で終わります。例: ^example-auth\.google\.com\/go_[a-z0-9]+\/google\/path$
    • すべての特殊文字は \ エスケープ文字でエスケープされます。\ 文字が余分にあるか、不足していないかを確認します。
    • 許可リスト内のイメージパスにタグやダイジェストは含まれません。たとえば、k8s.gcr.io/pause:3.1k8s.gcr.io/pause@sha256:1234567890 ではなく k8s.gcr.io/pause を使用します。

正規表現の問題を修正したら、ワークロードをクラスタにデプロイします。

コマンドと引数のエスケープ文字

特殊文字をエスケープしない場合、GKE はコマンドと引数を照合できません。文字のエスケープ要件は、許可リストの適用方法によって異なります。たとえば、許可リストを YAML ファイルまたは JSON ファイルとして適用する場合と、コマンドライン ツールを使用して許可リスト仕様を作成する場合では、エスケープ要件が異なります。このセクションでは、YAML ファイルのエスケープ要件について説明します。

正規表現を使用しない場合でも、WorkloadAllowlist 仕様の commands フィールドと args フィールドのすべての特殊文字をエスケープします。 特殊文字をエスケープするには、次の例のように \ 文字を使用します。

  • コマンド: kubectl describe \$\{POD_NAME\}
  • 引数: hostname \$NODE_NAME; dcgm-exporter --remote-hostengine-info \$\(NODE_IP\) --collectors /etc/dcgm-exporter/counters.csv

許可リストのワークロードに対するウェブフックの干渉

ワークロードが許可リストと一致するように正しく構成されている場合でも、GKE によって拒否されることがあります。この状況は、許可リストで許可された後に、クラスタ内の別のアドミッション コントローラ(ウェブフック)がワークロード コントローラによって作成された Pod を変更した場合に発生する可能性があります。このような変更により、Pod 仕様が許可リストと一致しなくなり、GKE Warden アドミッション ウェブフックによって拒否されることがあります。

この問題は、サイドカー コンテナまたは環境変数を Pod に挿入するサードパーティのモニタリング エージェントとセキュリティ エージェントでよく発生します。

最も一般的な症状は、ワークロード コントローラ(DaemonSet や Deployment など)が正常に作成されるものの、Pod を作成できないことです。コントローラのイベントを調べると、Pod がアドミッション ウェブフックによって拒否されたことを示すメッセージが表示されます。

  1. 特権ワークロードのデプロイに関する問題のセクション の手順に沿って、ワークロードに cloud.google.com/matching-allowlist ラベルを追加します。
  2. ワークロードの YAML マニフェストから spec.template をコピーします。
  3. 新しい Pod マニフェストを作成し、コピーした仕様を spec フィールドに貼り付けます。
  4. Pod マニフェストで apiVersionkindmetadata.name フィールドを設定します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
      labels:
        cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    spec:
      # Paste the content of spec.template here
    

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

    • POD_NAME: テスト Pod の名前。
    • ALLOWLIST_NAME: 許可リストの名前。
  5. Pod マニフェストを適用します。

    kubectl apply -f YOUR_POD_MANIFEST_FILE
    

    YOUR_POD_MANIFEST_FILE は、Pod マニフェスト ファイルのパスに置き換えます。

  6. 前のステップの出力を確認します。[ワークロードの不一致] セクションに、余分な環境変数(DD_AGENT_HOST など)、コンテナ、ボリュームなど、予期しないフィールドが表示されている場合は、別のウェブフックが Pod を変更している可能性が高くなります。

この問題を解決するには、競合するウェブフックを構成して、許可リストに登録されたワークロードの Pod を変更しないようにします。通常、これは、ワークロードまたはその名前空間にラベルまたはアノテーションを追加して、ウェブフックが変更から除外されるようにすることで行われます。たとえば、 Datadog を使用する場合は、ワークロードの Namespace に admission.datadoghq.com/enabled: "false" ラベルを追加します。

ワークロードをアドミッション コントローラから除外する方法については、使用している特定のサードパーティ ソフトウェアのドキュメントをご覧ください。

他のウェブフックが Pod を変更しないようにすることで、Pod が許可リストと一致し、Autopilot クラスタに正常にデプロイされるようにすることができます。

特権ワークロードと許可リストに関するバグと機能リクエスト

GKE パートナーまたはサードパーティ プロバイダが提供する特権ワークロードを実行する場合、そのプロバイダは、特権ワークロードと許可リストの作成、開発、維持を行う責任があります。パートナーまたはサードパーティの特権ワークロードまたは許可リストに関するバグが発生した場合や、機能リクエストがある場合は、プロバイダにお問い合わせください。

次のステップ