在前一篇文章中介绍了 Kubernetes 上的包管理工具 Helm。Helm Chart 以模板的形式来生成 Kubernetes 上的资源定义,允许对应用的安装进行灵活的定制。Helm 也提供了对安装到 Kubernetes 上的 release 的管理。不过,Helm Chart 的开发相对复杂,需要了解模板的语法。本文中要介绍的 kustomize 则提供了另外一种安装应用的方案。
kustomize 的名称来源于英文单词 customize ,也就是自定义,只不过把 c 换成了表示 Kubernetes 的 k。
kustomize 是一个通用的工具,它的作用是对描述 Kubernetes 资源的 YAML 文件进行定制,产生新的 YAML 文件,并保持原始的 YAML 文件不变。从这个意义上来说,你可以把 kustomize 看成是 Kubernetes YAML 文件的转换工具,可以与 XML 和 XSLT 进行类比。
kustomize 的一个重要特征是不使用模板,而是直接工作在原始的 YAML 文件上。这一点与 Helm 是不同的。不使用模板好处在于简单易懂,不需要掌握复杂的模板语法。
kustomize 的另外一个优势是集成在 kubectl 中,这就意味着不需要安装额外的工具就可以进行定制。需要注意的是,由于实现上的原因,kubectl 自带的 kustomize 的版本比较低,目前仍然需要安装单独的 kustomize 工具。这个问题要到 1.20 版本才会解决。
$ brew install kustomize
kustomize 使用 kustomization.yaml
文件来描述对 YAML 文件的修改。
下面我通过3个实例来具体说明kustomize的用法。
第一个实例使用 kustomize 提供的简单的配置项来对 Kubernetes 资源进行修改。在这个实例中,deployment.yaml
是一个 nginx 部署的资源。在 kustomization.yaml
文件中,resources
表示所包含的资源文件,namePrefix
表示为所有资源名称添加的前缀,commonAnnotations
表示为所有资源添加的注解,commonLabels
表示为所有资源添加的标签。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namePrefix: dev-
commonAnnotations:
updatedBy: kustomize
commonLabels:
owner: test-company
serverVersion: v1
使用 kustomize build
可以输出修改之后的 YAML 文件的内容。
$ kustomize build nginx
从输出的内容可以看到,生成的 Deployment 添加了相应的名称前缀、注解和标签。
输出的内容可以直接传递给 kubectl apply
命令,在 Kubernetes 上应用。
$ kustomize build nginx | kubectl apply -f -
也可以直接使用 kubectl
来应用。
$ kubectl apply -k nginx
第二个实例是生成 ConfigMap
和对资源进行手动修改。给出的 deployment.yaml
文件部署一个 busybox 容器。在 kustomization.yaml
文件中,configMapGenerator
用来生成 ConfigMap
,而 ConfigMap
中的内容可以是通过 files
声明的文件,或是通过 literals
声明的名值对。而 options
中的disableNameSuffixHash
表示不在名称之后添加Hash值作为后缀。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
patches:
- path: patch.yaml
configMapGenerator:
- name: app-properties
files:
- application.properties
literals:
- EXTRA_ARG=demo
options:
disableNameSuffixHash: true
在 patches
中声明了对资源 YAML 文件的修改。在 patch.yaml
文件中,只需要声明 Deployment
资源中需要修改的部分即可,最终生成的 YAML 文件会把原始的 deployment.yaml
文件和 patch.yaml
文件做合并。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sleep
spec:
template:
spec:
containers:
- name: busybox
env:
- name: VAR
valueFrom:
configMapKeyRef:
name: app-properties
key: EXTRA_ARG
最后一个例子展示了使用 kustomize 来组织应用的安装。在 base
目录中,包含了应用相关的资源,以及基本的定制。在 overlays
目录中,development
和 production
分别表示开发和生产环境,包含环境相关的定制。
app
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── development
│ ├── kustomization.yaml
│ └── resource_config.yaml
└── production
├── kustomization.yaml
└── resource_config.yaml
在每个环境中有各自的 kustomization.yaml
文件来声明所做的修改。这里的 resources
指向 base
目录。在 patches
中声明的 resource_config.yaml
用来修改容器的资源需求。
resources:
- ../../base
namePrefix: dev-
patches:
- path: resource_config.yaml
多个 kustomization.yaml
文件所声明的修改,可以叠加在一起,从而产生最终的资源文件。
总结
通过这3个实例的介绍,相信你对 kustomize 应该有一定的了解。总的来说,kustomize 提供了更强大的对 YAML 文件进行修改的能力,通过 kustomization.yaml
文件声明的定制,可以被共享和组合。相对于 Helm 来说,Helm 提供了对安装之后的 release 的管理,也有更加完备的 Chart 共享机制。如果是公开的应用,用 Helm 更好,方便应用的共享和使用,可以提供更灵活的配置方式;如果是私有应用,kustomize 会更加简单一些,因为在不同环境上的定制需求会很少,使用 YAML 的方式更加直接。
本文相关的视频已发布在我的B站( alexcheng1982)。
本文相关的代码在GitHub(VividcodeIO/kustomize-examples)。