構成ファイルのドリフトを防ぐ

Config Sync では、自動自己修復、定期的な再同期、オプションのドリフト防止により、「シャドウ オペレーション」のリスクを軽減できます。Config Sync がクラスタと信頼できる情報源間のドリフトを検出した場合は、許可して迅速に元に戻す、または完全に拒否できます。

自己修復は、マネージド リソースを監視して、信頼できる情報源のドリフトを検出し、検出したドリフトを元に戻します。セルフヒーリングは常に有効です。

定期的な再同期は、信頼できる情報源に変更が加えられていなくても、前回の同期が成功してから 1 時間後に自動的に同期を実施します。定期的な再同期は常に有効です。

自己修復と定期的な再同期は、ドリフトを修正するのに役立ちますが、ドリフト防止は管理対象オブジェクトの変更リクエストをインターセプトし、変更を許可する必要があるかどうかを検証します。変更が信頼できる情報源と一致しない場合、変更は拒否されます。ドリフト防止はデフォルトで無効になっています。有効にすると、ドリフト防止はデフォルトで RootSync オブジェクトを保護します。また、RepoSync オブジェクトを保護するように構成することもできます。

ドリフト防止を使用するには、RootSync API と RepoSync API を有効にする必要があります。

始める前に

Google Cloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新バージョンを取得します。

ドリフト防止を有効にする

ドリフト防止は、gcloud CLI を使用して有効にできます。 Cloud de Confiance コンソールで、ドリフト防止を有効にすることはできません。

ドリフト防止を有効にするには、次の操作を行います。

  1. 適用仕様マニフェストを更新して、spec.configSync.preventDrift フィールドを true に設定します。

    applySpecVersion: 1
    spec:
      configSync:
        enabled: true
        ... existing content ...
        preventDrift: true
    
  2. 更新されたマニフェストを適用します。

    gcloud beta container fleet config-management apply \
        --membership=MEMBERSHIP_NAME \
        --config=MANIFEST_NAME  \
        --project=PROJECT_ID
    

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

    • MEMBERSHIP_NAME: クラスタの登録時に選択したフリートのメンバーシップ名。gcloud container fleet memberships list コマンドを使用して名前を取得します。
    • MANIFEST_NAME: 適用仕様マニフェストの名前(通常は apply-spec.yaml)。
    • PROJECT_ID: プロジェクト ID。
  3. ConfigManagement Operator によって Config Sync ValidateWebhookConfiguration オブジェクトが作成されるまで待ちます。

    kubectl get validatingwebhookconfiguration admission-webhook.configsync.gke.io
    

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

    NAME                                  WEBHOOKS   AGE
    admission-webhook.configsync.gke.io   0          2m15s
    
  4. root-reconciler Deployment が Config Sync ValidatingWebhookConfiguration オブジェクトに Webhook を追加できるように、同期される信頼できる情報源の新しい変更を commit します。または、root-reconcilier Deployment を削除して調整をトリガーすることもできます。新しい root-reconciler Deployment により、Config Sync ValidatingWebhookConfiguration オブジェクトが更新されます。

  5. Webhook サーバーの準備が整うまで待ちます。Config Sync アドミッション Webhook デプロイログに serving webhook server が含まれているはずです。これには数分かかることがあります。

    kubectl logs -n config-management-system -l app=admission-webhook --tail=-1 | grep "serving webhook server"
    

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

    I1201 18:05:41.805531       1 deleg.go:130] controller-runtime/webhook "level"=0 "msg"="serving webhook server"  "host"="" "port"=10250
    I1201 18:07:04.626199       1 deleg.go:130] controller-runtime/webhook "level"=0 "msg"="serving webhook server"  "host"="" "port"=10250
    

ドリフト防止を無効にする

ドリフト防止を無効にすると、Config Sync は Config Sync アドミッション Webhook リソースをすべて削除します。Config Sync ValidatingWebhookConfiguration オブジェクトが存在しないため、Config Sync Reconciler はマネージド リソースの Webhook 構成ファイルを生成しません。

ドリフト防止を無効にするには、次の操作を行います。

  1. 適用仕様マニフェストを更新して、spec.configSync.preventDrift フィールドを false に設定します。

    applySpecVersion: 1
    spec:
      configSync:
        enabled: false
        ... existing content ...
        preventDrift: false
    
  2. 更新されたマニフェストを適用します。

    gcloud beta container fleet config-management apply \
        --membership=MEMBERSHIP_NAME \
        --config=MANIFEST_NAME  \
        --project=PROJECT_ID
    

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

    • MEMBERSHIP_NAME: クラスタの登録時に選択したフリートのメンバーシップ名。gcloud container fleet memberships list コマンドを使用して名前を取得します。
    • MANIFEST_NAME: 適用仕様マニフェストの名前(通常は apply-spec.yaml)。
    • PROJECT_ID: プロジェクト ID。

Namespace スコープの情報源で Admission Webhook を有効にする

