Advanced - Kustomize
什麼是 Kustomize
Kustomize 是 Kubernetes 原生的資源配置管理工具,從 Kubernetes 1.14 開始,已內建於 kubectl 命令行工具中。
它允許使用者透過非侵入式的方式對 YAML 配置進行覆寫和自訂,特別適合管理不同環境(如開發、測試、正式環境)的資源配置。
主要特點
- 基於 YAML 文件的無侵入性覆寫
- 不需要直接修改原始的 YAML 文件,可以在外層疊加配置來進行自訂。
- 支持多層次的資源定義
- 透過基礎資源(Base)和覆寫層(Overlay)的方式,方便管理不同環境的配置。
- 資源去重與整合
- 自動處理多個配置文件中的資源合併,避免重複定義。
- 靈活的變數注入與命名空間管理
- 支持透過變數(Variables)與 ConfigMap/Secret 自動注入配置,並簡化命名空間的管理。
實戰 Kustomize
基本指令
- 輸出 kustomize 結果:
kubectl.exe kustomize <kustomization_dir> - 查看 kustomize 結果與線上差異:
kubectl.exe diff -k <kustomization_dir> - 執行 kustomize 產生的結果:
kubectl.exe apply -k <kustomization_dir> - 刪除 kustomize 產生的資源:
kubectl.exe delete -k <kustomization_dir>
建立 base 的 kustomization 模板
- 首先我們看資料夾的結構,會有一個 base 儲存基本的設定檔,這些設定檔基本上儲存不變的地方,以及確定要改的地方
tree /f
---
├─base
│ deployment.yaml
│ kustomization.yaml
│ service.yaml
│
└─overlays
├─development
│ kustomization.yaml
│
└─production
kustomization.yaml
- 首先我們先來完成 deployment.yaml 和 service.yaml,首先 image 的地方改成 hello-world:tag ,抽象出來方便後續不同環境可以執行
base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
labels:
type: demo
spec:
replicas: 2
selector:
matchLabels:
type: demo
template:
metadata:
labels:
type: demo
spec:
containers:
- name: demo-container
image: hello-world:tag
ports:
- containerPort: 8080
base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: service
spec:
selector:
type: demo
ports:
- protocol: TCP
port: 8000
targetPort: 8080
type: LoadBalancer
- 接下來我們撰寫 kustomization.yaml,他可以設定標籤、註解,並且要修改的地方,然後還有引用其他的 yaml
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 給所有資源名稱添加前綴,方便區分不同版本的資源
namePrefix: v1-
# 給所有資源統一添加標籤,便於篩選和管理
commonLabels:
by: kustomization # 表示這些資源是通過 Kustomize 管理的
# 給所有資源統一添加註解,作為描述或備註信息
commonAnnotations:
note: Hello, I'm bar # 自定義的註解內容,可用於說明用途
images:
- name: hello-world:tag # 指定要更新的映像名稱
newTag: v1.0.0 # 將映像版本更新為 v1.0.0
# 引用其他 YAML 文件作為資源
resources:
- deployment.yaml
- service.yaml
- 接下來我們可以用 kustomize 來將抽象的設定檔生成設定檔,用來執行
kubectl.exe kustomize base
運行結果
apiVersion: v1
kind: Service
metadata:
annotations:
note: Hello, I'm bar
labels:
by: kustomization
name: v1-service
spec:
ports:
- port: 8000
protocol: TCP
targetPort: 8080
selector:
by: kustomization
type: demo
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
note: Hello, I'm bar
labels:
by: kustomization
type: demo
name: v1-deployment
spec:
replicas: 2
selector:
matchLabels:
by: kustomization
type: demo
template:
metadata:
annotations:
note: Hello, I'm bar
labels:
by: kustomization
type: demo
spec:
containers:
- image: hello-world:v1.0.0
name: demo-container
ports:
- containerPort: 8080
Overlay Kustomization
- 假設我們目前有development環境和production環境,因此我們需要寫兩個 kustomization 來設定他們
└─overlays
├─development
│ kustomization.yaml
│
└─production
kustomization.yaml
- 首先我們來看 development 的 kustomization,我們可以將資源或空間命名增加前綴,方便管理資源,同時我們可以使用 Json Patch,替換原本 yaml 裡面的東西,yaml 的階層加上/就等於 path,也能指定要作用的 target 範圍
overlays/development/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 引用基礎配置
resources:
- ../../base
# 給所有資源名稱添加前綴,標識環境為 "dev"
namePrefix: dev-
# 指定資源的 命名空間,所有資源都會被放置在 "dev-namespace" 中
namespace: dev-namespace
commonLabels:
by: dev-demo
app: dev-foo
commonAnnotations:
note: Hello, I'm development!
images:
- name: hello-world:tag
newTag: v1.0.0
# 使用 JSON Patch 格式來修改目標資源
patches:
- patch: |
- op: replace
path: /metadata/name
value: the-dev-development
- op: replace
path: /spec/template/spec/containers/0/name
value: the-dev-container
target: # 指定補丁的目標資源
group: apps # 資源所屬的 API 組
kind: Deployment # 資源類型為 Deployment
version: v1 # 資源的 API 版本
name: foo-deployment-v1 # 目標資源的名稱
- 接下來我們看 production 的 kustomization,我們可以一樣在資源前綴增加 prod 方便管理資源,另外也能使用不同的 image 和 label 來標示他們
overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: prod-
namespace: production-namespace
commonLabels:
by: prod-demo
app: pord-foo
commonAnnotations:
note: Hello, I'm Production!
images:
- name: hello-world:tag
newTag: v2.0.0
patches:
- patch: |
- op: replace
path: /metadata/name
value: the-prod-development
- op: replace
path: /spec/template/spec/containers/0/name
value: the-prod-container
target:
group: apps
kind: Deployment
version: v1
name: foo-deployment-v1
- 從這些 kustomization 我們可以觀察到,他們具有高度的內聚,而且低度的耦合,只需要將變數抽取出來單獨替換即可