跳至主要内容

Advanced - Kustomize

什麼是 Kustomize

Kustomize 是 Kubernetes 原生的資源配置管理工具,從 Kubernetes 1.14 開始,已內建於 kubectl 命令行工具中。 它允許使用者透過非侵入式的方式對 YAML 配置進行覆寫和自訂,特別適合管理不同環境(如開發、測試、正式環境)的資源配置。


主要特點

  1. 基於 YAML 文件的無侵入性覆寫
    • 不需要直接修改原始的 YAML 文件,可以在外層疊加配置來進行自訂。
  2. 支持多層次的資源定義
    • 透過基礎資源(Base)和覆寫層(Overlay)的方式,方便管理不同環境的配置。
  3. 資源去重與整合
    • 自動處理多個配置文件中的資源合併,避免重複定義。
  4. 靈活的變數注入與命名空間管理
    • 支持透過變數(Variables)與 ConfigMap/Secret 自動注入配置,並簡化命名空間的管理。

實戰 Kustomize

基本指令

  1. 輸出 kustomize 結果:kubectl.exe kustomize <kustomization_dir>
  2. 查看 kustomize 結果與線上差異:kubectl.exe diff -k <kustomization_dir>
  3. 執行 kustomize 產生的結果:kubectl.exe apply -k <kustomization_dir>
  4. 刪除 kustomize 產生的資源:kubectl.exe delete -k <kustomization_dir>

建立 base 的 kustomization 模板

  1. 首先我們看資料夾的結構,會有一個 base 儲存基本的設定檔,這些設定檔基本上儲存不變的地方,以及確定要改的地方
tree /f
---

├─base
│ deployment.yaml
│ kustomization.yaml
│ service.yaml

└─overlays
├─development
│ kustomization.yaml

└─production
kustomization.yaml
  1. 首先我們先來完成 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
  1. 接下來我們撰寫 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
  1. 接下來我們可以用 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

  1. 假設我們目前有development環境和production環境,因此我們需要寫兩個 kustomization 來設定他們
└─overlays
├─development
│ kustomization.yaml

└─production
kustomization.yaml
  1. 首先我們來看 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 # 目標資源的名稱
  1. 接下來我們看 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
  1. 從這些 kustomization 我們可以觀察到,他們具有高度的內聚,而且低度的耦合,只需要將變數抽取出來單獨替換即可