Kubernetes-使用Kustomize对Kubernetes对象进行声明式管理-树叶云kubernetes教程 (kubernetes与docker的关系)

教程大全 2025-07-12 10:04:49 浏览

使用 Kustomize 对 Kubernetes 对象进行声明式管理

Kustomize是一个独立的工具,用来通过kustomization 文件定制 Kubernetes 对象。

从 1.14 版本开始,kubectl也开始支持使用 kustomization 文件来管理 Kubernetes 对象。 要查看包含 kustomization 文件的目录中的资源,执行下面的命令:

kubectl kustomize 

要应用这些资源,使用参数–kustomize或-k标志来执行kubectl apply:

kubectl apply -k 

在开始之前

安装kubectl。

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 建议在至少有两个节点的集群上运行本教程,且这些节点不作为控制平面主机。 如果你还没有集群,你可以通过Minikube构建一个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

要检查版本,请输入​ kubectlversion ​。

Kustomize 概述

Kustomize 是一个用来定制 Kubernetes 配置的工具。它提供以下功能特性来管理 应用配置文件:

生成资源

ConfigMap 和 Secret 包含其他 Kubernetes 对象(如 Pod)所需要的配置或敏感数据。 ConfigMap 或 Secret 中数据的来源往往是集群外部,例如某个​ .properties ​文件或者 SSH 密钥文件。 Kustomize 提供​ secretGenerator ​和​ configMapGenerator ​,可以基于文件或字面 值来生成 Secret 和 ConfigMap。

configMapGenerator

要基于文件来生成 ConfigMap,可以在​ configMapGenerator ​的​​列表中添加表项。 下面是一个根据​ .properties ​文件中的数据条目来生成 ConfigMap 的示例:

# 生成一个application.properties 文件cat <application.propertiesFOO=BarEOFcat <./kustomization.yamlconfigMapGenerator:- name: example-configmap-1files:- application.propertiesEOF

所生成的 ConfigMap 可以使用下面的命令来检查:

kubectl kustomize ./

所生成的 ConfigMap 为:

apiVersion: v1data:application.properties: |FOO=Barkind: ConfigMapmetadata:name: example-configmap-1-8mbdf7882g

要从 env 文件生成 ConfigMap,请在​ configMapGenerator ​中的​​列表中添加一个条目。 这也可以用于通过省略​​和值来设置本地环境变量的值。

建议谨慎使用本地环境变量填充功能 —— 用补丁覆盖通常更易于维护。 当无法轻松预测变量的值时,从环境中设置值可能很有用,例如 git SHA。

下面是一个用来自​​文件的数据生成 ConfigMap 的例子:

# 创建一个 .env 文件# BAZ 将使用本地环境变量 $BAZ 的取值填充cat <.envFOO=BarBAZEOFcat <./kustomization.yamlconfigMapGenerator:- name: example-configmap-1envs:- .envEOF

可以使用以下命令检查生成的 ConfigMap:

BAZ=Qux kubectl kustomize ./

生成的 ConfigMap 为:

apiVersion: v1data:BAZ: QuxFOO: Barkind: ConfigMapmetadata:name: example-configmap-1-892ghb99c8

ConfigMap 也可基于字面的键值偶对来生成。要基于键值偶对来生成 ConfigMap, 在​ configMapGenerator ​的​​列表中添加表项。下面是一个例子,展示 如何使用键值偶对中的数据条目来生成 ConfigMap 对象:

cat <./kustomization.yamlconfigMapGenerator:- name: example-configmap-2literals:- FOO=BarEOF

可以用下面的命令检查所生成的 ConfigMap:

kubectl kustomize ./

所生成的 ConfigMap 为:

apiVersion: v1data:FOO: Barkind: ConfigMapmetadata:name: example-configmap-2-g2hdhfc6tk

要在 Deployment 中使用生成的 ConfigMap,使用 configMapGenerator 的名称对其进行引用。 Kustomize 将自动使用生成的名称替换该名称。

这是使用生成的 ConfigMap 的 deployment 示例:

# 创建一个 application.properties 文件cat <application.propertiesFOO=BarEOFcat <deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-applabels:app: my-appspec:selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: appimage: my-appvolumeMounts:- name: configmountpath: /configvolumes:- name: configconfigMap:name: example-configmap-1EOFcat <./kustomization.yamlresources:- deployment.yamlconfigMapGenerator:- name: example-configmap-1files:- application.propertiesEOF

生成 ConfigMap 和 Deployment:

kubectl kustomize ./

