こんにちは。Xイノベーション本部クラウドイノベーションセンターの柴田です。
本記事ではkustomizeでCustom Resourceを扱う方法を紹介します。
kustomizeとは
kustomize はKubernetesのマニフェストファイルを加工・生成するためのツールです。 ユースケースとして例えば環境毎(開発や本番など)にマニフェストの設定を上書きしたい場合などに利用できます。
kustomizeは内部にKubernetesの標準リソース( Deployment
など)のスキーマを保持しています。
これにより標準リソースのマニフェストを適切に加工できます。
例をみてみましょう。今回は以下の Deployment
リソースをkustomizeで加工します。
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp template: metadata: labels: app.kubernetes.io/name: myapp spec: containers: - name: myapp image: myapp:stable env: - name: KEY1 value: VALUE1 - name: KEY2 value: VALUE2 - name: mysidecar image: mysidecar:stable
同一ディレクトリに kustomization.yaml
を作成します。設定内容は以下のとおりです。
commonLabels
で全体にapp.kubernetes.io/name: myapp-overwrite
labelを設定します。patches
でmyapp
コンテナに環境変数KEY2=VALUE2-overwrite
を設定します。
# kustomization.yaml (for deployment) apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app.kubernetes.io/name: myapp-overwrite resources: - deployment.yaml patches: - patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite
kustomize build
コマンドを実行すると以下の結果が出力されます。
Deployment
が期待通り加工されました。
# Output of `kustomize build` command. apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite - name: KEY1 value: VALUE1 image: myapp:stable name: myapp - image: mysidecar:stable name: mysidecar
ここでのポイントは以下の2点です。
containers
やenv
について、単に配列をまるごと上書きするのではなく、name
の値をキーに適切にマージされている。.metadata.labels
だけでなく.spec.selector.matchLabels
や.spec.template.metadata.labels
にもapp.kubernetes.io/name
labelが設定されている。
kustomizeでCustom Resourceを適切に扱う
kustomizeはデフォルトでCustom Resourceを適切に扱えない
kustomizeはデフォルトでCustom Resourceを適切に加工できません。 kustomizeがCustom Resourceのスキーマを把握していないためです。
例をみてみましょう。今回は Argo Rollouts の Rollout
リソースをkustomizeで加工します。
# rollout.yaml apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp template: metadata: labels: app.kubernetes.io/name: myapp spec: containers: - name: myapp image: myapp:stable env: - name: KEY1 value: VALUE1 - name: KEY2 value: VALUE2 - name: mysidecar image: mysidecar:stable
同一ディレクトリに kustomization.yaml
を作成します。
# kustomization.yaml (for rollout) apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app.kubernetes.io/name: myapp-overwrite resources: - rollout.yaml patches: - patch: |- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite
kustomize build
コマンドを実行すると以下の結果が出力されます。
# Output of `kustomize build` command. apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp template: metadata: labels: app.kubernetes.io/name: myapp spec: containers: - env: - name: KEY2 value: VALUE2-overwrite name: myapp
先程の Deployment
の例と比較すると以下の点が異なります。
containers
やenv
がpatches
の内容でまるごと上書きされている。.spec.selector.matchLabels
や.spec.template.metadata.labels
のapp.kubernetes.io/name
labelが更新されていない。
kustomizeでCustom Resourceを適切に扱う
kustomzieでCustom Resourceを扱うには、以下の2つの対応を行う必要があります。
- kustomizeの OpenAPI Features を使用して、kustomizeにCustom ResourceのOpenAPIスキーマを設定する。
- kustomizeの Transformer Configurations を設定する。
Argo Rolloutsの公式ドキュメント に従って、先程のArgo Rolloutsの例を以下のとおり修正してみましょう。
curl -OL https://github.com/argoproj/argo-rollouts/raw/master/docs/features/kustomize/rollout_cr_schema.json
kustomization.yaml
にopenapi
とconfigurations
の設定を追記します。
# kustomization.yaml (for rollout) apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app.kubernetes.io/name: myapp-overwrite resources: - rollout.yaml patches: - patch: |- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite openapi: path: rollout_cr_schema.json configurations: - https://argoproj.github.io/argo-rollouts/features/kustomize/rollout-transform.yaml
kustomize build
コマンドを実行すると以下の結果が出力されます。
今度は Rollout
リソースが(ほぼ)期待通り加工されました。
なお env
は依然として上書きされていますが、これはArgo RolloutsのOpenAPIスキーマの問題です。
詳細は #1730 をご参照ください。
# Output of `kustomize build` command. apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite image: myapp:stable name: myapp - image: mysidecar:stable name: mysidecar
kustomizeで標準リソースとCustom Resourceを適切に扱う
独自のOpenAPIスキーマを設定すると標準リソースを適切に扱えなくなる
kustomizeの OpenAPI Features は、build-inのスキーマに 加えて 受け取ったOpenAPIスキーマを参照するのではなく、build-inのスキーマの かわりに 受け取ったOpenAPIスキーマを参照します。
そのため kustomization.yaml
の openapi
に独自のOpenAPIスキーマを設定すると、kustomizeがKubernetesの標準リソースのスキーマを参照できず、適切に加工できなくなります。
例をみてみましょう。今回はkustomizeで Deployment
と Rollout
の両方を加工します。
deployment.yaml
と rollout.yaml
は先程の例と同じものを使用します。
# kustomization.yaml (for deployment and rollout) apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app.kubernetes.io/name: myapp-overwrite resources: - deployment.yaml - rollout.yaml patches: - patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite - patch: |- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite openapi: path: rollout_cr_schema.json configurations: - https://argoproj.github.io/argo-rollouts/features/kustomize/rollout-transform.yaml
kustomize build
コマンドを実行すると以下の結果が出力されます。
kustomization.yaml
の oepnapi
にArgo RolloutsのOpenAPIスキーマを設定したため Rollout
は期待通り加工できました。
しかし今度は Deployment
の containers
や env
が patches
の内容でまるごと上書きされてしまいました。
# Output of `kustomize build` command. kustomize build . apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite name: myapp --- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite image: myapp:stable name: myapp - image: mysidecar:stable name: mysidecar
kustomizeで標準リソースとCustom Resourceを適切に扱う
この問題は
- 標準リソース
- Custom Resource
の両方のOpenAPIスキーマを統合して kustomization.yaml
の oepnapi
に渡すことで解決できます。
先程の例を以下のとおり修正してみましょう。 Kubernetesの標準リソースのOpenAPIスキーマは こちら からダウンロードできます。
- 標準リソースとArgo RolloutsのOpenAPIスキーマを統合する。
curl -sOL https://github.com/kubernetes/kubernetes/raw/master/api/openapi-spec/swagger.json curl -sOL https://github.com/argoproj/argo-rollouts/raw/master/docs/features/kustomize/rollout_cr_schema.json jq -s '.[0] * .[1]' swagger.json rollout_cr_schema.json > openapi.json
- 作成したファイルを
kustomization.yaml
のopenapi
に指定する。
# kustomization.yaml (for deployment and rollout) apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app.kubernetes.io/name: myapp-overwrite resources: - deployment.yaml - rollout.yaml patches: - patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite - patch: |- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: template: spec: containers: - name: myapp env: - name: KEY2 value: VALUE2-overwrite openapi: path: openapi.json configurations: - https://argoproj.github.io/argo-rollouts/features/kustomize/rollout-transform.yaml
kustomize build
コマンドを実行すると以下の結果が出力されます。
今度は Deployment
と Rollout
の両方を期待通り加工できました。
# Output of `kustomize build` command. kustomize build . apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite - name: KEY1 value: VALUE1 image: myapp:stable name: myapp - image: mysidecar:stable name: mysidecar --- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: labels: app.kubernetes.io/name: myapp-overwrite name: myapp spec: selector: matchLabels: app.kubernetes.io/name: myapp-overwrite template: metadata: labels: app.kubernetes.io/name: myapp-overwrite spec: containers: - env: - name: KEY2 value: VALUE2-overwrite image: myapp:stable name: myapp - image: mysidecar:stable name: mysidecar
終わりに
本記事ではkustomizeでCustom Resourceを扱う方法を紹介しました。 本記事がkustomizeを使ってKubernetesを運用する方の役に立てば幸いです。
参考
- kustomizeでCRDのpatchesStrategicMergeを動かしてみる - 1クール続けるブログ
- kustomizeでCustomResourceにいい感じにStrategicMergePatchする / StrategicMergePatch to CustomResource with Kustomize - Speaker Deck
- Using a Custom OpenAPI schema
- Transformer Configurations
- KEP-2206: OpenAPI Features in Kustomize
- openapi | SIG CLI
- Kustomize - Argo Rollouts - Kubernetes Progressive Delivery Controller
- Issue with Deployment resource patching when Rollout resources openapi definition is included · Issue #4613 · kubernetes-sigs/kustomize
- Kustomize fail to merge
.spec.template.spec.containers[].env
fields · Issue #1730 · argoproj/argo-rollouts
私たちは同じチームで働いてくれる仲間を探しています。クラウドアーキテクトの業務に興味がある方のご応募をお待ちしています。
執筆:@shibata.takao、レビュー:@sato.taichi (Shodoで執筆されました)