Namespace スコープの信頼できる情報源は、Webhook で完全には保護されていません。各 Namespace ソースの Config Sync Reconciler には、クラスタレベルで ValidatingWebhookConfiguration オブジェクトの読み取りまたは更新を行う権限がありません。

この権限がないと、Namespace Reconciler のログに次のようなエラーが記録されます。

Failed to update admission webhook: KNV2013: applying changes to
admission webhook: Insufficient permission. To fix, make sure the reconciler has
sufficient permissions.:
validatingwebhookconfigurations.admissionregistration.k8s.io "admission-
webhook.configsync.gke.io" is forbidden: User "system:serviceaccount:config-
management-system:ns-reconciler-NAMESPACE" cannot update resource
"validatingwebhookconfigurations" in API group "admissionregistration.k8s.io" at
the cluster scope

Namespace スコープの信頼できる情報源に Webhook 保護を使用しない場合は、このエラーを無視して問題ありません。ただし、Webhook を使用する場合は、複数の信頼できる情報源からの同期を構成した後に、Namespace スコープの信頼できる各情報源の Reconciler に権限を付与します。ClusterRole cluster-admin 権限を持つ ns-reconciler-NAMESPACE の RoleBinding がすでに存在する場合、この操作を行う必要はありません。

  1. ルートの信頼できる情報源で、Config Sync Admission Webhook に対する権限を付与する新しい ClusterRole 構成を宣言します。この ClusterRole は、クラスタごとに 1 回だけ定義する必要があります。

    # ROOT_SOURCE/cluster-roles/webhook-role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: admission-webhook-role
    rules:
    - apiGroups: ["admissionregistration.k8s.io"]
      resources: ["validatingwebhookconfigurations"]
      resourceNames: ["admission-webhook.configsync.gke.io"]
      verbs: ["get", "update"]
    
  2. Admission Webhook 権限を付与する必要がある Namespace スコープのソースごとに ClusterRoleBinding 構成を宣言して、Admission Webhook へのアクセス権を付与します。

    # ROOT_SOURCE/NAMESPACE/sync-webhook-rolebinding.yaml
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: syncs-webhook
    subjects:
    - kind: ServiceAccount
      name: ns-reconciler-NAMESPACE
      namespace: config-management-system
    roleRef:
      kind: ClusterRole
      name: admission-webhook-role
      apiGroup: rbac.authorization.k8s.io
    

    NAMESPACE は、Namespace スコープのソースを作成した Namespace に置き換えます。

  3. Git リポジトリから同期する場合など、信頼できる情報源のルートに変更を commit します。

    git add .
    git commit -m 'Providing namespace repository the permission to update the admission webhook.'
    git push
    
    
  4. kubectl get を使用して ClusterRole と ClusterRoleBinding が作成されていることを確認します。

    kubectl get clusterrole admission-webhook-role
    kubectl get clusterrolebindings syncs-webhook
    

放棄されたリソースのドリフト防止を無効にする

デフォルトでは、RootSync オブジェクトまたは RepoSync オブジェクトを削除しても、Config Sync は以前に RootSync オブジェクトまたは RepoSync オブジェクトによって管理されていたリソースを変更しません。これにより、Config Sync がこれらのリソース オブジェクトの追跡に使用するラベルとアノテーションが残存する場合があります。この結果、ドリフト保護が有効になっている場合は、以前に管理されていたリソースへの変更が拒否される可能性があります。

削除の伝播を使用していない場合は、残存するリソース オブジェクトに Config Sync によって追加されたラベルとアノテーションが保持される可能性があります。

これらのマネージド リソースを保持する場合は、信頼できる情報源で宣言されているすべてのマネージド リソースで configmanagement.gke.io/managed アノテーションを disabled に設定して RootSync オブジェクトまたは RepoSync オブジェクトを削除する前に、これらのリソースを管理対象外にします。これにより、これらのリソースを削除することなく、マネージド リソースからラベルとアノテーションを削除するよう Config Sync に指示されます。同期の完了後、RootSync オブジェクトまたは RepoSync オブジェクトを削除できます。

これらのマネージド リソースを削除するには、次の 2 つの方法があります。

  • 信頼できる情報源からマネージド リソースを削除します。その後、Config Sync はクラスタからマネージド オブジェクトを削除します。同期の完了後、RootSync オブジェクトまたは RepoSync オブジェクトを削除できます。
  • 削除する前に、RootSync オブジェクトまたは RepoSync オブジェクトの削除の伝播を有効にします。その後、Config Sync はクラスタからマネージド オブジェクトを削除します。

マネージド リソースを管理対象外にする前または削除する前に RootSync オブジェクトまたは RepoSync オブジェクトを削除した場合は、RootSync オブジェクトまたは RepoSync オブジェクトを再作成すると信頼できる情報源に一致するクラスタのリソースが採用されます。その後、リソースを管理対象外にする、または削除し、変更が同期されるのを待ってから、RootSync オブジェクトまたは RepoSync オブジェクトを再度削除できます。

次のステップ