k8s Kustomize
k8s Kustomize
Kustomize是一个通过kustomization 文件自定义 Kubernetes 对象的独立工具
从 1.14 开始,Kubectl 还支持使用 kustomization 文件管理 Kubernetes 对象:
1.1 语法
//语法
kubectl kustomize <kustomization_directory>
//要应用这些资源,请运行kubectl apply或--kustomize标记-k:
kubectl apply -k <kustomization_directory>
2.1 Kustomize 概述
Kustomize 是用于自定义 Kubernetes 配置的工具。它具有以下功能来管理应用程序配置文件:
- 从其他来源生成资源
- 为资源设置横切领域
- 编写和自定义资源集合
2.1.1 生成资源
ConfigMap 和 Secret 保存其他 Kubernetes 对象(例如 Pod)使用的配置或敏感数据,ConfigMap 或 Secret 的真实来源通常位于集群外部,例如.properties文件或 SSH 密钥文件。Kustomize 有secretGeneratorand configMapGenerator,它们从文件或文字生成 Secret 和 ConfigMap。
2.1.1.1 configMapGenerator
要从文件生成 ConfigMap,请将条目添加files到configMapGenerator. 以下是使用文件中的数据项生成 ConfigMap 的示例.properties:
//生成要加密的文件
cat <<EOF >application.properties
FOO=Bar
EOF
//生成kustomization文件
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
//检查生成的 ConfigMap,注意,这里只会打印,不会直接创建
kubectl kustomize ./
//直接生成ConfigMap
kubectl apply -k ./
//生成的 ConfigMap 为
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
要从 env 文件生成 ConfigMap,请将条目添加envs到configMapGenerator. 以下是使用文件中的数据项生成 ConfigMap 的示例.env:
//创建env文件
cat <<EOF >.env
FOO=Bar
EOF
//创建kustomization文件
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
envs:
- .env
EOF
//检查生成的 ConfigMap,注意,这里只会打印,不会直接创建,注意,如果版本过低会报错,我用的1.15报错了,1.24.1没问题
kubectl kustomize ./
//直接生成ConfigMap
kubectl apply -k ./
//生成的 ConfigMap 为:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-1-42cfbf598f
//注意:文件中的每个变量都会.env成为您生成的 ConfigMap 中的一个单独的键。这与前面的示例不同,它嵌入了一个名为.properties(及其所有条目)的文件作为单个键的值
ConfigMap 也可以从文字键值对生成。要从文字键值对生成 ConfigMap,请literals在 configMapGenerator 的列表中添加一个条目。以下是使用键值对中的数据项生成 ConfigMap 的示例:
///创建kustomization文件
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
EOF
//检查生成的 ConfigMap:
kubectl kustomize ./
//生成ConfigMap
kubectl kustomize -k ./
//生成的 ConfigMap 为:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
//要在部署中使用生成的 ConfigMap,请通过 configMapGenerator 的名称引用它。Kustomize 将自动将此名称替换为生成的名称
这是一个使用生成的 ConfigMap 的示例部署:
//创建配置文件
cat <<EOF >application.properties
FOO=Bar
EOF
//创建deployment文件
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
//生成kustomization文件
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
//生成 ConfigMap 和部署
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
2.1.1.2 secretGeneratorand
您可以从文件或文字键值对生成 Secret。要从文件生成 Secret,请将条目添加files到secretGenerator. 以下是使用文件中的数据项生成 Secret 的示例:
//生成密码文件
cat <<EOF >./password.txt
username=admin
password=secret
EOF
//生成kustomization文件
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,请在literals列表中添加一个条目secretGenerator。以下是使用键值对中的数据项生成 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 中使用:
//生成账号密码文件
cat <<EOF >./password.txt
username=admin
password=secret
EOF
//生成deployment文件
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
//生成kustomization文件
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
2.1.1.3 生成器选项
生成的 ConfigMap 和 Secret 附加了内容哈希后缀。这样可以确保在内容更改时生成新的 ConfigMap 或 Secret。要禁用附加后缀的行为,可以使用generatorOptions. 除此之外,还可以为生成的 ConfigMap 和 Secret 指定横切选项。
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
2.1.2 设置横切字段
为项目中的所有 Kubernetes 资源设置横切字段是很常见的。设置横切字段的一些用例
- 为所有资源设置相同的命名空间
- 添加同名前缀或后缀
- 添加相同的标签集
- 添加相同的注释集
例子
//生成deployment文件
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
//生成kustomization文件
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 Resource中设置的
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
2.1.3 编写和自定义资源
在一个项目中组成一组资源并在同一个文件或目录中管理它们是很常见的。Kustomize 提供组合来自不同文件的资源并对其应用补丁或其他自定义
Kustomize 支持不同资源的组合。文件中的resources字段kustomization.yaml定义要包含在配置中的资源列表。在列表中设置资源配置文件的路径resources。这是一个由部署和服务组成的 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
补丁可用于对资源应用不同的自定义。Kustomize 通过patchesStrategicMerge和支持不同的修补机制patchesJson6902。patchesStrategicMerge是文件路径的列表。每个文件都应该被解析为一个战略合并补丁。补丁中的名称必须与已加载的资源名称匹配。推荐做一件事的小补丁。例如,创建一个用于增加部署副本数的补丁和另一个用于设置内存限制的补丁。
# 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 ./查看部署
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 补丁找到正确的资源,该资源的组、版本、种类和名称需要在kustomization.yaml. 例如,增加一个 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 还提供自定义容器图像或将其他对象的字段值注入容器而无需创建补丁。例如,您可以通过在 中的images字段中指定新图像来更改容器内使用的图像kustomization.yaml。
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 名称或作为命令参数。由于服务名称可能会随着文件的更改namePrefix或nameSuffix添加到kustomization.yaml文件中而更改。不建议在命令参数中硬编码服务名称。对于这种用法,Kustomize 可以通过vars.
# 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
3.1 基础和覆盖
Kustomize 有bases和overlays的概念。base是一个带有 的目录,kustomization.yaml其中包含一组资源和相关的定制。base 可以是本地目录,也可以是来自远程 repo 的目录,只要 akustomization.yaml存在于其中即可。叠加层是一个目录,其.kustomization.yaml引用其他自定义目录作为其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
bases:
- ../base
namePrefix: dev-
EOF
mkdir prod
cat <<EOF > prod/kustomization.yaml
bases:
- ../base
namePrefix: prod-
EOF
4.1 如何使用 Kustomize 应用/查看/删除对象
在命令中使用--kustomize或来识别由 . 管理的资源。注意应该指向一个自定义目录,比如
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
运行以下命令以应用部署对象dev-my-nginx:
//创建
kubectl apply -k ./
//运行以下命令之一以查看部署对象dev-my-nginx
kubectl get -k ./
kubectl describe -k ./
//运行以下命令,将部署对象dev-my-nginx与应用清单时集群所处的状态进行比较
kubectl diff -k ./
//运行以下命令删除 Deployment 对象dev-my-nginx
> kubectl delete -k ./
deployment.apps "dev-my-nginx" deleted