生成的 Deployment 将通过名称引用生成的 ConfigMap:

apiVersion: v1data:application.properties: |FOO=Barkind: ConfigMapmetadata:name: example-configmap-1-g4hk9g2ff8---apiVersion: apps/v1kind: Deploymentmetadata:labels:app: my-appname: my-appspec:selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- image: my-appname: appvolumeMounts:- mountPath: /configname: configvolumes:- configMap:name: example-configmap-1-g4hk9g2ff8name: config

secretGenerator

你可以基于文件或者键值偶对来生成 Secret。要使用文件内容来生成 Secret, 在​ secretGenerator ​下面的​​列表中添加表项。 下面是一个根据文件中数据来生成 Secret 对象的示例:

# 创建一个 password.txt 文件cat <./password.txtusername=adminpassword=secretEOFcat <./kustomization.yamlsecretGenerator:- name: example-secret-1files:- password.txtEOF

所生成的 Secret 如下:

apiVersion: v1data:password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==kind: Secretmetadata:name: example-secret-1-t2kt65hgtbtype: Opaque

要基于键值偶对字面值生成 Secret,先要在​ secretGenerator ​的​​列表中添加表项。下面是基于键值偶对中数据条目来生成 Secret 的示例:

cat <./kustomization.yamlsecretGenerator:- name: example-secret-2literals:- username=admin- password=secretEOF

所生成的 Secret 如下:

apiVersion: v1data:password: c2VjcmV0username: YWRtaW4=kind: Secretmetadata:name: example-secret-2-t52t6g96d8type: Opaque

与 ConfigMaps 一样,生成的 Secrets 可以通过引用 secretGenerator 的名称在部署中使用:

# 创建一个 password.txt 文件cat <./password.txtusername=adminpassword=secretEOFcat <deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-applabels:app: my-appspec:selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: appimage: my-appvolumeMounts:- name: passwordmountPath: /secretsvolumes:- name: passwordsecret:secretName: example-secret-1EOFcat <./kustomization.yamlresources:- deployment.yamlsecretGenerator:- name: example-secret-1files:- password.txtEOF

generatorOptions

所生成的 ConfigMap 和 Secret 都会包含内容哈希值后缀。 这是为了确保内容发生变化时,所生成的是新的 ConfigMap 或 Secret。 要禁止自动添加后缀的行为,用户可以使用​ generatorOptions ​。 除此以外,为生成的 ConfigMap 和 Secret 指定贯穿性选项也是可以的。

cat <./kustomization.yamlconfigMapGenerator:- name: example-configmap-3literals:- FOO=BargeneratorOptions:disableNameSuffixHash: truelabels:type: generatedannotations:note: generatedEOF

运行​ kubectl kustomize ./ ​来查看所生成的 ConfigMap:

apiVersion: v1data:FOO: Barkind: ConfigMapmetadata:annotations:note: generatedlabels:type: generatedname: example-configmap-3

设置贯穿性字段

在项目中为所有 Kubernetes 对象设置贯穿性字段是一种常见操作。 贯穿性字段的一些使用场景如下:

下面是一个例子:

# 创建一个 deployment.yamlcat <./deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploymentlabels:app: nginxspec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxEOFcat <./kustomization.yamlnamespace: my-namespacenamePrefix: dev-nameSuffix: "-001"commonLabels:app: bingocommonAnnotations:oncallPager: 800-555-1212resources:- deployment.yamlEOF

执行​ kubectl kustomize ./ ​查看这些字段都被设置到 Deployment 资源上:

apiVersion: apps/v1kind: Deploymentmetadata:annotations:oncallPager: 800-555-1212labels:app: bingoname: dev-nginx-deployment-001namespace: my-namespacespec:selector:matchLabels:app: bingotemplate:metadata:annotations:oncallPager: 800-555-1212labels:app: bingospec:containers:- image: nginxname: nginx

组织和定制资源

一种常见的做法是在项目中构造资源集合并将其放到同一个文件或目录中管理。 Kustomize 提供基于不同文件来组织资源并向其应用补丁或者其他定制的能力。

组织

Kustomize 支持组合不同的资源。​ kustomization.yaml ​文件的​​字段 定义配置中要包含的资源列表。你可以将​​列表中的路径设置为资源配置文件 的路径。下面是由 Deployment 和 Service 构成的 NGINX 应用的示例:

# 创建 deployment.yaml 文件cat < deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80EOF# 创建 service.yaml 文件cat < service.yamlapiVersion: v1kind: Servicemetadata:name: my-nginxlabels:run: my-nginxspec:ports:- port: 80protocol: TCPselector:run: my-nginxEOF# 创建 kustomization.yaml 来组织以上两个资源cat <./kustomization.yamlresources:- deployment.yaml- service.yamlEOF

