Ingressの定義をkustomizeで作成するときの注意
こんにちは。インフラエンジニアの北野です。
kustomizeを使用する機会がありましたので、そこで得た知見を紹介したいと思います。
kustomizeを使ってIngressのマニフェストを管理しようとしたのですが、[patchesStrategicMerge:]では定義を想定通り生成できない事態に陥ったので、原因と対応方法について紹介します。
patchesStrategicMergeでの上書きは定義が消える
kustomizeでは、kubernetesと同じjson形式で記述できるpatchesStrategicMergeを使用することを基本的には推奨しますが、patchesStrategicMergeでは、Ingressの定義を想定通り生成できません。
何故なら、Ingressの定義のspec.rulesは配列の構造体となっており、一意となる名前も存在しないからです。そのため、spec.rules内のパラメータを環境固有の設定としてoverlaysのマニフェストファイルに書くことが出来ないからです。
一体どういうことかというと、例えば以下の定義を生成したいとします。
// 生成したい定義
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: portal.dev.com
http:
paths:
- path: /portal-nginx/example/
pathType: Prefix
backend:
service:
name: portal-nginx
port:
number: 80
この定義の中で、環境毎に差異の生じる箇所が[host:]だけだとすると、 baseのマニフェストとoverlaysのマニフェストは以下のように作りたくなります。
// 作成したくなるbase側のyaml(hostを定義しない)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- http:
paths:
- path: /portal-nginx/example/
pathType: Prefix
backend:
service:
name: portal-nginx
port:
number: 80
// 作成したくなるoverlays側のyaml(hostだけ定義する)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: portal.dev.com
しかし、[patchesStrategicMerge:]でoverlays側のyamlを定義したとき、buildすると、以下のような[http:]が削除された結果となってしまいます。
// 生成されてしまう定義(hostだけしか定義が存在しない)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: portal.dev.com
このように、[patchesStrategicMerge:]だと、base側のspec.rulesを丸々overlays側のspec.rulesが上書きしてしまいます。spec.rulesは配列の構造体となっており、一意となる名前も存在しない為です。
patchesJson6902で値を置換して解決
対応方法は色々とあるのですが、[patchesJson6902:]で対応する方法が最もシンプルかと考えているので、紹介します。
準備するディレクトリ構成とファイルは以下となります。
base
│ └─portal
│ ├─kustomization.yaml
│ └─ingress.yaml
overlays
└─prod
└─portal
├─kustomization.yaml
└─ingress-patch.yaml
4つのファイルの記述例を順に挙げていきます。
base側のkustomization.yaml
// ./base/portal/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ingress.yaml
全環境共通の設定
[host:]の要素を値は空で記述しておきます。
// ./base/portal/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host:
http:
paths:
- path: /portal-nginx/example/
pathType: Prefix
backend:
service:
name: portal-nginx
port:
number: 80
overlays側のkustomizaion.yaml
[patchesJson6902:]を記述し、[target:]に更新対象を特定するための情報と、 [path:]に更新情報のファイル名を記述します。
// ./overlays/prod/portal/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../../base/portal
patchesJson6902:
- target:
group: networking.k8s.io
version: v1
kind: Ingress
name: example-ingress
path: ingress-patch.yaml
環境固有の設定
[op:]には更新の挙動、[path:]には更新する場所を、[value:]には置換後の値を記述します。
// ./overlays/prod/portal/ingress-patch.yaml
- op: replace
path: /spec/rules/0/host
value: portal.dev.com
build結果
試しにbuildしたところ、無事に固有であるhostと共通のhost以外の定義も存在している設定を生成できました。
# kubectl kustomize ./overlays/prod/portal/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: portal.dev.com
http:
paths:
- backend:
service:
name: portal-nginx
number: 80
port: null
path: /portal-nginx/example/
pathType: Prefix
#
まとめ
kustomizeは便利ですが、全ての定義パターンを[patchesStrategicMerge:]で表現できません。
しかし、[patchesJson6902:]のような拡張機能を使えば、柔軟に定義を生成できます。 Ingressの定義をkustomize管理したいかたは、同じ問題に遭遇すると思うので、解決法としてお試しください。
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/