未指定のフィールドを無視する
このドキュメントでは、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 スキーマで foo
と bar
という名前の 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 リソースのアノテーション値を更新することはできません。
リソースをすでに作成しているが、別の入力動作のためにこのアノテーションの値を変更する場合は、次の手順に従う必要があります。
アノテーション
cnrm.cloud.google.com/deletion-policy: abandon
を編集して既存の Kubernetes リソースに追加し、次のステップで削除しても基盤となる Google Cloud リソースが削除されないようにします。Kubernetes クラスタからリソースを削除します。
アノテーション
cnrm.cloud.google.com/state-into-spec: absent
をリソースの YAML に追加します。(省略可)YAML から
cnrm.cloud.google.com/deletion-policy: abandon
を削除します。更新された 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 Sync や Argo CD などの構成管理ツールを使用している場合、構成管理ツールと Config Connector の間で競合が発生することがあります。たとえば、トラブルシューティング ガイドで説明されている KNV2005 エラーです。このような問題の根本原因は次のとおりです。
- Config Connector は、仕様のリストに値が入力され、デフォルトでは指定されません。
spec.bars[0].br2
は一例です。 - 構成管理ツールと 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 で新しい問題を開いてください。