kubectl kustomize ./ ​所得到的资源中既包含 Deployment 也包含 Service 对象。

定制

补丁文件(Patches)可以用来对资源执行不同的定制。 Kustomize 通过​ patchesStrategicMerge ​和​ patchesJson6902 ​支持不同的打补丁 机制。​ patchesStrategicMerge ​的内容是一个文件路径的列表,其中每个文件都应可解析为策略性合并补丁(Strategic Merge Patch)。 补丁文件中的名称必须与已经加载的资源的名称匹配。 建议构造规模较小的、仅做一件事情的补丁。 例如,构造一个补丁来增加 Deployment 的副本个数;构造另外一个补丁来设置内存限制。

# 创建 deployment.yaml 文件cat < deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80EOF# 生成一个补丁 increase_replicas.yamlcat < increase_replicas.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:replicas: 3EOF# 生成另一个补丁 Set_memory.yamlcat < set_memory.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:template:spec:containers:- name: my-nginxresources:limits:memory: 512MiEOFcat <./kustomization.yamlresources:- deployment.yamlpatchesStrategicMerge:- increase_replicas.yaml- set_memory.yamlEOF

执行​ kubectl kustomize ./ ​来查看 Deployment:

apiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:replicas: 3selector:matchLabels:run: my-nginxtemplate:metadata:labels:run: my-nginxspec:containers:- image: nginxname: my-nginxports:- containerPort: 80resources:limits:memory: 512Mi

并非所有资源或者字段都支持策略性合并补丁。为了支持对任何资源的任何字段进行修改, Kustomize 提供通过​ patchesJson6902 ​来应用JSON 补丁的能力。为了给 JSON 补丁找到正确的资源,需要在​ kustomization.yaml ​文件中指定资源的 组(group)、版本(version)、类别(kind)和名称(name)。 例如,为某 Deployment 对象增加副本个数的操作也可以通过​ patchesJson6902 ​来完成:

# 创建一个 deployment.yaml 文件cat < deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80EOF# 创建一个 JSON 补丁文件cat < patch.yaml- op: replacepath: /spec/replicasvalue: 3EOF# 创建一个 kustomization.yamlcat <./kustomization.yamlresources:- deployment.yamlpatchesJson6902:- target:group: appsversion: v1kind: Deploymentname: my-nginxpath: patch.yamlEOF

执行​ kubectl kustomize ./ ​以查看​​字段被更新:

apiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:replicas: 3selector:matchLabels:run: my-nginxtemplate:metadata:labels:run: my-nginxspec:containers:- image: nginxname: my-nginxports:- containerPort: 80

除了补丁之外,Kustomize 还提供定制容器镜像或者将其他对象的字段值注入到容器 中的能力,并且不需要创建补丁。 例如,你可以通过在​ kustomization.yaml ​文件的​​字段设置新的镜像来 更改容器中使用的镜像。

cat < deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80EOFcat <./kustomization.yamlresources:- deployment.yamlimages:- name: nginxnewName: my.image.registry/nginxnewTag: 1.4.0EOF

执行​ kubectl kustomize ./ ​以查看所使用的镜像已被更新:

apiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:replicas: 2selector:matchLabels:run: my-nginxtemplate:metadata:labels:run: my-nginxspec:containers:- image: my.image.registry/nginx:1.4.0name: my-nginxports:- containerPort: 80

有些时候,Pod 中运行的应用可能需要使用来自其他对象的配置值。 例如,某 Deployment 对象的 Pod 需要从环境变量或命令行参数中读取读取 Service 的名称。 由于在​ kustomization.yaml ​文件中添加​ namePrefix ​或​ nameSuffix ​时 Service 名称可能发生变化,建议不要在命令参数中硬编码 Service 名称。 对于这种使用场景,Kustomize 可以通过​​将 Service 名称注入到容器中。

# 创建一个 deployment.yaml 文件(引用此处的文档分隔符)cat <<'EOF' > deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxcommand: ["start", "--host", "$(MY_SERVICE_NAME)"]EOF# 创建一个 service.yaml 文件cat < service.yamlapiVersion: v1kind: Servicemetadata:name: my-nginxlabels:run: my-nginxspec:ports:- port: 80protocol: TCPselector:run: my-nginxEOFcat <./kustomization.yamlnamePrefix: dev-nameSuffix: "-001"resources:- deployment.yaml- service.yamlvars:- name: MY_SERVICE_NAMEobjref:kind: Servicename: my-nginxapiVersion: v1EOF

