文件参考来源: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
今天要来介绍 k8s 中用来做资源管理的工具 kustomize
kustomize 是一个 standalone 的工具透过 kustomization file 来管理 k8s 物件
在 k8s 中可以透过以下指令来查看资料夹中包含的 kustomization file
kubectl kustomize $kustomization_directory
要布署这些资源要使用以下指令:
kubectl apply -k $kustomization_directory
Kustomize 是一个用来客制化 k8s 设定档的工具, 具有以下特性可以管理设定档:
ConfigMap 跟 Secret 具有其他 k8s 物件比如说 Pod 的设定档跟机敏资料
而这些设定档跟机敏资料来源通常是来自 k8s 丛集之外, 比如说 .properties 或是 SSH keyfile
Kustomize 有 secretGenerator 与 configMapGenerator 可以从外部档案产生 Secret 与 ConfigMap
来源档案 application.properties 如下:
FOO=Bar
则可以透过设定 kustomization.yaml 如下
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出以下 ConfigMap :
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
来源档案 .env 如下
FOO=Bar
则可以设定 kustomization.yaml 如下:
configMapGenerator:
- name: example-configmap-1
envs:
- .env
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出以下 ConfigMap :
apiVersion: v1
data:
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
要注意的是 每个 .env 的设定值在产生出来的 ConfigMap 都是原本的 key-value 形式保存, 而 .properties 的所有内容则是都被当成 value
另外也有一种 literal 的作法
直接设定 kustomization.yaml 如下:
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出以下 ConfigMap:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
上面由於是用 generator 产生出来的 configMap 所以名称都带有 hash
这边的 hash 值都是随意给的, 所以实际在机器上跑出来的应该不会根本文一样
下面给一个实际的范例
给一个设定档案 application.properties 如下:
FOO=BAR
给一设定档 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
就可以透过写一个 kustomization.yaml 如下:
resources:
- deployment.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
然後在同一个资料夹执行以下指令
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
给定一个设定档 password.txt 如下:
username=admin
password=secret
写一个设定档 kustomization.yaml 如下:
secretGenerator:
- name: example-secret-1
files:
- password.txt
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出以下 Secret:
apiVersion: v1
data:
password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==
kind: Secret
metadata:
name: example-secret-1-t2kt65hgtb
type: Opaque
另外也可以使用 literals 来建制 Secrets
建制 kustomization.yaml 如下
secretGenerator:
- name: examples-secret-2
literals:
- username=admin
- password=secret
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出以下 Secret:
apiVersion: v1
data:
password: c2VjcmV0
username: YWRtaW4=
kind: Secret
metadata:
name: example-secret-2-t52t6g96d8
type: Opaque
下面给一个实际的范例
给定设定档 password.txt 如下:
username=admin
password=secret
而设定档 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
就可以透过以下设定档 kustomization.yaml
resources:
- deployment.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
把 password.txt 跟 deployment.yaml 给结合在一起
另外对於 generator 其实有一些选项可以设定
比如说不想要档案产生出来名称有 hash 就可以设定 disableNameSuffixHash: true 如下
configMapGenerator:
- name: example-configmap-3
literals:
- FOO=Bar
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
annotations:
note: generated
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出来 ConfigMap 的 name 不会有 hash 如下
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
annotations:
note: generated
labels:
type: generated
name: example-configmap-3
所谓的 cross-cutting field 指的是有一些共通栏位会出现各种设定档之内
比如说 namespace, name prefix 或 suffix 或是 labels 或是 annotations
假设有一个设定档 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
就可以透过设定 kustomization.yaml 如下
namespace: my-namespace
namePrefix: dev-
nameSuffix: "-001"
commonLabels:
app: bingo
commonAnnotations:
oncallPager: 800-555-1212
resources:
- deployment.yaml
然後在同一个资料夹执行以下指令
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 可以针对 Deployment 做一些附加属性, 让布署增加弹性
可以透过 kustomizae 来组合同一个资料夹下的布署资源
或是把其他资源附加到目前的资源内
以下是透过 kustomize 组合同一个资料夹下的 Deployment 跟 Service
建立一个 nginx 的 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
建立一个 nginx 的 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 来把上面两个资源组合在一起如下:
resources:
- deployment.yaml
- service.yaml
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出来的布署档包含 Service, Deployment
Kustomize 可以让设定档切分成多个 patch 档, 在发布时组合所有 patch 成为一个发布档
patch 档合成的机制分为 patchesStrategicMerge 与 patchesJson6902
这种模式写法就是一堆档案的路径
而每个 patch 档案需要符合 strategic merge patch
范例如下:
设定档 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
建立 increase_replicas.yaml 来增加 replicas
increase_replicas.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
建立 set_memory.yaml 来设定 memroy limit
set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
建立 kustomization.ymal 如下
resources:
- deployment.yaml
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
然後在同一个资料夹执行以下指令
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
因为不是所有 Resource 栏位都能支援 strategic merge patches
所以 Kustomize 提供 patchesJson6902 来支援 JSON patch
范例如下:
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
建立一个 json patch 的设定档 patch.yaml 如下:
- op: replace
path: /spec/replicas
value: 3
设定 kustomization.yaml 如下:
resources:
- deployment.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-nginx
path: patch.yaml
然後在同一个资料夹执行以下指令
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
在 kustomization.yaml 可以指定 images 来替换原本 Deployment 内部的 images
假设 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
建立 kustomization.yaml 如下:
resources:
- deployment.yaml
images:
- name: nginx
newName: my.image.registry/nginx
newTag: 1.4.0
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出来的 Deployment 就会如下
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
有时候为了让 Deployment 更有弹性
所会在 Deployment 引入变数
也可以在 Kustomize 设定变数值做变数替换
范例如下:
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)"]
service.yaml 如下:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
建立一个 ksutomization.yaml 如下:
namePrefix: dev-
nameSuffix: "-001"
resources:
- deployment.yaml
- service.yaml
vars:
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-nginx
apiVersion: v1
然後在同一个资料夹执行以下指令
kubectl kustomize ./
产生出来的 Deployment 就会如下
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
command 的变数被 kustomization.yaml 的设定所替换了
Kustomize 具有 base 跟 overlay 的概念
base 就是指在一个资料夹具有一个 kustomization.yaml 档案包含所有布署设定
overlay 指指在一个资料夹具有一个 kustomization.yaml 档案把 base 参考到其他具有 kustomization.yaml 的路径
base 可以被其他 overlay 引用
overlay 可以具有多个 base
base 范例如下
假设在资料夹 base
建立一个 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
建立 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
建立 base/kustomization.yaml 如下:
resources:
- deployment.yaml
- service.yaml
而 overlay 范例则如下
建立一个 dev 资料夹
mkdir dev
建立一个 dev/kustomization.yaml 如下
bases:
- ../base
namePrefix: dev-
建立一个 prod 资料夹
mkdir prod
建立一个 prod/kustomization.yaml 如下
bases:
- ../base
namePrefix: prod-
上面两个 overlay 都引用了 base , 并且加入 namePrefix
以下指令用来布署
kubectl apply -k $kustomization_dir/
范例如下:
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
建立 kustomization.yaml 如下:
namePrefix: dev-
commonLabels:
app: my-nginx
resources:
- deployment.yaml
在同一个资料夹使用以下指令做布署
kubectl apply -k ./
查看布署可以使用以下两个指令
kubectl get -k ./
kubectl describe -k ./
比较 k8s 物件状态与布署差别可以用以下指令
kubectl diff -k ./
删除布署
kubectl delete -k ./
在布署 k8s 中会产生许多的设定档
这时候管理设定档就是一个很重要的事情
这时如果能透过一些工具来做不同环境的设定切割就会是很方便的事情
比如这个章节所提到的 kustomize
<<: JavaScript学习日记 : Day24 - Map
在前面章节已介绍如何让Arduino Nano 33 BLE Sense(以下简称BLE Sense...
tags: 2021铁人赛 React 还记得这个网站有筛选图表的功能吗?当初画wireframe的...
在 AppFollow 上查目标市场的 auto suggestion 找在一些大关键字中排名比较...
一. decoder 架构如下: decoder主要是解析encoder的资讯,转换成output的...
GraphInstagramService: interface GraphInstagramSer...