K8s:通過 Kustomize 實(shí)現(xiàn)YAML資源文件組合與繼承
在使用 helm 的時(shí)候,有些 chart 包里面,小伙伴可能會(huì)發(fā)現(xiàn),好多資源對(duì)象是定義在一個(gè)文件里的,而且定義的順序是按照創(chuàng)建順序的,剛開始我一直以為是寫好之后又整合到一起的,但是后來遇到了 Kustomize,才發(fā)現(xiàn)可能并不是那樣。
Kustomize 通過 kustomization 文件 不但可以定制 Kubernetes 對(duì)象。還可以組合 多個(gè)資源對(duì)象為一個(gè) yaml 文件 ,實(shí)現(xiàn)資源對(duì)象 yaml 文件的簡單管理。
組合和繼承資源
一種常見的做法是在項(xiàng)目中構(gòu)造資源集合并將其放到同一個(gè)文件或目錄中管理。 Kustomize 提供基于不同配置文件來合并資源并向其應(yīng)用一些補(bǔ)丁或者其他定制的能力。
資源文件的組合
Kustomize 支持組合不同的資源。kustomization.yaml 文件的 resources 字段定義配置中要包含的資源列表。 你可以將 resources 列表中的路徑設(shè)置為資源配置文件的路徑。 下面是由 Deployment 和 Service 構(gòu)成的 NGINX 應(yīng)用的示例:
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$cat deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web-deploy
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx-web
ports:
- containerPort: 80
name: nginx-web
resources: {}
status: {}
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-svc
labels:
app: nginx-svc
spec:
ports:
- port: 30088
targetPort: 80
name: nginx-web
selector:
app: web
定義如下的 kustomization yaml 文件,即可以做到 deploy 和 svc 的 yaml 文件整合
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$cat kustomization.yaml
resources:
- deploy.yaml
- service.yaml
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$ls
deploy.yaml kustomization.yaml service.yaml
kubectl kustomize ./ 檢查生成的資源文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl kustomize ./
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-svc
name: web-svc
spec:
ports:
- name: nginx-web
port: 30088
targetPort: 80
selector:
app: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web-deploy
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx-web
ports:
- containerPort: 80
name: nginx-web
resources: {}
status: {}
如果希望直接應(yīng)用他們,可以實(shí)現(xiàn)下面的命令
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl apply -k ./
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl get svc web-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-svc ClusterIP 10.106.69.74 <none> 30088/TCP 25h
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl get deployments.apps web
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 25h
資源文件的繼承
補(bǔ)丁文件(Patches)可以用來對(duì)資源執(zhí)行不同的定制。用通俗的話講,即可以定義一些其他的文件(補(bǔ)丁文件),在繼承原來資源文件的基礎(chǔ)上,重寫原來的單一的資源文件中某些字段。類似于面向?qū)ο罄锩娴睦^承關(guān)系。
Kustomize 通過 patchesStrategicMerge 和 patchesJson6902 支持不同的打補(bǔ)丁機(jī)制(重寫)。
模板化重寫
patchesStrategicMerge 的內(nèi)容是一個(gè)文件路徑的列表,其中每個(gè)文件都應(yīng)可解析為 策略性合并補(bǔ)丁(Strategic Merge Patch)。 補(bǔ)丁文件中的名稱必須與已經(jīng)加載的資源的名稱匹配。 建議構(gòu)造規(guī)模較小的、僅做一件事情的補(bǔ)丁。
例如,構(gòu)造一個(gè)補(bǔ)丁來增加 Deployment 的副本個(gè)數(shù);構(gòu)造另外一個(gè)補(bǔ)丁來設(shè)置內(nèi)存限制。
原始文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$cat 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
重寫 Deployment 的副本個(gè)數(shù)
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$cat increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
重寫 pod 模板的內(nèi)存限制
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$cat set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$
kustomization 文件可以看做是描述繼承關(guān)系的文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$ls
deployment.yaml increase_replicas.yaml kustomization.yaml set_memory.yaml
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$cat kustomization.yaml
resources:
- deployment.yaml
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
生成的新的資源文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/patches]
└─$kubectl kustomize ./
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
局部值重寫
并非所有資源或者字段都支持策略性合并補(bǔ)丁。為了支持對(duì)任何資源的任何字段進(jìn)行修改, Kustomize 提供通過 patchesJson6902 來應(yīng)用 JSON 補(bǔ)丁的能力。 為了給 JSON 補(bǔ)丁找到正確的資源,需要在 kustomization.yaml 文件中指定資源的組(group)、 版本(version)、類別(kind)和名稱(name)。 例如,為某 Deployment 對(duì)象增加副本個(gè)數(shù)的操作也可以通過 patchesJson6902 來完成:
# 創(chuàng)建一個(gè) JSON 補(bǔ)丁文件
cat patch.yaml
- op: replace
path: /spec/replicas
value: 3
# 創(chuàng)建一個(gè) kustomization.yaml
cat ./kustomization.yaml
resources:
- deployment.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-nginx
path: patch.yaml
對(duì)象字段重寫
除了補(bǔ)丁之外,Kustomize 還提供定制容器鏡像或者將其他對(duì)象的字段值注入到容器中的能力,并且不需要?jiǎng)?chuàng)建補(bǔ)丁。 例如,你可以通過在 kustomization.yaml 文件的 images 字段設(shè)置新的鏡像來更改容器中使用的鏡像。
cat ./kustomization.yaml
resources:
- deployment.yaml
images:
- name: nginx
newName: my.image.registry/nginx
newTag: 1.4.0
組合中變量的使用
有些時(shí)候,Pod 中運(yùn)行的應(yīng)用可能需要使用來自其他對(duì)象的配置值。 例如,某 Deployment 對(duì)象的 Pod 需要從環(huán)境變量或命令行參數(shù)中讀取讀取 Service 的名稱。 由于在 kustomization.yaml 文件中添加 namePrefix 或 nameSuffix 時(shí) Service 名稱可能發(fā)生變化,建議不要在命令參數(shù)中硬編碼 Service 名稱。 對(duì)于這種使用場景,Kustomize 可以通過 vars 將 Service 名稱注入到容器中。
deployment 中使用了變量
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$cat 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)"]
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
kustomization.yaml 需要定義變量的來源。
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$ls
deployment.yaml kustomization.yaml service.yaml
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$cat kustomization.yaml
namePrefix: dev-
nameSuffix: "-001"
resources:
- deployment.yaml
- service.yaml
vars:
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-nginx
apiVersion: v1
查看組合后的變量情況
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$kubectl kustomize ./
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: dev-my-nginx-001
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
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
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/vars]
└─$
Bases 與 Overlays
Kustomize 中有 基準(zhǔn)(bases) 和 覆蓋(overlays) 的概念區(qū)分。 這里可以理解為目錄級(jí)別 yaml 資源文件的繼承?;鶞?zhǔn) 為父類目錄,覆蓋 為子類重寫目錄。
基準(zhǔn) 是包含 kustomization.yaml 文件的一個(gè)目錄,其中包含一組資源及其相關(guān)的定制。 基準(zhǔn)可以是本地目錄或者來自遠(yuǎn)程倉庫的目錄,只要其中存在 kustomization.yaml 文件即可。
覆蓋 也是一個(gè)目錄,其中包含將其他 kustomization 目錄當(dāng)做 bases 來引用的 kustomization.yaml 文件。 基準(zhǔn)不了解覆蓋的存在,且可被多個(gè)覆蓋所使用。 覆蓋則可以有多個(gè)基準(zhǔn),且可針對(duì)所有基準(zhǔn)中的資源執(zhí)行組織操作,還可以在其上執(zhí)行定制。
創(chuàng)建一個(gè) bases 目錄。里面存放基準(zhǔn) 的 yaml 文件
kustomization.yaml 文件定義
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/rebase]
└─$cat kustomization.yaml
resources:
- deployment.yaml
- service.yaml
合并后的基準(zhǔn)文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/rebase]
└─$kubectl kustomize ./
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
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: nginx
name: my-nginx
此基準(zhǔn)可在多個(gè)覆蓋中使用。你可以在不同的覆蓋中添加不同的 namePrefix 或其他通用字段。 下面是兩個(gè)使用同一基準(zhǔn)的覆蓋(具體的 Yaml 資源目錄繼承):
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/]
└─$mkdir dev
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/]
└─$mkdir prod
編寫繼承的 yaml 資源文件目錄的 kustomization.yaml 文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize]
└─$cat ./prod/kustomization.yaml
bases:
- ../rebase
namePrefix: prod-
namespace: liruilong-prod
┌──[root@vms81.liruilongs.github.io]-[~/kustomize]
└─$cat ./dev/kustomization.yaml
bases:
- ../rebase
namePrefix: dev-
namespace: liruilong-dev
查看覆蓋(繼承)后新的資源文件
┌──[root@vms81.liruilongs.github.io]-[~/kustomize]
└─$kubectl kustomize ./prod/
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: prod-my-nginx
namespace: liruilong-prod
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prod-my-nginx
namespace: liruilong-prod
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
┌──[root@vms81.liruilongs.github.io]-[~/kustomize]
└─$kubectl kustomize ./dev/
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: dev-my-nginx
namespace: liruilong-dev
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-my-nginx
namespace: liruilong-dev
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
┌──[root@vms81.liruilongs.github.io]-[~/kustomize]
└─$
如何使用 Kustomize 來應(yīng)用、查看和刪除對(duì)象
應(yīng)用對(duì)象
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl apply -k ./
service/web-svc created
deployment.apps/web created
查看對(duì)象
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl get -k ./
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/web-svc ClusterIP 10.100.206.11 <none> 30088/TCP 7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 1/3 3 1 7s
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl describe -k ./
Name: web-svc
Namespace: awx
Labels: app=nginx-svc
Annotations: <none>
Selector: app=web
Type: ClusterIP
。。。。。。
Name: web
Namespace: awx
CreationTimestamp: Sat, 24 Dec 2022 01:14:23 +0800
Labels: app=web-deploy
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=web
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
。。。。。
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl diff -k ./
刪除對(duì)象
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$kubectl delete -k ./
service "web-svc" deleted
deployment.apps "web" deleted
┌──[root@vms81.liruilongs.github.io]-[~/kustomize/merge]
└─$
博文參考
https://kubectl.docs.kubernetes.io/zh/installation/
https://github.com/kubernetes-sigs/kustomize
https://kubernetes.io/zh-cn/docs/tasks/manage-kubernetes-objects/kustomization/
qiabib
作者:山河已無恙
歡迎關(guān)注微信公眾號(hào) :山河已無恙