k8s Kustomize 声明式管理应用
kustomize 介绍
Kustomize 是一个用来定制 Kubernetes 配置的工具。它提供以下功能特性来管理应用配置文件:
1. 从其他来源生成资源
2. 为资源设置贯穿性(Cross-Cutting)字段
3. 组织和定制资源集合
查看kustomize版本
# kubectl version --short --client
Client Version: v1.25.2
Kustomize Version: v4.5.7
kustomize 资源清单
bases <[]string> # 列表中每个条目都应能解析为一个包含 kustomization.yaml 文件的目录。该字段在 v2.1.0 中已弃用。
resources <[]string> # 待定制的原始资源配置文件列表,将由Kustomize按顺序处理
namespace <string> # 设定所有名称空间级别资源所属的目标名称空间
commonLabels <map[string]string> # 添加到所有资源的通用标签,包括Pod模板及相关的标签选择器
commonAnnotations <map[string]string> # 添加到所有资源的通用注解
configMapGenerator <[]ConfigMapGeneratorArgs> # ConfigMap资源生成器列表
- name <String> # ConfigMap资源的名称,会受到namePrefix和nameSuffix的影响
namespace <String> # 资源所在的名称空间,会覆盖Kustomize级别的名称空间设定
behavior <String> # 与上级同名资源的合并策略,可用取值为create/replace/merge
files <[]String> # 从指定的路径加载文件生成ConfigMap,要使用当前项目的相对路径
literals <[]String> # 从指定的key=value格式的直接值生成ConfigMap
env <String> # 从指定的环境变量文件中加载key=value格式的环境变量作为资源数据
secretGenerator <[]secretGeneratorArgs> # Secret资源生成器列表
- name <String> # Secret资源的名称,会受到namePrefix和nameSuffix的影响
namespace <String> # 资源所在的名称空间,会覆盖Kustomize级别的名称空间设定
behavior <String> # 与上级同名资源的合并策略,可用取值为create/replace/merge
files <[]String> # 从指定的路径加载文件生成Secret,加载起始于当前项目的相对路径
literals <[]String> # 从指定的key=value格式的直接值生成Secret
type <String> # Secret资源的类型,且kubernetes.io/tls有特殊的键名要求
generatorOptions <GeneratorOptions> # 当前kustomization.yaml中的ConfigMap和Secret生成器专用的选项
labels <map[String]String> # 为当前kustomization.yaml中所有生成的资源添加的标签
annotations <map[String]String> # 为生成的所有资源添加的注解
disableNameSuffixHash <Boolean> # 是否禁用hash名称后缀,默认为启用
namePrefix <string> # 统一给所有资源添加的名称前缀
nameSuffix <string> # 统一给所有资源添加的名称后缀
images <[]Image> # 将所有Pod模板中符合name字段条件的镜像文件修改为指定的镜像
- name <String> # 资源清单中原有的镜像名称,即待替换的镜像
nameName <String> # 要使用的新镜像名称
newTag <String> # 要使用的新镜像的标签
digest <String> # 要使用的新镜像的SHA256校验码
vars <[]Var> # 指定可替换Pod容器参数中变量的值或容器环境变量的值
- name <String> # 变量的名称,支持以$(name)格式进行引用
objref <String> # 包含了要引用的目标字段的对象的名称
fieldref <String> # 引用的字段名称,默认为metadata.name
patchesJson6902 <[]Json6902> # 由各待补对象及其补丁文件所组成的列表
path <String> # 补丁文件,不含有目标资源对象的信息,支持JSON或YAML格式
target <Target> # 待补资源对象
group <String> # 资源所属的群组
version <String> # API版本
kind <String> # 资源类型
name <String> # 资源对象的名称
namespace <string> # 资源对象所属的名称空间
patchesStrategicMerge <[]string> # 将补丁补到匹配的资源之上,匹配的方式是根据资源Group/Version/Kind + Name/Namespace判断
vars <[]Var> # 每个条目用来从某资源的字段来析取文字。该字段在 v5.0.0 中已弃用。
configurations <[]string> # 列表中每个条目都应能解析为一个包含 Kustomize 转换器配置 的文件
crds <[]string> # 列表中每个条目都应能够解析为 Kubernetes 类别的 OpenAPI 定义文件
replacements:
- source:
group: string
version: string
kind: string
name: string
namespace: string
fieldPath: string
options:
delimiter: string
index: int
create: bool
targets:
- select:
group: string
version: string
kind: string
name: string
namespace: string
reject:
- group: string
version: string
kind: string
name: string
namespace: string
fieldPaths:
- string
options:
delimiter: string
index: int
create: bool
kustomize 文件结构
base
~/someApp
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
overlay
~/someApp
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── development
│ ├── cpu_count.yaml
│ ├── kustomization.yaml
│ └── replica_count.yaml
└── production
├── cpu_count.yaml
├── kustomization.yaml
└── replica_count.yaml
kustomize 使用示例
使用kustomize 部署demoapp。
创建项目目录
# mkdir demoapp/{base,overlays} -pv
base 配置文件
base/depoly-demoapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demoapp
name: deployment-demoapp
spec:
replicas: 1
selector:
matchLabels:
app: demoapp
template:
metadata:
creationTimestamp: null
labels:
app: demoapp
spec:
containers:
- image: ikubernetes/demoapp:v1.0
name: demoapp
env:
- name: PORT
value: "8080"
base/service-demoapp.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: demoapp
name: svc-demoapp
spec:
ports:
- name: http-8080
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: demoapp
type: ClusterIP
base/ns-demoapp.yaml
apiVersion: v1
kind: Namespace
metadata:
name: demoapp
base/kustomization.yaml
namespace: demoapp
resources:
- depoly-demoapp.yaml
- service-demoapp.yaml
- ns-demoapp.yaml
查看生成的YAML文件内容
# kubectl kustomize base/
apiVersion: v1
kind: Namespace
metadata:
name: demoapp
---
apiVersion: v1
kind: Service
metadata:
labels:
app: demoapp
name: svc-demoapp
namespace: demoapp
spec:
ports:
- name: http-8080
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: demoapp
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demoapp
name: deployment-demoapp
namespace: demoapp
spec:
replicas: 1
selector:
matchLabels:
app: demoapp
template:
metadata:
creationTimestamp: null
labels:
app: demoapp
spec:
containers:
- env:
- name: PORT
value: "8080"
image: ikubernetes/demoapp:v1.0
name: demoapp
创建base资源
# kubectl apply -k base/
namespace/demoapp created
service/svc-demoapp created
deployment.apps/deployment-demoapp created
查看base svc资源
# kubectl get svc -n demoapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-demoapp ClusterIP 10.100.228.19 <none> 8080/TCP 65s
查看base pod资源
# kubectl get pod -n demoapp
NAME READY STATUS RESTARTS AGE
deployment-demoapp-69f6cf9477-588rt 1/1 Running 0 30s
删除base资源
# kubectl delete -k base/
namespace "demoapp" deleted
service "svc-demoapp" deleted
deployment.apps "deployment-demoapp" deleted
overlays配置文件
创建环境目录
# mkdir overlays/production
生成环境配置目录
overlays/production/application.properties
cat <<EOF > overlays/production/application.properties
FOO_File=Prod_Bar
EOF
overlays/production/.env
cat <<EOF > overlays/production.env
FOO_Env=Prod_Bar
EOF
overlays/production/password.txt
cat <<EOF >./password.txt
username=admin
password=secret
EOF
overlays/production/increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demoapp
spec:
replicas: 3
overlays/production/patch.yaml
- op: replace # 替换式补丁
path: /spec/ports/0/targetPort # .spec.ports[0].targetPort字段
value: 48080 # 将上面字段的值修改为此处指定的值
- op: add # 添加新的配置项
path: /spec/ports/1 # .spec.ports[1]列表项
value: # 添加的内容为以下几个字段
name: https
protocol: TCP
port: 443
targetPort: 48443
overlays/production/set_configmap.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demoapp
spec:
template:
spec:
containers:
- name: demoapp
volumeMounts:
- name: config
mountPath: /config
- name: password
mountPath: /secrets
volumes:
- name: config
configMap:
name: example-configmap-file
- name: password
secret:
secretName: example-secret-1
overlays/production/set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demoapp
spec:
template:
spec:
containers:
- name: demoapp
resources:
limits:
memory: 128Mi
overlays/production/set_env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demoapp
spec:
template:
spec:
containers:
- name: demoapp
env:
- name: DEMO_SERVICE_NAME
value: SERVICE_NAME
overlays/production/kustomization.yaml
namespace: demoapp
commonLabels:
app: prod-demoapp
commonAnnotations:
oncallPager: 800-555-1212
resources:
- ../../base
configMapGenerator:
- name: example-configmap-file
files:
- application.properties
- name: example-configmap-env
envs:
- .env
- name: example-configmap-literals
literals:
- FOO_literals=Bar
secretGenerator:
- name: example-secret-1
files:
- password.txt
- name: example-secret-2
literals:
- username=admin
- password=secret
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
annotations:
note: generated
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
- set_configmap.yaml
- set_env.yaml
patchesJson6902:
- target:
version: v1
kind: Service
name: svc-demoapp
path: patch.yaml
replacements:
- source:
kind: Service
name: svc-demoapp
targets:
- select:
kind: Deployment
name: deployment-demoapp
fieldPaths:
- spec.template.spec.containers.[name=demoapp].env.[name=DEMO_SERVICE_NAME].value
namePrefix: prod-
nameSuffix: "-001"
查看overlays/production YAML 文件
# kubectl kustomize production/
apiVersion: v1
kind: Namespace
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: prod-demoapp
name: demoapp
---
apiVersion: v1
data:
FOO_Env: Prod_Bar
kind: ConfigMap
metadata:
annotations:
note: generated
oncallPager: 800-555-1212
labels:
app: prod-demoapp
type: generated
name: prod-example-configmap-env-001
namespace: demoapp
---
apiVersion: v1
data:
application.properties: |
FOO_File=Prod_Bar
kind: ConfigMap
metadata:
annotations:
note: generated
oncallPager: 800-555-1212
labels:
app: prod-demoapp
type: generated
name: prod-example-configmap-file-001
namespace: demoapp
---
apiVersion: v1
data:
FOO_literals: Bar
kind: ConfigMap
metadata:
annotations:
note: generated
oncallPager: 800-555-1212
labels:
app: prod-demoapp
type: generated
name: prod-example-configmap-literals-001
namespace: demoapp
---
apiVersion: v1
data:
password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==
kind: Secret
metadata:
annotations:
note: generated
oncallPager: 800-555-1212
labels:
app: prod-demoapp
type: generated
name: prod-example-secret-1-001
namespace: demoapp
type: Opaque
---
apiVersion: v1
data:
password: c2VjcmV0
username: YWRtaW4=
kind: Secret
metadata:
annotations:
note: generated
oncallPager: 800-555-1212
labels:
app: prod-demoapp
type: generated
name: prod-example-secret-2-001
namespace: demoapp
type: Opaque
---
apiVersion: v1
kind: Service
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: prod-demoapp
name: prod-svc-demoapp-001
namespace: demoapp
spec:
ports:
- name: http-8080
port: 8080
protocol: TCP
targetPort: 48080
- name: https
port: 443
protocol: TCP
targetPort: 48443
selector:
app: prod-demoapp
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: prod-demoapp
name: prod-deployment-demoapp-001
namespace: demoapp
spec:
replicas: 3
selector:
matchLabels:
app: prod-demoapp
template:
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: prod-demoapp
spec:
containers:
- env:
- name: DEMO_SERVICE_NAME
value: prod-svc-demoapp-001
- name: PORT
value: "8080"
image: ikubernetes/demoapp:v1.0
name: demoapp
resources:
limits:
memory: 128Mi
volumeMounts:
- mountPath: /config
name: config
- mountPath: /secrets
name: password
volumes:
- configMap:
name: prod-example-configmap-file-001
name: config
- name: password
secret:
secretName: prod-example-secret-1-001
创建 overlays/production 资源
# kubectl apply -k production/
namespace/demoapp created
configmap/prod-example-configmap-env-001 created
configmap/prod-example-configmap-file-001 created
configmap/prod-example-configmap-literals-001 created
secret/prod-example-secret-1-001 created
secret/prod-example-secret-2-001 created
service/prod-svc-demoapp-001 created
deployment.apps/prod-deployment-demoapp-001 created
创建 overlays/production pod 资源
# kubectl get pod -n demoapp
NAME READY STATUS RESTARTS AGE
prod-deployment-demoapp-001-545cfd57b8-82dq7 1/1 Running 0 52s
prod-deployment-demoapp-001-545cfd57b8-b7kd2 1/1 Running 0 52s
prod-deployment-demoapp-001-545cfd57b8-dxksg 1/1 Running 0 52s
删除 overlays/production 资源
# kubectl delete -k production/
namespace "demoapp" deleted
configmap "prod-example-configmap-env-001" deleted
configmap "prod-example-configmap-file-001" deleted
configmap "prod-example-configmap-literals-001" deleted
secret "prod-example-secret-1-001" deleted
secret "prod-example-secret-2-001" deleted
service "prod-svc-demoapp-001" deleted
deployment.apps "prod-deployment-demoapp-001" deleted
参考文档
https://github.com/kubernetes-sigs/kustomize