このページでは、CustomResourceDefinitionにバージョン情報を追加する方法を説明します。 バージョン情報は、CustomResourceDefinitionの安定性レベルを示したり、API表現間の変換を伴う新しいバージョンへAPIを進化させたりするために使用します。 また、オブジェクトをあるバージョンから別のバージョンにアップグレードする方法についても説明します。
Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:
カスタムリソースについての基本的な理解が必要です。
作業するKubernetesサーバーは次のバージョン以降のものである必要があります: v1.16.バージョンを確認するには次のコマンドを実行してください: kubectl version.
CustomResourceDefinition APIは、CustomResourceDefinitionの新しいバージョンを導入してアップグレードするためのワークフローを提供します。
CustomResourceDefinitionが作成されると、最初のバージョンがCustomResourceDefinitionのspec.versionsリストに適切な安定性レベルとバージョン番号で設定されます。
例えば、v1beta1は最初のバージョンがまだ安定していないことを示します。
すべてのカスタムリソースオブジェクトは、最初はこのバージョンで保存されます。
CustomResourceDefinitionが作成されると、クライアントはv1beta1 APIを使い始められます。
後にv1などの新しいバージョンを追加する必要が生じることがあります。
新しいバージョンを追加する手順:
None変換戦略を使用でき、異なるバージョンを提供する際にapiVersionフィールドのみが変更されます。spec.versionsリストにserved:trueを設定した新しいバージョンを追加します。
また、spec.conversionフィールドを選択した変換戦略に設定します。
Conversion Webhookを使用する場合は、spec.conversion.webhookClientConfigフィールドをWebhookを呼び出すように設定します。新しいバージョンが追加されると、クライアントは段階的に新しいバージョンへ移行できます。 一部のクライアントが古いバージョンを使用し、他のクライアントが新しいバージョンを使用することは問題ありません。
保存されているオブジェクトを新しいバージョンに移行する手順:
オブジェクトを新しい保存バージョンにアップグレードする前、最中、および後でも、クライアントが古いバージョンと新しいバージョンの両方を使用することは安全です。
古いバージョンを削除する手順:
servedをspec.versionsリストでfalseに設定します。
まだ古いバージョンを使用しているクライアントがある場合、古いバージョンでカスタムリソースオブジェクトにアクセスしようとするとエラーが報告されます。
その場合は、古いバージョンでserved:trueに戻し、残りのクライアントを新しいバージョンに移行してから、この手順を繰り返してください。spec.versionsリストで、新しいバージョンのstorageがtrueに設定されていることを確認します。status.storedVersionsにリストされていないことを確認します。spec.versionsリストから古いバージョンを削除します。CustomResourceDefinition APIのversionsフィールドは、開発したカスタムリソースの複数バージョンをサポートするために使用できます。
バージョンごとに異なるスキーマを持つことができ、Conversion Webhookによってカスタムリソースをバージョン間で変換できます。
WebhookConversionは、適用可能な箇所ではKubernetes API規約に従ってください。
特に、注意事項と提案についてのAPI変更ドキュメントを参照してください。
apiextensions.k8s.io/v1beta1では、versionsの代わりにversionフィールドがありました。
versionフィールドは非推奨でオプションですが、空でない場合はversionsフィールドの最初の項目と一致する必要があります。この例では、2つのバージョンを持つCustomResourceDefinitionを示します。 最初の例では、すべてのバージョンが同じスキーマを共有し、バージョン間の変換がないことを前提としています。 YAML内のコメントはより詳しいコンテキストを提供します。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# 名前は以下のspecフィールドと一致する必要があり、<plural>.<group>の形式である必要があります。
name: crontabs.example.com
spec:
# REST APIに使用するグループ名: /apis/<group>/<version>
group: example.com
# このCustomResourceDefinitionでサポートされるバージョンのリスト
versions:
- name: v1beta1
# 各バージョンはServedフラグで有効/無効を切り替えられます。
served: true
# 1つのバージョンのみをストレージバージョンとしてマークする必要があります。
storage: true
# スキーマは必須です
schema:
openAPIV3Schema:
type: object
properties:
host:
type: string
port:
type: string
- name: v1
served: true
storage: false
schema:
openAPIV3Schema:
type: object
properties:
host:
type: string
port:
type: string
# conversionセクションはKubernetes 1.13+で導入され、デフォルト値はNone変換(strategyサブフィールドがNoneに設定)です。
conversion:
# None変換はすべてのバージョンで同じスキーマを前提とし、カスタムリソースのapiVersionフィールドのみを適切な値に設定します
strategy: None
# NamespacedまたはClusterのいずれか
scope: Namespaced
names:
# URLで使用する複数形の名前: /apis/<group>/<version>/<plural>
plural: crontabs
# CLIでのエイリアスおよび表示に使用する単数形の名前
singular: crontab
# kindは通常、キャメルケースの単数形の型名です。リソースマニフェストでこれを使用します。
kind: CronTab
# shortNamesを使用するとCLIでリソースをより短い文字列で指定できます。
shortNames:
- ct
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# 名前は以下のspecフィールドと一致する必要があり、<plural>.<group>の形式である必要があります。
name: crontabs.example.com
spec:
# REST APIに使用するグループ名: /apis/<group>/<version>
group: example.com
# このCustomResourceDefinitionでサポートされるバージョンのリスト
versions:
- name: v1beta1
# 各バージョンはServedフラグで有効/無効を切り替えられます。
served: true
# 1つのバージョンのみをストレージバージョンとしてマークする必要があります。
storage: true
- name: v1
served: true
storage: false
validation:
openAPIV3Schema:
type: object
properties:
host:
type: string
port:
type: string
# conversionセクションはKubernetes 1.13+で導入され、デフォルト値はNone変換(strategyサブフィールドがNoneに設定)です。
conversion:
# None変換はすべてのバージョンで同じスキーマを前提とし、
# カスタムリソースのapiVersionフィールドのみを適切な値に設定します。
strategy: None
# NamespacedまたはClusterのいずれか
scope: Namespaced
names:
# URLで使用する複数形の名前: /apis/<group>/<version>/<plural>
plural: crontabs
# CLIでのエイリアスおよび表示に使用する単数形の名前
singular: crontab
# kindは通常、パスカルケースの単数形の型名です。リソースマニフェストでこれを使用します。
kind: CronTab
# shortNamesを使用するとCLIでリソースをより短い文字列で指定できます。
shortNames:
- ct
CustomResourceDefinitionをYAMLファイルに保存し、kubectl applyを使用して作成できます。
kubectl apply -f my-versioned-crontab.yaml
作成後、APIサーバーは有効化された各バージョンをHTTP RESTエンドポイントで提供し始めます。
上記の例では、APIバージョンは/apis/example.com/v1beta1と/apis/example.com/v1で利用できます。
CustomResourceDefinitionでバージョンが定義される順序に関わらず、kubectlはデフォルトバージョンとして最も優先度の高いバージョンを使用してオブジェクトにアクセスします。 優先度は、name フィールドを解析してバージョン番号、安定性(GA、Beta、Alpha)、およびその安定性レベル内のシーケンスを判断することで決定されます。
バージョンをソートするために使用されるアルゴリズムは、KubernetesプロジェクトがKubernetesバージョンをソートするのと同じ方法でバージョンをソートするよう設計されています。
バージョンはvで始まり、その後に数字、オプションのbetaまたはalpha指定、およびオプションの追加の数値バージョン情報が続きます。
大まかに言えば、バージョン文字列はv2またはv2beta1のようになります。
バージョンは以下のアルゴリズムを使用してソートされます。
betaまたはalphaという文字列が続く場合、それらはその順序でソートされ、betaまたはalphaサフィックスのない同等の文字列(GAバージョンと想定)の後に配置されます。betaまたはalphaの後に別の数字が続く場合、それらの数字も大きいものから小さいものへとソートされます。foo1がfoo10より先にソートされることに注意してください。
これはKubernetesバージョンパターンに従うエントリの数値部分のソートとは異なります。次のソート済みバージョンリストを見るとわかりやすいかもしれません。
- v10
- v2
- v1
- v11beta2
- v10beta3
- v3beta1
- v12alpha1
- v11alpha2
- foo1
- foo10
複数バージョンの指定の例では、バージョンのソート順はv1の後にv1beta1となります。
これにより、提供されたオブジェクトがバージョンを指定しない限り、kubectlコマンドはデフォルトバージョンとしてv1を使用します。
Kubernetes v1.19 [stable]
v1.19以降、CustomResourceDefinitionは定義するリソースの特定バージョンが非推奨であることを示せます。 そのリソースの非推奨バージョンへのAPIリクエストが行われると、APIレスポンスのヘッダーに警告メッセージが返されます。 必要に応じて、リソースの非推奨バージョンごとに警告メッセージをカスタマイズできます。
カスタマイズされた警告メッセージは、非推奨のAPIグループ、バージョン、およびkindを示し、該当する場合は代わりに使用すべきAPIグループ、バージョン、およびkindを示してください。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: crontabs.example.com
spec:
group: example.com
names:
plural: crontabs
singular: crontab
kind: CronTab
scope: Namespaced
versions:
- name: v1alpha1
served: true
storage: false
# カスタムリソースのv1alpha1バージョンが非推奨であることを示します。
# このバージョンへのAPIリクエストはサーバーレスポンスに警告ヘッダーを受け取ります。
deprecated: true
# v1alpha1 APIリクエストを行うAPIクライアントに返されるデフォルトの警告を上書きします。
deprecationWarning: "example.com/v1alpha1 CronTab is deprecated; see http://example.com/v1alpha1-v1 for instructions to migrate to example.com/v1 CronTab"
schema: ...
- name: v1beta1
served: true
# カスタムリソースのv1beta1バージョンが非推奨であることを示します。
# このバージョンへのAPIリクエストはサーバーレスポンスに警告ヘッダーを受け取ります。
# このバージョンにはデフォルトの警告メッセージが返されます。
deprecated: true
schema: ...
- name: v1
served: true
storage: true
schema: ...
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.example.com
spec:
group: example.com
names:
plural: crontabs
singular: crontab
kind: CronTab
scope: Namespaced
validation: ...
versions:
- name: v1alpha1
served: true
storage: false
# カスタムリソースのv1alpha1バージョンが非推奨であることを示します。
# このバージョンへのAPIリクエストはサーバーレスポンスに警告ヘッダーを受け取ります。
deprecated: true
# v1alpha1 APIリクエストを行うAPIクライアントに返されるデフォルトの警告を上書きします。
deprecationWarning: "example.com/v1alpha1 CronTab is deprecated; see http://example.com/v1alpha1-v1 for instructions to migrate to example.com/v1 CronTab"
- name: v1beta1
served: true
# カスタムリソースのv1beta1バージョンが非推奨であることを示します。
# このバージョンへのAPIリクエストはサーバーレスポンスに警告ヘッダーを受け取ります。
# このバージョンにはデフォルトの警告メッセージが返されます。
deprecated: true
- name: v1
served: true
storage: true
古いAPIバージョンは、その古いバージョンのカスタムリソースを提供したすべてのクラスターで既存の保存データが新しいAPIバージョンに移行され、古いバージョンがCustomResourceDefinitionのstatus.storedVersionsから削除されるまで、CustomResourceDefinitionマニフェストから削除できません。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: crontabs.example.com
spec:
group: example.com
names:
plural: crontabs
singular: crontab
kind: CronTab
scope: Namespaced
versions:
- name: v1beta1
# カスタムリソースのv1beta1バージョンが提供されなくなったことを示します。
# このバージョンへのAPIリクエストはサーバーレスポンスでnot foundエラーを受け取ります。
served: false
schema: ...
- name: v1
served: true
# 新しく提供するバージョンをストレージバージョンとして設定する必要があります。
storage: true
schema: ...
Kubernetes v1.16 [stable]
CustomResourceWebhookConversionフィーチャーゲートが有効である必要があります。
ベータ機能として多くのクラスターで自動的に有効化されています。
詳細についてはフィーチャーゲートのドキュメントを参照してください。上記の例では、バージョン間でNone変換を使用しており、変換時にapiVersionフィールドのみを設定し、オブジェクトの残りの部分は変更しません。
APIサーバーは、変換が必要な場合に外部サービスを呼び出すWebhookConversionもサポートしています。
例えば以下の場合です。
これらすべてのケースをカバーし、APIサーバーによる変換を最適化するために、変換リクエストには外部呼び出しを最小限に抑えるために複数のオブジェクトを含めることができます。 Webhookはこれらの変換を独立して実行する必要があります。
Kubernetes e2eテストで検証されているカスタムリソースConversion Webhookサーバーの実装を参照してください。
このWebhookはAPIサーバーから送信されたConversionReviewリクエストを処理し、ConversionResponseにラップした変換結果を返します。
リクエストには、オブジェクトの順序を変更せずに独立して変換する必要があるカスタムリソースのリストが含まれていることに注意してください。
このサーバーは他の変換にも再利用できるように構成されています。
共通コードのほとんどはフレームワークファイルにあり、異なる変換に対して実装が必要な1つの関数のみを残しています。
ClientAuthフィールドを空のままにしており、デフォルトはNoClientCertです。
つまり、Webhookサーバーはクライアント(おそらくAPIサーバー)の身元を認証しません。
相互TLSやその他の方法でクライアントを認証する必要がある場合は、APIサーバーの認証方法を参照してください。Conversion Webhookは、変換されたオブジェクトのmetadata内のlabelsとannotations以外のものを変更してはなりません。
name、UID、namespaceへの変更はリジェクトされ、変換を引き起こしたリクエストは失敗します。
その他のすべての変更は無視されます。
Conversion Webhookのデプロイに関するドキュメントは、アドミッションWebhookのサービス例と同じです。
以降のセクションでは、Conversion Webhookサーバーがdefault Namespaceのexample-conversion-webhook-serverという名前のサービスにデプロイされ、/crdconvertパスでトラフィックを提供していることを前提としています。
None変換の例は、specのconversionセクションを変更することで、Conversion Webhookを使用するように拡張できます。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# 名前は以下のspecフィールドと一致する必要があり、<plural>.<group>の形式である必要があります。
name: crontabs.example.com
spec:
# REST APIに使用するグループ名: /apis/<group>/<version>
group: example.com
# このCustomResourceDefinitionでサポートされるバージョンのリスト
versions:
- name: v1beta1
# 各バージョンはServedフラグで有効/無効を切り替えられます。
served: true
# 1つのバージョンのみをストレージバージョンとしてマークする必要があります。
storage: true
# トップレベルのスキーマが定義されていない場合、各バージョンが独自のスキーマを定義できます。
schema:
openAPIV3Schema:
type: object
properties:
hostPort:
type: string
- name: v1
served: true
storage: false
schema:
openAPIV3Schema:
type: object
properties:
host:
type: string
port:
type: string
conversion:
# Webhookストラテジーは、カスタムリソース間のあらゆる変換に対して外部Webhookを呼び出すようAPIサーバーに指示します。
strategy: Webhook
# Webhookは、strategyが`Webhook`の場合に必須であり、APIサーバーが呼び出すWebhookエンドポイントを設定します。
webhook:
# conversionReviewVersionsはWebhookが理解/推奨するConversionReviewのバージョンを示します。
# リストの中でAPIサーバーが理解できる最初のバージョンがWebhookに送信されます。
# Webhookは受け取ったのと同じバージョンのConversionReviewオブジェクトで応答する必要があります。
conversionReviewVersions: ["v1","v1beta1"]
clientConfig:
service:
namespace: default
name: example-conversion-webhook-server
path: /crdconvert
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"
# NamespacedまたはClusterのいずれか
scope: Namespaced
names:
# URLで使用する複数形の名前: /apis/<group>/<version>/<plural>
plural: crontabs
# CLIでのエイリアスおよび表示に使用する単数形の名前
singular: crontab
# kindは通常、キャメルケースの単数形の型名です。リソースマニフェストでこれを使用します。
kind: CronTab
# shortNamesを使用するとCLIでリソースをより短い文字列で指定できます。
shortNames:
- ct
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# 名前は以下のspecフィールドと一致する必要があり、<plural>.<group>の形式である必要があります。
name: crontabs.example.com
spec:
# REST APIに使用するグループ名: /apis/<group>/<version>
group: example.com
# 以下のOpenAPIスキーマで指定されていないオブジェクトフィールドを除去します。
preserveUnknownFields: false
# このCustomResourceDefinitionでサポートされるバージョンのリスト
versions:
- name: v1beta1
# 各バージョンはServedフラグで有効/無効を切り替えられます。
served: true
# 1つのバージョンのみをストレージバージョンとしてマークする必要があります。
storage: true
# トップレベルのスキーマが定義されていない場合、各バージョンが独自のスキーマを定義できます。
schema:
openAPIV3Schema:
type: object
properties:
hostPort:
type: string
- name: v1
served: true
storage: false
schema:
openAPIV3Schema:
type: object
properties:
host:
type: string
port:
type: string
conversion:
# Webhookストラテジーは、カスタムリソース間のあらゆる変換に対して外部Webhookを呼び出すようAPIサーバーに指示します。
strategy: Webhook
# webhookClientConfigは、strategyが`Webhook`の場合に必須であり、APIサーバーが呼び出すWebhookエンドポイントを設定します。
webhookClientConfig:
service:
namespace: default
name: example-conversion-webhook-server
path: /crdconvert
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"
# NamespacedまたはClusterのいずれか
scope: Namespaced
names:
# URLで使用する複数形の名前: /apis/<group>/<version>/<plural>
plural: crontabs
# CLIでのエイリアスおよび表示に使用する単数形の名前
singular: crontab
# kindは通常、キャメルケースの単数形の型名です。リソースマニフェストでこれを使用します。
kind: CronTab
# shortNamesを使用するとCLIでリソースをより短い文字列で指定できます。
shortNames:
- ct
CustomResourceDefinitionをYAMLファイルに保存し、kubectl applyを使用して適用できます。
kubectl apply -f my-versioned-crontab-with-conversion.yaml
新しい変更を適用する前に、変換サービスが起動して実行されていることを確認してください。
APIサーバーがリクエストをConversion Webhookに送信すべきと判断すると、Webhookへの接続方法を知る必要があります。
これはWebhook設定のwebhookClientConfigスタンザで指定します。
Conversion WebhookはURLまたはサービスへの参照を通じて呼び出すことができ、オプションでTLS接続の検証に使用するカスタムCAバンドルを含めることができます。
urlはWebhookの場所を標準的なURL形式(scheme://host:port/path)で指定します。
hostはクラスター内で実行中のサービスを参照しないようにしてください。
代わりにserviceフィールドを指定してサービスへの参照を使用してください。
ホストは一部のAPIサーバー(例えば、kube-apiserverはレイヤー違反になるためクラスター内DNSを解決できません)では外部DNSを通じて解決される場合があります。
hostはIPアドレスでも構いません。
localhostまたは127.0.0.1をhostとして使用することは、このWebhookを必要とする可能性のあるAPIサーバーを実行するすべてのホストで、このWebhookを実行するよう細心の注意を払わない限りリスクがあります。
このようなインストールはポータブルでなかったり、新しいクラスターでの実行が難しかったりする可能性があります。
スキームは"https"である必要があります。 URLは"https://"で始まる必要があります。
ユーザー認証またはBasic認証(例えば "user:password@")の使用は許可されていません。 フラグメント("#...")およびクエリパラメーター("?...")も許可されていません。
以下は、URLを呼び出すように設定されたConversion Webhookの例です(TLS証明書はシステムの信頼ルートを使用して検証されるため、caBundleは指定していません)。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
webhook:
clientConfig:
url: "https://my-webhook.example.com:9443/my-webhook-path"
...
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
webhookClientConfig:
url: "https://my-webhook.example.com:9443/my-webhook-path"
...
webhookClientConfig内のserviceスタンザは、Conversion Webhookのサービスへの参照です。
Webhookがクラスター内で実行されている場合は、urlの代わりにserviceを使用してください。
サービスのNamespaceと名前は必須です。
ポートはオプションで、デフォルトは443です。
パスはオプションで、デフォルトは"/"です。
以下は、サブパス"/my-path"のポート"1234"でサービスを呼び出し、カスタムCAバンドルを使用してServerName my-service-name.my-service-namespace.svcに対するTLS接続を検証するように設定されたWebhookの例です。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
webhook:
clientConfig:
service:
namespace: my-service-namespace
name: my-service-name
path: /my-path
port: 1234
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"
...
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
webhookClientConfig:
service:
namespace: my-service-namespace
name: my-service-name
path: /my-path
port: 1234
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"
...
WebhookにはContent-Type: application/jsonを持つPOSTリクエストが送信され、apiextensions.k8s.io APIグループのConversionReview APIオブジェクトがJSONとしてシリアライズされたものがボディとして含まれます。
WebhookはCustomResourceDefinitionのconversionReviewVersionsフィールドを使用して、受け入れるConversionReviewオブジェクトのバージョンを指定できます。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
webhook:
conversionReviewVersions: ["v1", "v1beta1"]
...
conversionReviewVersionsはapiextensions.k8s.io/v1カスタムリソース定義を作成する際の必須フィールドです。
Webhookは現在および1つ前のAPIサーバーが理解できるConversionReviewバージョンを少なくとも1つサポートする必要があります。
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
...
spec:
...
conversion:
strategy: Webhook
conversionReviewVersions: ["v1", "v1beta1"]
...
conversionReviewVersionsが指定されない場合、apiextensions.k8s.io/v1beta1カスタムリソース定義を作成する際のデフォルトはv1beta1です。
APIサーバーはconversionReviewVersionsリストの中でサポートする最初のConversionReviewバージョンを送信します。
リスト内のバージョンがAPIサーバーでサポートされていない場合、カスタムリソース定義は作成できません。
以前に作成されたConversion Webhook設定にAPIサーバーが送信できるConversionReviewバージョンのいずれもサポートされていない場合、Webhookの呼び出しは失敗します。
この例では、CronTabオブジェクトをexample.com/v1に変換するリクエストのConversionReviewオブジェクトに含まれるデータを示します。
{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "ConversionReview",
"request": {
# この変換呼び出しを一意に識別するランダムなuid
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
# オブジェクトを変換すべきAPIグループとバージョン
"desiredAPIVersion": "example.com/v1",
# 変換するオブジェクトのリスト。
# 1つまたは複数のバージョン、1つまたは複数のオブジェクトを含む場合があります。
"objects": [
{
"kind": "CronTab",
"apiVersion": "example.com/v1beta1",
"metadata": {
"creationTimestamp": "2019-09-04T14:03:02Z",
"name": "local-crontab",
"namespace": "default",
"resourceVersion": "143",
"uid": "3415a7fc-162b-4300-b5da-fd6083580d66"
},
"hostPort": "localhost:1234"
},
{
"kind": "CronTab",
"apiVersion": "example.com/v1beta1",
"metadata": {
"creationTimestamp": "2019-09-03T13:02:01Z",
"name": "remote-crontab",
"resourceVersion": "12893",
"uid": "359a83ec-b575-460d-b553-d859cedde8a0"
},
"hostPort": "example.com:2345"
}
]
}
}
{
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
"apiVersion": "apiextensions.k8s.io/v1beta1",
"kind": "ConversionReview",
"request": {
# この変換呼び出しを一意に識別するランダムなuid
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
# オブジェクトを変換すべきAPIグループとバージョン
"desiredAPIVersion": "example.com/v1",
# 変換するオブジェクトのリスト。
# 1つまたは複数のバージョンの1つまたは複数のオブジェクトを含む場合があります。
"objects": [
{
"kind": "CronTab",
"apiVersion": "example.com/v1beta1",
"metadata": {
"creationTimestamp": "2019-09-04T14:03:02Z",
"name": "local-crontab",
"namespace": "default",
"resourceVersion": "143",
"uid": "3415a7fc-162b-4300-b5da-fd6083580d66"
},
"hostPort": "localhost:1234"
},
{
"kind": "CronTab",
"apiVersion": "example.com/v1beta1",
"metadata": {
"creationTimestamp": "2019-09-03T13:02:01Z",
"name": "remote-crontab",
"resourceVersion": "12893",
"uid": "359a83ec-b575-460d-b553-d859cedde8a0"
},
"hostPort": "example.com:2345"
}
]
}
}
WebhookはHTTPステータスコード200、Content-Type: application/json、およびConversionReviewオブジェクト(送信されたのと同じバージョン)を含むボディで応答します。
このオブジェクトはresponseスタンザが設定され、JSONにシリアライズされています。
変換が成功した場合、Webhookは以下のフィールドを含むresponseスタンザを返す必要があります:
request.uidからコピーされたuid{"status":"Success"}に設定されたresultrequest.objectsのすべてのオブジェクトをrequest.desiredAPIVersionに変換したものを含むconvertedObjectsWebhookからの最小限の成功レスポンスの例:
{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "ConversionReview",
"response": {
# <request.uid>と一致する必要があります。
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
"result": {
"status": "Success"
},
# オブジェクトはrequest.objectsの順序と一致し、apiVersionが<request.desiredAPIVersion>に設定されている必要があります。
# kind、metadata.uid、metadata.name、metadata.namespaceフィールドはWebhookによって変更してはなりません。
# metadata.labelsとmetadata.annotationsフィールドはWebhookによって変更できます。
# Webhookによるmetadataフィールドのその他すべての変更は無視されます。
"convertedObjects": [
{
"kind": "CronTab",
"apiVersion": "example.com/v1",
"metadata": {
"creationTimestamp": "2019-09-04T14:03:02Z",
"name": "local-crontab",
"namespace": "default",
"resourceVersion": "143",
"uid": "3415a7fc-162b-4300-b5da-fd6083580d66"
},
"host": "localhost",
"port": "1234"
},
{
"kind": "CronTab",
"apiVersion": "example.com/v1",
"metadata": {
"creationTimestamp": "2019-09-03T13:02:01Z",
"name": "remote-crontab",
"resourceVersion": "12893",
"uid": "359a83ec-b575-460d-b553-d859cedde8a0"
},
"host": "example.com",
"port": "2345"
}
]
}
}
{
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
"apiVersion": "apiextensions.k8s.io/v1beta1",
"kind": "ConversionReview",
"response": {
# <request.uid>と一致する必要があります。
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
"result": {
"status": "Failed"
},
# オブジェクトはrequest.objectsの順序と一致し、apiVersionが<request.desiredAPIVersion>に設定されている必要があります。
# kind、metadata.uid、metadata.name、metadata.namespaceフィールドはWebhookによって変更してはなりません。
# metadata.labelsとmetadata.annotationsフィールドはWebhookによって変更できます。
# Webhookによるmetadataフィールドのその他すべての変更は無視されます。
"convertedObjects": [
{
"kind": "CronTab",
"apiVersion": "example.com/v1",
"metadata": {
"creationTimestamp": "2019-09-04T14:03:02Z",
"name": "local-crontab",
"namespace": "default",
"resourceVersion": "143",
"uid": "3415a7fc-162b-4300-b5da-fd6083580d66"
},
"host": "localhost",
"port": "1234"
},
{
"kind": "CronTab",
"apiVersion": "example.com/v1",
"metadata": {
"creationTimestamp": "2019-09-03T13:02:01Z",
"name": "remote-crontab",
"resourceVersion": "12893",
"uid": "359a83ec-b575-460d-b553-d859cedde8a0"
},
"host": "example.com",
"port": "2345"
}
]
}
}
変換が失敗した場合、Webhookは以下のフィールドを含むresponseスタンザを返す必要があります:
request.uidからコピーされたuid{"status":"Failed"}に設定されたresult変換リクエストの失敗を示すWebhookからのレスポンスの例(オプションのメッセージ付き):
{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "ConversionReview",
"response": {
"uid": "<value from request.uid>",
"result": {
"status": "Failed",
"message": "hostPort could not be parsed into a separate host and port"
}
}
}
{
# v1.16でapiextensions.k8s.io/v1を推奨として非推奨になりました。
"apiVersion": "apiextensions.k8s.io/v1beta1",
"kind": "ConversionReview",
"response": {
"uid": "<value from request.uid>",
"result": {
"status": "Failed",
"message": "hostPort could not be parsed into a separate host and port"
}
}
}
オブジェクトが書き込まれると、書き込み時にストレージバージョンとして指定されているバージョンで保存されます。 ストレージバージョンが変更されても、既存のオブジェクトは自動的に変換されません。 ただし、新しく作成または更新されたオブジェクトは新しいストレージバージョンで書き込まれます。 オブジェクトが現在提供されていないバージョンで書き込まれていた可能性があります。
オブジェクトを読み取る際は、パスの一部としてバージョンを指定します。 現在提供されているバージョンであれば、任意のバージョンでオブジェクトをリクエストできます。 オブジェクトの保存バージョンとは異なるバージョンを指定した場合、Kubernetesはリクエストしたバージョンでオブジェクトを返しますが、保存されているオブジェクトはディスク上で変更されません。
読み取りリクエストを提供する際に返されるオブジェクトに何が起きるかは、CRDのspec.conversionに何が指定されているかによります:
strategy値Noneが指定されている場合、オブジェクトへの変更はapiVersion文字列の変更と、不明なフィールドのプルーニング(設定に依存)のみです。
保存バージョンとリクエストバージョン間でスキーマが異なる場合、この方法では適切な結果が得られない可能性があることに注意してください。
特に、バージョン間で同じデータが異なるフィールドで表現されている場合は、このストラテジーを使用しないでください。既存のオブジェクトを更新すると、現在のストレージバージョンで書き直されます。 これがオブジェクトがあるバージョンから別のバージョンに変更される唯一の方法です。
これを説明するために、以下の仮想的な一連のイベントを考えてみましょう:
v1beta1です。
オブジェクトを作成します。
バージョンv1beta1で保存されます。v1バージョンを追加して、ストレージバージョンとして指定します。
ここではv1とv1beta1のスキーマが同一であり、これはKubernetesエコシステムでAPIを安定版に昇格させる際の通常のケースです。v1beta1で読み取り、次にバージョンv1で再度読み取ります。
返された両方のオブジェクトはapiVersionフィールドを除いて同一です。v1で保存されます。
これで2つのオブジェクトがあり、一方はv1beta1で、もう一方はv1です。v1であるため、バージョンv1で保存されます。APIサーバーは、ストレージバージョンとしてマークされたことがあるすべてのバージョンをステータスフィールドのstoredVersionsに記録します。
オブジェクトは、ストレージバージョンとして指定されたことがある任意のバージョンで保存されている場合があります。
ストレージバージョンであったことがないバージョンのオブジェクトはストレージに存在できません。
バージョンを非推奨化してサポートを終了する場合は、ストレージアップグレード手順を選択してください。
オプション1: Storage Version Migratorを使用する
status.storedVersionsフィールドから古いバージョンを削除しますオプション2: 既存のオブジェクトを新しい保存バージョンに手動でアップグレードする
以下はv1beta1からv1へのアップグレード手順の例です。
v1をストレージに設定し、kubectlを使用して適用します。
storedVersionsはv1beta1, v1になります。v1)でオブジェクトを書き込むよう強制されます。status.storedVersionsフィールドからv1beta1を削除します。kubectlを使用してCRDオブジェクトのstatusサブリソースにパッチを当てる方法の例を以下に示します:
kubectl patch customresourcedefinitions <CRD_Name> --subresource='status' --type='merge' -p '{"status":{"storedVersions":["v1"]}}'