使用 Kustomize 宣告式管理 Kubernetes 物件
Kustomize 是一個獨立工具,用於透過 kustomization 檔案自訂 Kubernetes 物件。
從 1.14 版開始,Kubectl 也支援使用 kustomization 檔案管理 Kubernetes 物件。若要檢視包含 kustomization 檔案的目錄中找到的資源,請執行下列命令
kubectl kustomize <kustomization_directory>
若要套用這些資源,請執行 kubectl apply
並加上 --kustomize
或 -k
旗標
kubectl apply -k <kustomization_directory>
開始之前
安裝 kubectl
。
您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用這些 Kubernetes 實驗環境之一
若要檢查版本,請輸入kubectl version
。Kustomize 總覽
Kustomize 是一個用於自訂 Kubernetes 組態的工具。它具有以下功能來管理應用程式組態檔
- 從其他來源產生資源
- 為資源設定跨領域欄位
- 組合和自訂資源集合
產生資源
ConfigMaps 和 Secrets 保存組態或敏感資料,供其他 Kubernetes 物件(例如 Pod)使用。ConfigMaps 或 Secrets 的事實來源通常在叢集外部,例如 .properties
檔案或 SSH 金鑰檔。Kustomize 具有 secretGenerator
和 configMapGenerator
,可從檔案或文字產生 Secret 和 ConfigMap。
configMapGenerator
若要從檔案產生 ConfigMap,請在 configMapGenerator
中的 files
清單中新增一個項目。以下是從 .properties
檔案產生具有資料項目的 ConfigMap 的範例
# Create a application.properties file
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
可以使用以下命令檢查產生的 ConfigMap
kubectl kustomize ./
產生的 ConfigMap 為
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
若要從 env 檔案產生 ConfigMap,請在 configMapGenerator
中的 envs
清單中新增一個項目。以下是從 .env
檔案產生具有資料項目的 ConfigMap 的範例
# Create a .env file
cat <<EOF >.env
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
envs:
- .env
EOF
可以使用以下命令檢查產生的 ConfigMap
kubectl kustomize ./
產生的 ConfigMap 為
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-1-42cfbf598f
注意
.env
檔案中的每個變數都會成為您產生的 ConfigMap 中的個別金鑰。這與先前的範例不同,先前的範例將名為 application.properties
的檔案(及其所有項目)嵌入為單一金鑰的值。ConfigMaps 也可以從文字金鑰值對產生。若要從文字金鑰值對產生 ConfigMap,請在 configMapGenerator 中的 literals
清單中新增一個項目。以下是從金鑰值對產生具有資料項目的 ConfigMap 的範例
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
EOF
可以使用以下命令檢查產生的 ConfigMap
kubectl kustomize ./
產生的 ConfigMap 為
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
若要在 Deployment 中使用產生的 ConfigMap,請依 configMapGenerator 的名稱參考它。Kustomize 將自動將此名稱替換為產生的名稱。
這是使用產生 ConfigMap 的 Deployment 範例
# Create a application.properties file
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: example-configmap-1
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
產生 ConfigMap 和 Deployment
kubectl kustomize ./
產生的 Deployment 將依名稱參考產生的 ConfigMap
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-g4hk9g2ff8
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-app
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- image: my-app
name: app
volumeMounts:
- mountPath: /config
name: config
volumes:
- configMap:
name: example-configmap-1-g4hk9g2ff8
name: config
secretGenerator
您可以從檔案或文字金鑰值對產生 Secrets。若要從檔案產生 Secret,請在 secretGenerator
中的 files
清單中新增一個項目。以下是從檔案產生具有資料項目的 Secret 的範例
# Create a password.txt file
cat <<EOF >./password.txt
username=admin
password=secret
EOF
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
產生的 Secret 如下
apiVersion: v1
data:
password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==
kind: Secret
metadata:
name: example-secret-1-t2kt65hgtb
type: Opaque
若要從文字金鑰值對產生 Secret,請在 secretGenerator
中的 literals
清單中新增一個項目。以下是從金鑰值對產生具有資料項目的 Secret 的範例
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-2
literals:
- username=admin
- password=secret
EOF
產生的 Secret 如下
apiVersion: v1
data:
password: c2VjcmV0
username: YWRtaW4=
kind: Secret
metadata:
name: example-secret-2-t52t6g96d8
type: Opaque
與 ConfigMaps 類似,產生的 Secrets 可以透過參考 secretGenerator 的名稱在 Deployments 中使用
# Create a password.txt file
cat <<EOF >./password.txt
username=admin
password=secret
EOF
cat <<EOF >deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: password
mountPath: /secrets
volumes:
- name: password
secret:
secretName: example-secret-1
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
generatorOptions
產生的 ConfigMaps 和 Secrets 附加了內容雜湊後綴。這確保在內容變更時會產生新的 ConfigMap 或 Secret。若要停用附加後綴的行為,可以使用 generatorOptions
。除此之外,也可以為產生的 ConfigMaps 和 Secrets 指定跨領域選項。
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-3
literals:
- FOO=Bar
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
annotations:
note: generated
EOF
執行 kubectl kustomize ./
以檢視產生的 ConfigMap
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
annotations:
note: generated
labels:
type: generated
name: example-configmap-3
設定跨領域欄位
為專案中的所有 Kubernetes 資源設定跨領域欄位非常常見。設定跨領域欄位的一些使用案例
- 為所有資源設定相同的命名空間
- 新增相同名稱前綴或後綴
- 加入相同的標籤集
- 加入相同的註解集
這是一個範例
# Create a deployment.yaml
cat <<EOF >./deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
cat <<EOF >./kustomization.yaml
namespace: my-namespace
namePrefix: dev-
nameSuffix: "-001"
commonLabels:
app: bingo
commonAnnotations:
oncallPager: 800-555-1212
resources:
- deployment.yaml
EOF
執行 kubectl kustomize ./
以檢視這些欄位都已在 Deployment 資源中設定
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
name: dev-nginx-deployment-001
namespace: my-namespace
spec:
selector:
matchLabels:
app: bingo
template:
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
spec:
containers:
- image: nginx
name: nginx
組合與自訂資源
在專案中組合一組資源並在同一個檔案或目錄中管理它們是很常見的。Kustomize 提供了從不同檔案組合資源,並對它們應用修補程式或其他自訂設定。
組合
Kustomize 支援不同資源的組合。kustomization.yaml
檔案中的 resources
欄位,定義了要包含在組態中的資源列表。在 resources
列表中設定資源組態檔案的路徑。以下是一個由 Deployment 和 Service 組成的 NGINX 應用程式範例
# Create a deployment.yaml file
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Create a service.yaml file
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Create a kustomization.yaml composing them
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
來自 kubectl kustomize ./
的資源包含 Deployment 和 Service 物件。
自訂
修補程式可用於對資源應用不同的自訂設定。Kustomize 透過 patchesStrategicMerge
和 patchesJson6902
支援不同的修補機制。patchesStrategicMerge
是一個檔案路徑列表。每個檔案都應解析為策略性合併修補程式。修補程式內的名稱必須與已載入的資源名稱相符。建議使用只做一件事的小型修補程式。例如,建立一個修補程式來增加 deployment 副本數量,另一個修補程式用於設定記憶體限制。
# Create a deployment.yaml file
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Create a patch increase_replicas.yaml
cat <<EOF > increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
EOF
# Create another patch set_memory.yaml
cat <<EOF > set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
EOF
執行 kubectl kustomize ./
以檢視 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ports:
- containerPort: 80
resources:
limits:
memory: 512Mi
並非所有資源或欄位都支援策略性合併修補程式。為了支援修改任意資源中的任意欄位,Kustomize 提供透過 patchesJson6902
應用JSON 修補程式。為了找到 JSON 修補程式的正確資源,需要在 kustomization.yaml
中指定該資源的 group、version、kind 和 name。例如,增加 Deployment 物件的副本數量也可以透過 patchesJson6902
完成。
# Create a deployment.yaml file
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Create a json patch
cat <<EOF > patch.yaml
- op: replace
path: /spec/replicas
value: 3
EOF
# Create a kustomization.yaml
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-nginx
path: patch.yaml
EOF
執行 kubectl kustomize ./
以查看 replicas
欄位已更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ports:
- containerPort: 80
除了修補程式之外,Kustomize 還提供自訂容器映像檔,或將其他物件的欄位值注入到容器中,而無需建立修補程式。例如,您可以透過在 kustomization.yaml
中的 images
欄位中指定新的映像檔,來變更容器內使用的映像檔。
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
images:
- name: nginx
newName: my.image.registry/nginx
newTag: 1.4.0
EOF
執行 kubectl kustomize ./
以查看正在使用的映像檔已更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: my.image.registry/nginx:1.4.0
name: my-nginx
ports:
- containerPort: 80
有時,在 Pod 中運行的應用程式可能需要使用來自其他物件的組態值。例如,來自 Deployment 物件的 Pod 需要從 Env 或作為命令列引數讀取相應的 Service 名稱。由於 Service 名稱可能會隨著在 kustomization.yaml
檔案中加入 namePrefix
或 nameSuffix
而變更。不建議在命令列引數中硬式編碼 Service 名稱。對於這種用法,Kustomize 可以透過 vars
將 Service 名稱注入到容器中。
# Create a deployment.yaml file (quoting the here doc delimiter)
cat <<'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
command: ["start", "--host", "$(MY_SERVICE_NAME)"]
EOF
# Create a service.yaml file
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
cat <<EOF >./kustomization.yaml
namePrefix: dev-
nameSuffix: "-001"
resources:
- deployment.yaml
- service.yaml
vars:
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-nginx
apiVersion: v1
EOF
執行 kubectl kustomize ./
以查看注入到容器中的 Service 名稱是 dev-my-nginx-001
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-my-nginx-001
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- command:
- start
- --host
- dev-my-nginx-001
image: nginx
name: my-nginx
基礎與覆蓋
Kustomize 具有基礎 (bases) 和覆蓋 (overlays) 的概念。基礎是一個包含 kustomization.yaml
的目錄,其中包含一組資源和相關的自訂設定。基礎可以是本機目錄或來自遠端儲存庫的目錄,只要其中存在 kustomization.yaml
即可。覆蓋是一個包含 kustomization.yaml
的目錄,它將其他 kustomization 目錄稱為其 bases
。基礎不知道覆蓋的存在,並且可以在多個覆蓋中使用。一個覆蓋可以有多個基礎,它組合來自基礎的所有資源,並且還可以在其之上進行自訂。
這是一個基礎的範例
# Create a directory to hold the base
mkdir base
# Create a base/deployment.yaml
cat <<EOF > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
EOF
# Create a base/service.yaml file
cat <<EOF > base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Create a base/kustomization.yaml
cat <<EOF > base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
此基礎可以用於多個覆蓋。您可以在不同的覆蓋中加入不同的 namePrefix
或其他跨領域的欄位。以下是兩個使用相同基礎的覆蓋。
mkdir dev
cat <<EOF > dev/kustomization.yaml
resources:
- ../base
namePrefix: dev-
EOF
mkdir prod
cat <<EOF > prod/kustomization.yaml
resources:
- ../base
namePrefix: prod-
EOF
如何使用 Kustomize 應用/檢視/刪除物件
在 kubectl
命令中使用 --kustomize
或 -k
來識別由 kustomization.yaml
管理的資源。請注意,-k
應指向 kustomization 目錄,例如
kubectl apply -k <kustomization directory>/
給定以下 kustomization.yaml
,
# Create a deployment.yaml file
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Create a kustomization.yaml
cat <<EOF >./kustomization.yaml
namePrefix: dev-
commonLabels:
app: my-nginx
resources:
- deployment.yaml
EOF
執行以下命令以應用 Deployment 物件 dev-my-nginx
> kubectl apply -k ./
deployment.apps/dev-my-nginx created
執行以下其中一個命令以檢視 Deployment 物件 dev-my-nginx
kubectl get -k ./
kubectl describe -k ./
執行以下命令以比較 Deployment 物件 dev-my-nginx
與叢集在應用 manifest 後的狀態
kubectl diff -k ./
執行以下命令以刪除 Deployment 物件 dev-my-nginx
> kubectl delete -k ./
deployment.apps "dev-my-nginx" deleted
Kustomize 功能列表
欄位 | 類型 | 說明 |
---|---|---|
namespace | string | 將 namespace 新增至所有資源 |
namePrefix | string | 此欄位的值會預先添加到所有資源的名稱 |
nameSuffix | string | 此欄位的值會附加到所有資源的名稱 |
commonLabels | map[string]string | 要新增到所有資源和選擇器的標籤 |
commonAnnotations | map[string]string | 要新增到所有資源的註解 |
resources | []string | 此列表中的每個條目都必須解析為現有的資源組態檔案 |
configMapGenerator | []ConfigMapArgs | 此列表中的每個條目都會產生一個 ConfigMap |
secretGenerator | []SecretArgs | 此列表中的每個條目都會產生一個 Secret |
generatorOptions | GeneratorOptions | 修改所有 ConfigMap 和 Secret 產生器的行為 |
bases | []string | 此列表中的每個條目都應解析為包含 kustomization.yaml 檔案的目錄 |
patchesStrategicMerge | []string | 此列表中的每個條目都應解析為 Kubernetes 物件的策略性合併修補程式 |
patchesJson6902 | []Patch | 此列表中的每個條目都應解析為 Kubernetes 物件和 Json Patch |
vars | []Var | 每個條目都是為了從一個資源的欄位捕獲文字 |
images | []Image | 每個條目都是為了修改一個映像檔的名稱、標籤和/或摘要,而無需建立修補程式 |
configurations | []string | 此列表中的每個條目都應解析為包含 Kustomize 轉換器組態的檔案 |
crds | []string | 此列表中的每個條目都應解析為 Kubernetes 類型的 OpenAPI 定義檔案 |