未指定のフィールドを無視する


このドキュメントでは、cnrm.cloud.google.com/state-into-spec アノテーションを使用してデフォルトの仕様フィールドに入力する動作を変更する方法と、それを変更する必要がある場合について説明します。

外部でのフィールドの管理で説明されているように、Config Connector が Google Cloud にリソースを作成すると、読み取り可能でない限り、仕様に指定されていないフィールドは API の値が使用されます(たとえば、GET HTTP リクエストを使用して利用することはできません)。

つまり、デフォルトでは、元の YAML で指定されていないフィールドは常に Kubernetes リソースの仕様に表示されます。つまり、kubectl get <resource kind> <resource name> -oyaml を実行したときに、リソース仕様の多くのフィールドは、適用した YAML にありません。

たとえば、CRD スキーマで foobar という名前の 2 つのフィールドを仕様に指定できて、適用された YAML ファイルに foo のみが指定されているとします。

spec:
  foo: "foo"

YAML が正常に適用され、リソースが UpToDate の場合、bar という名前の別のフィールドが Kubernetes リソースに表示されます。

spec:
  foo: "foo"
  bar: "bar"

Config Connector と Google Cloud APIs 間のやり取りは複雑であるため、デフォルトの動作を変更して、リソース仕様に未指定のフィールドを入力しないようにすることをおすすめします。

未指定のフィールドの仕様への入力をスキップする

YAML ファイルを作成するときに、cnrm.cloud.google.com/state-into-spec アノテーションの値を absent と指定できます。これにより、Kubernetes リソース仕様に未指定のフィールドの入力が省略されます。

metadata:
  annotations:
    cnrm.cloud.google.com/state-into-spec: absent

指定しない場合、このアノテーションにはデフォルト値の merge が設定されます。つまり、Config Connector によってすべての未指定フィールドが仕様に設定されます。このアノテーションは不変です。つまり、既存の Config Connector リソースのアノテーション値を更新することはできません。

リソースをすでに作成しているが、別の入力動作のためにこのアノテーションの値を変更する場合は、次の手順に従う必要があります。

  1. アノテーション cnrm.cloud.google.com/deletion-policy: abandon を編集して既存の Kubernetes リソースに追加し、次のステップで削除しても基盤となる Google Cloud リソースが削除されないようにします。

  2. Kubernetes クラスタからリソースを削除します。

  3. アノテーション cnrm.cloud.google.com/state-into-spec: absent をリソースの YAML に追加します。

  4. (省略可)YAML から cnrm.cloud.google.com/deletion-policy: abandon を削除します。

  5. 更新された YAML を適用します。

このアノテーションによって生じる違いについて詳細に説明するために、次のスキーマの仕様があるとします。

foo1: string
foo2: string
bars:
- bar:
    br1: string
    br2: string
barz:
  bz1: string
  bz2: string

また、YAML で仕様を次のように指定したとします。

spec:
  foo1: "foo1"
  bars:
  - br1: "1_br1"
  - br1: "2_br1"
  barz:
    bz1: "bz1"

デフォルトでは、作成された Kubernetes リソースの入力仕様は次のようになります。

spec:
  foo1: "foo1"
  foo2: "foo2"
  bars:
  - br1: "1_br1"
    br2: "1_br2"
  - br1: "2_br1"
    br2: "2_br2"
  barz:
    bz1: "bz1"
    bz2: "bz2"

cnrm.cloud.google.com/state-into-spec: absent を設定すると、作成される Kubernetes リソースの最終仕様は次のようになります。

spec:
  foo1: "foo1"
  bars:
  - br1: "1_br1"
  - br1: "2_br1"
  barz:
    bz1: "bz1"

cnrm.cloud.google.com/state-into-spec: absent を使用するケース

cnrm.cloud.google.com/state-into-spec: absent の設定が必要となる一般的なシナリオがいくつかあります。

リスト内の未指定のフィールドを外部で管理する

Config Connector は、リソース仕様のすべてのリスト フィールドをアトミック フィールドとして扱います。その結果、Config Connector の外部からリスト内のサブフィールドに加えた変更は、デフォルトで Config Connector によって元に戻されます。ただし、このアノテーションを使用して、Config Connector がリスト内のサブフィールドを管理対象外にすることもできます。詳細については、リソース仕様のリスト フィールドの動作をご覧ください。

構成管理ツールと Config Connector 間の競合を解決する

Config SyncArgo CD などの構成管理ツールを使用している場合、構成管理ツールと Config Connector の間で競合が発生することがあります。たとえば、トラブルシューティング ガイドで説明されている KNV2005 エラーです。このような問題の根本原因は次のとおりです。

  1. Config Connector は、仕様のリストに値が入力され、デフォルトでは指定されません。spec.bars[0].br2 は一例です。
  2. 構成管理ツールと Config Connector は、どちらもリスト フィールドをアトミックとして扱います。したがって、追加された spec.bars[0].br2 は、構成管理ツールでブレとして扱われ、drift を修正するために削除されます。

これらの問題を解決するには、Config Connector が未指定のフィールド spec.bars[0].br2 を仕様に追加しないように、cnrm.cloud.google.com/state-into-spec: absent を設定します。

GET / PUT の対称性の問題を解決する

GET / PUT の対称性は、REST API の設計原則を示します。具体的には、GET レスポンスが PUT リクエストとして同じ URL に送信されると、基になる REST リソースの状態に変更がない HTTP 200 OK レスポンスになることが想定されます。

リソース仕様の Config Connector によって入力される未指定のフィールドは、GET リクエストの結果として行われます。つまり、今後の調整では、Config Connector が、GET リクエストから学習した未指定のフィールド値を使用して、PUT / PATCH リクエストを基盤となる Google Cloud API に送信するということです。通常、これは問題になりませんが、未指定のフィールド値が原因で、一部の Google Cloud APIs で PUT / PATCH リクエストが拒否される可能性があります。同じ例で、API 実装が GET / PUT の対称性の原則に違反している場合は、値「bz2」が設定された spec.barz.bz2 によって、HTTP 400 クライアント エラーやその他の予期しないレスポンスが発生する可能性があります。

このカテゴリの問題を回避するには、cnrm.cloud.google.com/state-into-spec: absent の設定を試して、調整中のエラーが消えるかどうかを確認します。

cnrm.cloud.google.com/state-into-spec: absent を回避するケース

ソリューションが未指定のフィールドから入力された値に依存する場合は、cnrm.cloud.google.com/state-into-spec: absent を設定しないでください。たとえば、ComputeAddress リソースを使用していて、サーバーによって生成された spec.address 値が必要な場合(元の YAML では未指定フィールドである可能性があります)、spec.address の値は Kubernetes リソース仕様に入力されないので、このアノテーションは使用しないでください。

観測された状態

cnrm.cloud.google.com/state-into-spec: absent を設定する必要があるものの、ソリューションが未指定のフィールドから入力された値に依存する場合は、これらのフィールドが CRD スキーマの status.observedState の下に存在するかどうかを確認します。これらが status.observedState の下に表されている場合は、cnrm.cloud.google.com/state-into-spec: absent を設定した後、調整が成功した後でも、指定されていないフィールドの値にアクセスできます。

status.observedState フィールドには、Config Connector が最後に成功した調整でモニタリングしたリソースについて、選択された観測されたフィールドのライブ状態が含まれます。観測されたフィールドは、一般的なユースケースの依存関係であり、計算された spec フィールドである場合に選択されます。観測されたフィールドは、CRD スキーマで確認できます。

目的の観測フィールドが見つからない場合は、既存の問題を確認するか、公開 Issue Tracker で新しい問題を開いてください。