Kustomize
我们在使用K8s部署应用的时候,经常会因为管理对应的声明式文件而烦恼。在集群规模的变大和业务的增长的时候,我们通过手动去编排,管理这些声明式文件是不太现实的。目前对声明式文件的编排下,主流的解决方案是Helm
和Kustomize
。
Helm
的功能丰富,提供了更灵敏,可拓展的K8s声明式文件管理解决方案。Kustomize
是由K8s社区开发的K8s资源配置管理方案。Kustomize
在功能上不如Helm
丰富,但是由于与K8s的集成较好,在使用kubectl
时候,原生就可以通过-k
参数指定 kustomization 文件。在业务量小,集群小,需求不大的情况下使用起来相比Helm
更为便利。对于想要学习管理资源配置文件的初学者来说,更为友好。
什么是Kustomize
?
Kustomize 提供了一种无需模板和 DSL 即可自定义 Kubernetes 资源配置的解决方案。
Kustomize 允许您出于多种目的自定义原始、无模板的 YAML 文件,使原始 YAML 保持不变并按原样使用。
自定义目标 kubernetes;它理解并可以修补kubernetes style
API 对象。它就像 make,因为它所做的事情是在文件中声明的,它就像sed,因为它发出编辑后的文本。
Kustomize 是一个用于 Kubernetes 配置管理的强大工具,它旨在帮助开发人员和运维团队更轻松地管理复杂的应用程序部署。Kustomize 提供了一种声明性方法来定制和管理 Kubernetes 配置,而无需修改原始 YAML 文件。以下是 Kustomize 的一些主要特点和优势:
- 声明式配置管理:Kustomize 鼓励使用声明性配置,而不是直接编辑 YAML 文件。您可以通过简单的文件修改来实现所需的配置更改,而不必担心复杂的合并和编辑操作。
- 模块化配置:Kustomize 支持将 Kubernetes 配置划分为可重用的模块,称为“Kustomization”。这使得可以轻松地组合和共享不同的配置片段,以构建多个应用程序变体。
- 环境特定配置:Kustomize 提供了一种简单的方法来管理不同环境(例如开发、测试和生产)的配置差异。您可以轻松地覆盖或合并配置以满足不同环境的需求。
- 可扩展性:Kustomize 支持自定义修改器(transformer),这些修改器可以自定义 Kubernetes 配置,以适应特定的用例。这使得 Kustomize 非常灵活,可以适应各种部署要求。
- 与持续集成/持续部署(CI/CD)集成:Kustomize 可以与常见的 CI/CD 工具集成,如 Jenkins、GitLab CI/CD、GitHub Actions 等,使自动化部署变得更加容易。
安装kustomize
本文通过Go进行安装,也可以通过二进制进行安装。
二进制安装:
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
Go安装
# golang >= 1.17
go install sigs.k8s.io/kustomize/kustomize/v5@latest
# golang < 1.17
go get sigs.k8s.io/kustomize/kustomize/v5
安装之后通过kustomize version
查看是否成功安装。
入门
我们通过一个例子来介绍Kustomize
到底是什么:
假设我们当前有一个app需要部署,这个app的部署同时涉及到Service,Deployment,ConfigMap等(这里只列举三个,实际上要部署的工作负载可能会更多)。并且,在不同环境下需要同时部署该app,dev和prod环境下的数据库密码也许不同,Service使用的路由器也有可能不同,此时我们该如何去管理呢?
app.yaml
:
apiVersion: v1
kind: Pod
metadata:
labels:
traefik.instance: app
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: whoami-svc
spec:
ports:
- protocol: TCP
port: 4000
targetPort: 80
selector:
traefik.instance: app
此时我们可以通过Kustomize进行管理对应的资源文件。
通过kustomize create --resources app.yaml,svc.yaml
生成对应的kustomize文件。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# resources声明了多个K8s资源文件
resources:
- app.yaml
- svc.yaml
我们看一下目录结构:
./
├── app.yaml
├── kustomization.yaml
└── svc.yaml
我们可以通过kubectl apply -k ./
(kustomization文件所在的目录),就可以将Kustomization文件中声明的resources部署K8s集群中。
Transformer
Kustomize 中的转换器(transformer)是一种可以修改 Kubernetes 配置的插件或工具。这些转换器允许您在部署过程中对原始的 Kubernetes YAML 文件进行修改、扩展或定制,以适应特定的需求。转换器通常用于应用程序配置的特定场景,例如添加标签、修改资源名称、引入配置片段等。
我们可以理解为,这是对资源文件的一些字段进行统一修改。
我们先学习一个command:
kustomize build ./
,这可以将当前kustomize所管理的resources构建出来。
CommonLabels
CommonLabels为Kustomize
管理的所有资源和资源中存在Selectors字段添加Labels。
- 如果资源上已经存在同名label,则该值将被覆盖。
- 如果资源上没有同名label,则值会添加上去
apiVersion: v1
kind: Pod
metadata:
labels:
# 此时存在labels abc
abc: def
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
我们在kustomize中进行声明commonLabels
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- app.yaml
commonLabels:
abc: zxc
进行构建: kustomize build ./
$ kustomize build ./
apiVersion: v1
kind: Pod
metadata:
labels:
# 此时对应的label被覆盖
abc: zxc
traefik.instance: app
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
CommonAnnotations
CommonAnnotations为Kustomize
管理的所有资源添加annotations。
- 如果资源上已经存在同名annotation,则该值将被覆盖
- 如果资源上没有同名annotation,则值会添加上去
apiVersion: v1
kind: Pod
metadata:
# 此时不存在annotation
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
我们在kustomize中添加annotation:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- app.yaml
commonAnnotations:
shyunn.io: instance
通过kustomize build ./
进行构建,此时可以看见annotation自动添加到资源上。
$ kustomize build ./
apiVersion: v1
kind: Pod
metadata:
annotations:
shyunn.io: instance
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
Name
kustomize
提供了对资源名称添加prefix
前缀和suffix
后缀的功能,这可以让我们在不同的环境下可以生成不同name。尤其是在下面我们介绍的multi namespace中提供了能力。
NamePrefix:为所有资源和引用的名称添加前缀
NameSuffix:为所有资源和引用的名称添加后缀
apiVersion: v1
kind: Pod
metadata:
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
在kustomize文件中声明nameprefix和namefuffix:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- app.yaml
namePrefix: shyunn-
nameSuffix: -dev
通过kustomize构建,我们可以看到对应的资源名称被添加上了前缀和后缀。
$ kustomize build ./
apiVersion: v1
kind: Pod
metadata:
# 添加了prefix和suffix
name: shyunn-whoami-dev
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
Namespace
kustomize
可以为所有的资源添加namespace。
-
如果在资源上设置了现有 namespace,则将覆盖现有 namespace
-
如果在资源上未设置现有 namespace,则使用现有 namespace
apiVersion: v1
kind: Pod
metadata:
name: whoami
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
在kustomize文件中声明namespace。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- app.yaml
namespace: dev
通过进行构建我们可以发现,对应的资源被声明在dev的namespace中
$ kustomize build ./
apiVersion: v1
kind: Pod
metadata:
name: whoami
# 对应的namespace被添加上去
namespace: dev
spec:
containers:
- image: nginx:1.14.1
name: whoami
ports:
- containerPort: 80
Other
Image
修改镜像的name,tag或digest,而无需使用patches 。
images字段将会修改 kustomization 所引用的资源的镜像。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deploy.yaml
images:
# 将会修改所有资源中镜像名对应的镜像
- name: redis
# 修改镜像名
newName: aliyun/redis
# 修改tag
newTag: v1
- name: nginx
# 仅修改tag
newTag: 1.8.0
- name: my-demo-app
# 仅修改镜像名
newName: my-app
- name: alpine
# 修改镜像digest
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
Replicas
Replicas修改 kustomization 文件中所引用的资源的副本数。
只能匹配如下资源中的一种:
Deployment
ReplicationController
ReplicaSet
StatefulSet
如果有更复杂的变更需求,则使用
patch
进行修改
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 覆盖引用的资源中,指定资源的replicas数量
replicas:
# 资源名
# 必须匹配上述资源中的其中一种
- name: deployment-name
count: 5
Generator
kustomize
提供了生成K8s中Secret
,ConfigMap
资源的功能。
ConfigMap
我们可以通过传入file,env file,literals进行生成ConfigMap。
先来看一个例子
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 配置对应的configMapGen
configMapGenerator:
- name: cm-1
# 引用file
# file名作为key
files:
- cm-data-1
- name: cm-2
# 引用env文件(kv文件)
envs:
- kv2
- name: cm-3
# 使用字面值kv对
literals:
- GO_ROOT=/usr/bin/go/bin
我们进行渲染查看效果:
$ kustomize build ./
apiVersion: v1
data:
cm-data-1: |
123
kind: ConfigMap
metadata:
name: cm-1-kc4gtbhgk9
---
apiVersion: v1
data:
kvabcf: ""
kind: ConfigMap
metadata:
name: cm-2-hm5fc8dt8f
---
apiVersion: v1
data:
GO_ROOT: /usr/bin/go/bin
kind: ConfigMap
metadata:
name: cm-3-7mf596gcb2
我们可以看到,当我们构建 kustomization 时,将会为我们生成指定的ConfigMap。当我们在进行多环境管理的时候,可以根据需求和环境进行生成ConfigMap。
我们在resources中定义的
ConfigMap
名可以声明与configMapGenerator
名称一致,当进行构建的时候会自动进行关联。
我们还可以对生成的ConfigMap
设置Labels和Annotations:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: cm-3
literals:
- GO_ROOT=/usr/bin/go/bin
# 通过options进行设置ConfigMap的labels和annotations
options:
labels:
cm-gen: "true"
annotations:
cm-gen: "true"
构建结果:
$ kustomize build ./
apiVersion: v1
data:
GO_ROOT: /usr/bin/go/bin
kind: ConfigMap
metadata:
# 对应的annotations和labels也被设置了
annotations:
cm-gen: "true"
labels:
cm-gen: "true"
name: cm-3-7mf596gcb2
每个 ConfigMapGenerator
项均接受的参数 behavior: [create|replace|merge]
,这个参数允许修改或替换父级现有的 ConfigMap
.
在kustomize进行级联使用的时候,我们如果声明一个同名的ConfigMap
。此时则需要考虑如何设置behavior
Secret
Secret
的字段与ConfigMap
字段使用类似。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: cm-1
files:
- cm-data-1
type: Opaque
- name: cm-2
envs:
- kv2
- name: cm-3
literals:
- GO_ROOT=/usr/bin/go/bin
options:
labels:
cm-gen: "true"
annotations:
cm-gen: "true"
进行构建的结果:
$ kustomize build ./
apiVersion: v1
data:
cm-data-1: MTIzCg==
kind: Secret
metadata:
name: cm-1-76642cdm79
type: Opaque
---
apiVersion: v1
data:
kvabcf: ""
kind: Secret
metadata:
name: cm-2-f844thkf2f
type: Opaque
---
apiVersion: v1
data:
GO_ROOT: L3Vzci9iaW4vZ28vYmlu
kind: Secret
metadata:
annotations:
cm-gen: "true"
labels:
cm-gen: "true"
name: cm-3-tmg5k7k57c
type: Opaque
GeneratorOptions
GeneratorOptions
用于控制生成的ConfigMap
和Secret
。我们不仅可以单独声明,在上面的例子中,我们在ConfigMap
和Secret
项中也可以声明option去覆盖全局声明的GeneratorOptions
。
先来看一下相关的字段定义:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generatorOptions:
# 添加labels到所有生成的Secret/Confimap上
# Sercet/Configmap可以通过option进行覆盖全局的配置
labels:
kustomize.generated.resources: somevalue
# 添加annotations到所有生成的Secret/Confimap上
# Sercet/Configmap可以通过option进行覆盖全局的配置
annotations:
kustomize.generated.resource: somevalue
# 禁用生成的资源名后面加hash后缀
# 细心的朋友应该有注意到,我们上面几个生成资源的例子渲染后输出的资源名都有一个hash后缀
disableNameSuffixHash: true
我们尝试使用generatorOptions
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generatorOptions:
labels:
gen-options: global
# 禁用生成的ConfigMap携带Hash后缀
disableNameSuffixHash: true
configmapGenerator:
- name: cm-1
literals:
- GOOS=linux
# 使用局部的option进行覆盖
- name: cm-2-overlay
literals:
- GOOS=windows
options:
labels:
gen-options: overlay
经过构建后输出:
$ kustomize build ./
apiVersion: v1
data:
GOOS: linux
kind: ConfigMap
metadata:
labels:
gen-options: global
name: cm-1
---
apiVersion: v1
data:
GOOS: windows
kind: ConfigMap
metadata:
labels:
gen-options: overlay
name: cm-2-overlay
Base-Overlay
在 kustomization 文件中,不仅可以关联K8s resources资源文件,同时还可以引用其他 kustomization 文件。在开发中,我们一般会将通用的deployment
,service
作为基础层(base),在基础层通过 kustomization 文件将相关的基础资源进行组织。在部署期间,可能开发阶段需要连接开发的数据库,生成阶段需要连接生产的数据库。此时我们会创建一个覆盖层(overlays)。在该覆盖层下根据不同的环境/命名空间进行声明目录,在目录中创建对应的 kustomization 文件应用基础层(base)的 kustomization 文件。
resources:
# 通过资源引用base层的kustomization文件
- ../../base/kustomization.yaml
这种方式让我们可以有更灵活的方式组织资源文件。对应用进行抽象,将基础的组件抽象成base层,在部署的时候根据业务要求和环境,进行动态的组合不同的resources。
处理 Kustomization 文件时,可能会访问到该目录以内或以外的文件。
像 YAML 资源这样的数据文件,或者用于生成 ConfigMap 或 Secret 的包含 name=value
的文本文件,或者用于补丁转换的补丁文件,必须在这个目录的内部,需要显式的使用相对路径来表达。
v2.1 中有一个特殊选项 --load_restrictions none
能够放宽这个限制,从而让不同的 Kustomization 可以共享补丁文件。
可以用 URL、绝对路径或者相对路径引用其它的 Kustomization(包含 kustomization.yaml
文件的其它目录)。
如果 A
Kustomization 依赖 B
Kustomization,那么:
B
不能包含A
。B
不能依赖A
,间接依赖也不可以。
A
可以包含 B
,但是这样的话,最简单的方式可能是让 A
直接依赖 B
的资源,并去除 B
的 kustomization.yaml
文件(就是把 B
合并到 A
)。
通常情况下,B
和 A
处于同级目录,或者 B
放在一个完全独立的 Git 仓库里,可以从任意的 Kustomization 进行引用。
常见布局大致如下:
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── dev
│ ├── kustomization.yaml
│ └── patch.yaml
├── prod
│ ├── kustomization.yaml
│ └── patch.yaml
└── staging
├── kustomization.yaml
└── patch.yaml
dev
、prod
以及 staging
是否依赖于 base
,要根据 kustomization.yaml
具体判断。
Patch
Patches 在资源上添加或覆盖字段,Kustomization 使用 patches
字段来提供该功能。
patches
字段包含要按指定顺序应用的 patch 列表。
patch可以是:
- 是一个 strategic merge patch,或者是一个 JSON patch。
- 也可以是 patch 文件或 inline string
- 针对单个资源或多个资源
目标选择器可以通过 group、version、kind、name、namespace、标签选择器和注释选择器来选择资源,选择一个或多个匹配所有指定字段的资源来应用 patch。
当我们使用仓库中,或者引用别人的 kustomization 文件的时候,由于并不能直接在源文件上直接进行修改,此时我们可以通过
patch
操作进行打补丁
假设我们在base文件中定义好了一个deployment
文件,我们在dev环境中进行引用,此时我们可以通过patch
的操作进行补丁形式修改副本数。
# deploymen文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
spec:
selector:
matchLabels:
run: nginx
replicas: 1
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: my-nginx
image: nginx:1.14.1
ports:
- containerPort: 80
# base/kustomization.yaml
aiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
我们在dev环境中引用base的 kustomization 文件:
# dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base/
# 声明patches
patches:
# 可以通过patch声明inline string patch
# 或者通过path指定patch文件
- patch: |-
- op: replace
path: /spec/replicas
# 将副本数改为3
value: 3
target:
group: apps
version: v1
kind: Deployment
name: whoami
# 可以通过label或annotation选择器进行选择
#labelSelector: "env=dev"
#annotationSelector: "zone=west"
我们构建输出结果:
$ kustomize build ./
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:1.14.1
name: my-nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: config
volumes:
- configMap:
name: nginx-cm
name: config
可以看到副本数被补丁改为3。因此在很多情况我们不能直接进行修改源文件,可以通过补丁的形式根据需求的修改字段。
我们还可以通过patchesStrategicMerge
的形式进行打补丁。如下所示
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base/
patches:
- patch: |-
- op: replace
path: /spec/replicas
value: 3
target:
group: apps
version: v1
kind: Deployment
name: whoami
# 添加一个deployment中pod的镜像 nginx:1.14.1 + nginx:latest
# 当然,也可以将inline string替换为file: - patch: image_patch.yaml
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
spec:
template:
spec:
containers:
- name: nginx
image: nignx:latest
最佳实践
【又学又练,快如闪电】
application
我们通过一个案例巩固一下 kustomize 的使用: 现有一个需求,我们需要部署一个应用,该应用在不同的环境中所对应的配置文件也不同,我们需要根据需求进行不同环境下的部署。
该应用需要准备deployment(应用)
,service(服务)
,configmap(配置)
文件
# deployment文件(丐版)
apiVersion: apps/v1
kind: Deployment
metadata:
name: application
spec:
# 基础副本数为1
replicas: 1
selector:
matchLabels:
run: app
template:
metadata:
labels:
run: app
spec:
containers:
- image: shyunn.images.io/app:v0.1.5
name: app
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: config
# configmap配置挂载
volumes:
- configMap:
name: app-cm
name: config
# service
apiVersion: v1
kind: Service
metadata:
name: app-svc
spec:
ports:
- protocol: TCP
port: 4000
targetPort: 80
selector:
run: app
# configmap我们通过kustomize进行生成,灵活度更高. 故在此不声明
---
# dev开发环境下的conf配置
database:
mysql:
username: dev-usr
password: abcd-efg
redis:
url: 127.0.0.1:9090
# prod生产环境下的conf配置
database:
mysql:
username: prod-usr
password: 123-456
redis:
url: 127.0.0.1:9010
此时我们创建目录进行分类,如下:
$ tree ./
./
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
├── dev
│ ├── conf.yaml
│ └── kustomization.yaml
└── prod
├── conf.yaml
└── kustomization.yaml
# base的kustomization文件组合了所需的基础资源配置
$ cat base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
# dev的kustomization
$ cat dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base/
configMapGenerator:
# 对应app应用的ConfigMap
- name: app-cm
files:
- ./conf.yaml
commonLabels:
shyunn.app.stage: dev
nameSuffix: -dev
replicas:
- name: application
count: 2
# prod的kustmization
$ cat prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base/
configMapGenerator:
# 对应app应用的ConfigMap
- name: app-cm
files:
- ./conf.yaml
commonLabels:
shyunn.app.stage: prod
nameSuffix: -prod
replicas:
- name: application
count: 5
我们通过kustomize build
进行渲染输出,看一下是否符合我们的预期:
# 开发环境下构建
$ kustomize build ./dev/
apiVersion: v1
data:
conf.yaml: |
# dev开发环境下的配置
database:
mysql:
username: dev-usr
password: abcd-efg
redis:
url: 127.0.0.1:9090
kind: ConfigMap
metadata:
labels:
shyunn.app.stage: dev
name: app-cm-dev-gc9d9d6gcc
---
apiVersion: v1
kind: Service
metadata:
labels:
shyunn.app.stage: dev
name: app-svc-dev
spec:
ports:
- port: 4000
protocol: TCP
targetPort: 80
selector:
run: app
shyunn.app.stage: dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
shyunn.app.stage: dev
name: application-dev
spec:
replicas: 2
selector:
matchLabels:
run: app
shyunn.app.stage: dev
template:
metadata:
labels:
run: app
shyunn.app.stage: dev
spec:
containers:
- image: shyunn.images.io/app:v0.1.5
name: app
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: config
volumes:
- configMap:
name: app-cm-dev-gc9d9d6gcc
name: config
# 生产环境下构建
$ kustomize build ./prod/
apiVersion: v1
data:
conf.yaml: |
# prod生产环境下的配置
database:
mysql:
username: prod-usr
password: 123-456
redis:
url: 127.0.0.1:9010
kind: ConfigMap
metadata:
labels:
shyunn.app.stage: prod
name: app-cm-prod-82k4f42245
---
apiVersion: v1
kind: Service
metadata:
labels:
shyunn.app.stage: prod
name: app-svc-prod
spec:
ports:
- port: 4000
protocol: TCP
targetPort: 80
selector:
run: app
shyunn.app.stage: prod
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
shyunn.app.stage: prod
name: application-prod
spec:
replicas: 5
selector:
matchLabels:
run: app
shyunn.app.stage: prod
template:
metadata:
labels:
run: app
shyunn.app.stage: prod
spec:
containers:
- image: shyunn.images.io/app:v0.1.5
name: app
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: config
volumes:
- configMap:
name: app-cm-prod-82k4f42245
name: config
以上就完成了通过kustomize
管理K8s资源文件。通过base
管理基础文件,overlay
组合基础层文件进行自定义构建。这样操作的好处是让我们更灵活的管理配置,组合配置。以上例子中,我们可以对conf进行更为灵活的权限设置,dev和prod的配置文件设置不同的权限。让不同的开发人员仅关注属于专业领域的资源管理。
作为运维管理员,我们也许需要同时部署到生产和开发环境中,此时我们可以再叠加一层,将应用同时部署在一个命名空间中。
首先修改dev和prod中kustomization
文件resources指向的base路径。然后重新修改目录结构
$ tree ./
./
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlay
├── dev
│ ├── conf.yaml
│ └── kustomization.yaml
├── kustomization.yaml # 管理dev,prod
├── namespace.yaml # 需要部署的namespace
└── prod
├── conf.yaml
└── kustomization.yaml
# 运维人员可以一键将应用部署到指定的namespace中,同时部署prod和dev的应用。
$ cat overlay/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- dev/
- prod/
- namespace.yaml
namespace: orange
command
kustomize命令中有许多比较实用命令,可以帮助我们快速构建 kustomization 文件以及部署。
kustomize kustomize create --resources app.yaml
: 帮助我们快速构建一个 kustomization 文件,同时将app.yaml引用在resources中。
kustomize build ./ | kubectl apply -f -
:将kustomize 构建输出作为STDIN传递给kubectl进行部署。
此命令等价于kubectl apply -k ./
kustomize cfg count ./
:统计当前目录下资源配置
$ kustomize cfg count ./
.//
: 2
Deployment: 1
Kustomization: 4
Namespace: 1
Service: 1
kustomize cfg tree ./
:输出当前目录下资源的树形结构
:fire:: 这个命令极大的帮助我们进行构建 kustomization 文件结构
$ kustomize cfg tree ./
.
├── base
│ ├── [deployment.yaml] Deployment application
│ ├── [kustomization.yaml] Kustomization
│ └── [service.yaml] Service app-svc
└── overlay
├── [kustomization.yaml] Kustomization
├── [namespace.yaml] Namespace orange
├── dev
│ └── [kustomization.yaml] Kustomization
└── prod
└── [kustomization.yaml] Kustomization