执行​ kubectl kustomize ./ ​以查看注入到容器中的 Service 名称是​ dev-my-nginx-001 ​:

apiVersion: apps/v1kind: Deploymentmetadata:name: dev-my-nginx-001spec:replicas: 2selector:matchLabels:run: my-nginxtemplate:metadata:labels:run: my-nginxspec:containers:- command:- start- --host- dev-my-nginx-001image: nginxname: my-nginx

基准(Bases)与覆盖(Overlays)

Kustomize 中有基准(bases)和覆盖(overlays)的概念区分。基准是包含​ kustomization.yaml ​文件的一个目录,其中包含一组资源及其相关的定制。 基准可以是本地目录或者来自远程仓库的目录,只要其中存在​ kustomization.yaml ​文件即可。覆盖也是一个目录,其中包含将其他 kustomization 目录当做​​来引用的​ kustomization.yaml ​文件。基准不了解覆盖的存在,且可被多个覆盖所使用。 覆盖则可以有多个基准,且可针对所有基准中的资源执行组织操作,还可以在其上执行定制。

# 创建一个包含基准的目录mkdir base# 创建 base/deployment.yamlcat < base/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxEOF# 创建 base/service.yaml 文件cat < base/service.yamlapiVersion: v1kind: Servicemetadata:name: my-nginxlabels:run: my-nginxspec:ports:- port: 80protocol: TCPselector:run: my-nginxEOF# 创建 base/kustomization.yamlcat < base/kustomization.yamlresources:- deployment.yaml- service.yamlEOF

此基准可在多个覆盖中使用。你可以在不同的覆盖中添加不同的​ namePrefix ​或 其他贯穿性字段。下面是两个使用同一基准的覆盖:

mkdir devcat < dev/kustomization.yamlbases:- ../basenamePrefix: dev-EOFmkdir prodcat < prod/kustomization.yamlbases:- ../basenamePrefix: prod-EOF

如何使用 Kustomize 来应用、查看和删除对象

在​​命令中使用​ --kustomize ​或​​参数来识别被​ kustomization.yaml ​所管理的资源。 注意​​要指向一个 kustomization 目录。例如:

kubectl apply -k /

假定使用下面的​ kustomization.yaml ​,

# 创建 deployment.yaml 文件cat < deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80EOF# 创建 kustomization.yamlcat <./kustomization.yamlnamePrefix: dev-commonLabels:app: my-nginxresources:- deployment.yamlEOF

执行下面的命令来应用 Deployment 对象​ dev-my-nginx ​:

树叶云kubernetes教程kubectl apply -k ./
deployment.apps/dev-my-nginx created

运行下面的命令之一来查看 Deployment 对象​ dev-my-nginx ​:

kubectl get -k ./
kubectl describe -k ./

执行下面的命令来比较 Deployment 对象​ dev-my-nginx ​与清单被应用之后 集群将处于的状态:

kubectl diff -k ./

执行下面的命令删除 Deployment 对象​ dev-my-nginx ​:

kubectl delete -k ./
deployment.apps "dev-my-nginx" deleted

Kustomize 功能特性列表

字段 类型 解释
为所有资源添加名字空间
namePrefix 此字段的值将被添加到所有资源名称前面
nameSuffix 此字段的值将被添加到所有资源名称后面
commonLabels map[string]string 要添加到所有资源和选择算符的标签
commonAnnotations map[string]string 要添加到所有资源的注解
列表中的每个条目都必须能够解析为现有的资源配置文件
configMapGenerator []ConfigMapArgs 列表中的每个条目都会生成一个 ConfigMap
secretGenerator []SecretArgs 列表中的每个条目都会生成一个 Secret
generatorOptions GeneratorOptions 更改所有 ConfigMap 和 Secret 生成器的行为
列表中每个条目都应能解析为一个包含 kustomization.yaml 文件的目录
patchesStrategicMerge 列表中每个条目都能解析为某 Kubernetes 对象的策略性合并补丁
patchesJson6902 列表中每个条目都能解析为一个 Kubernetes 对象和一个 JSON 补丁
每个条目用来从某资源的字段来析取文字
每个条目都用来更改镜像的名称、标记与/或摘要,不必生成补丁
configurations 列表中每个条目都应能解析为一个包含Kustomize 转换器配置的文件
列表中每个条目都应能够解析为 Kubernetes 类别的 OpenAPI 定义文件
本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