はじめに
kustomize、便利ですよね。
複数環境でkubernetesを運用するとき、共通化などによりマニフェスト管理負荷を下げる目的に、利用している現場が多いかと思います。
kustomizeは直感的に使えて便利な反面、なんとなくで使えてしまうので、
この記事では名前空間を環境別で分けたい時に、地味にぶつかりそうなエラーとその解決策を書いてみました。
実行環境
$ kustomize version
v5.4.2
本題
例示
例を挙げて考えてみます。
簡単に、以下のようなディレクトリ構成とします。(今回はdev環境のみ考慮)
baseではdefault名前空間
にdeploymentを定義しつつも、dev環境ではdev名前空間
にdeploymentをデプロイしたいケースを想定します。
(今回はついでにcpuのresource requestも書き換えます)
base
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
cpu: "500m"
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
overlays
resources:
- ../../base
- ./namespace-dev.yaml
patches:
- path: deployment-patch.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
overlaysのdeployment-patch.yamlは後述。
NG例
patchesで名前空間も書き換えようと思い、deployment-patch.yamlを以下のように書くとエラーが出てビルドできません。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
cpu: "250m"
↓エラーメッセージ
kustomize build overlays/dev Error: no resource matches strategic merge patch "Deployment.v1.apps/nginx-deployment.dev": no matches for Id Deployment.v1.apps/nginx-deployment.dev; failed to find unique target for patch Deployment.v1.apps/nginx-deployment.dev
つまりkustomizeは dev名前空間
にあるnginx-deploymentリソースをパッチ対象と認識しますが、baseではnginx-deploymentをdefault名前空間
で定義しているので、パッチ(書き換え)対象リソースが無いという理由でエラーになっています。
OK例
patchesで名前空間を書き換えるのではなく、kustomization.yaml自体でnamespaceを指定することで解決できます。
kustomization.yamlでnamespaceを書くことで、その配下の全リソースがそのnamespaceで作成されることになります。
namespace: dev # これを追記
resources:
- ../../base
- ./namespace-dev.yaml
patches:
- path: deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
# namespace: dev # こっちのnamespaceは削除
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
cpu: "250m"
patch側のnamespaceの記述は必ず削除する必要があります。
そうしないと、依然として前述のエラーが発生します。
上記により、無事にビルド・デプロイできるようになりました。
$ kustomize build overlays/dev
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 250m
$ kubectl apply -k overlays/dev
namespace/dev created
deployment.apps/nginx-deployment created
さいごに
kustomization.yamlのnamespaceオプションの存在を知っていればこのエラーは回避できますが、patchesが便利なため名前空間も無理やり書き換えようとしてハマるパターンが多そうなので書いてみました。(実際に自分もハマりましたw)
個人的は、この一件でなんとなくkustomizeを使っていたのが露呈してしまったので、これを機にkustomizeを体系的に勉強しようと思いました。