Kustomize
参考文档
- 使用 Kustomize 对 Kubernetes 对象进行声明式管理 | Kubernetes
- kubernetes-sigs/kustomize: Customization of kubernetes YAML configurations (github.com)
- Kustomize - Kubernetes native configuration management
- SIG CLI (kubernetes.io)
Kustomize 概述
Kustomize 引入了一种无需模板的方法来自定义应用程序配置,从而简化了现成应用程序的使用。
Kustomize 是一个独立的工具,用来通过 kustomization 文件 定制 Kubernetes 对象。
基准(Bases)与覆盖(Overlays)
Kustomize 中有 基准(bases) 和 覆盖(overlays) 的概念区分。 基准 是包含 kustomization.yaml
文件的一个目录,其中包含一组资源及其相关的定制。 基准可以是本地目录或者来自远程仓库的目录,只要其中存在 kustomization.yaml
文件即可。 覆盖 也是一个目录,其中包含将其他 kustomization 目录当做 bases
来引用的 kustomization.yaml
文件。 基准不了解覆盖的存在,且可被多个覆盖所使用。 覆盖则可以有多个基准,且可针对所有基准中的资源执行组织操作,还可以在其上执行定制。
# 创建一个包含基准的目录
mkdir base
# 创建 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
# 创建 base/service.yaml 文件
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
# 创建 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
功能特性列表
Kustomize 是一个用来定制 Kubernetes 配置的工具。它提供以下功能特性来管理应用配置文件:
- 从其他来源生成资源
- 为资源设置贯穿性(Cross-Cutting)字段
- 组织和定制资源集合
生成资源
ConfigMap 和 Secret 包含其他 Kubernetes 对象(如 Pod)所需要的配置或敏感数据。 ConfigMap 或 Secret 中数据的来源往往是集群外部,例如某个 .properties
文件或者 SSH 密钥文件。 Kustomize 提供 secretGenerator
和 configMapGenerator
,可以基于文件或字面值来生成 Secret 和 ConfigMap。
configMapGenerator
files
要基于文件来生成 ConfigMap,可以在 configMapGenerator
的 files
列表中添加表项。 下面是一个根据 .properties
文件中的数据条目来生成 ConfigMap 的示例:
# 生成一个 application.properties 文件
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
所生成的 ConfigMap 可以使用下面的命令来检查:
kubectl kustomize ./
所生成的 ConfigMap 为:
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
envs
要从 env 文件生成 ConfigMap,请在 configMapGenerator
中的 envs
列表中添加一个条目。 下面是一个用来自 .env
文件的数据生成 ConfigMap 的例子:
# 创建一个 .env 文件
cat <<EOF >.env
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
envs:
- .env
EOF
可以使用以下命令检查生成的 ConfigMap:
kubectl kustomize ./
生成的 ConfigMap 为:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-1-42cfbf598f
说明: .env 文件中的每个变量在生成的 ConfigMap 中成为一个单独的键。 这与之前的示例不同,前一个示例将一个名为 .properties 的文件(及其所有条目)嵌入到同一个键的值中。
literals
ConfigMap 也可基于字面的键值偶对来生成。要基于键值偶对来生成 ConfigMap, 在 configMapGenerator
的 literals
列表中添加表项。下面是一个例子, 展示如何使用键值偶对中的数据条目来生成 ConfigMap 对象:
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
EOF
可以用下面的命令检查所生成的 ConfigMap:
kubectl kustomize ./
所生成的 ConfigMap 为:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
要在 Deployment 中使用生成的 ConfigMap,使用 configMapGenerator 的名称对其进行引用。 Kustomize 将自动使用生成的名称替换该名称。
这是使用生成的 ConfigMap 的 deployment 示例:
# 创建一个 application.properties 文件
cat <<EOF >application.properties
FOO=Bar
EOF
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
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
生成 ConfigMap 和 Deployment:
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
secretGenerator
你可以基于文件或者键值偶对来生成 Secret。
files
要使用文件内容来生成 Secret, 在 secretGenerator
下面的 files
列表中添加表项。 下面是一个根据文件中数据来生成 Secret 对象的示例:
# 创建一个 password.txt 文件
cat <<EOF >./password.txt
username=admin
password=secret
EOF
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
literals
要基于键值偶对字面值生成 Secret,先要在 secretGenerator
的 literals
列表中添加表项。下面是基于键值偶对中数据条目来生成 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
与 ConfigMap 一样,生成的 Secret 可以通过引用 secretGenerator 的名称在 Deployment 中使用:
# 创建一个 password.txt 文件
cat <<EOF >./password.txt
username=admin
password=secret
EOF
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
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
generatorOptions
所生成的 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
设置贯穿性字段
在项目中为所有 Kubernetes 对象设置贯穿性字段是一种常见操作。 贯穿性字段的一些使用场景如下:
- 为所有资源设置相同的名字空间
namespace
- 为所有对象添加相同的前缀
namePrefix
或后缀nameSuffix
- 为对象添加相同的标签集合
commonLabels
- 为对象添加相同的注解集合
commonAnnotations
下面是一个例子:
# 创建一个 deployment.yaml
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
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 资源上:
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
组织和定制资源
一种常见的做法是在项目中构造资源集合并将其放到同一个文件或目录中管理。 Kustomize 提供基于不同文件来组织资源并向其应用补丁或者其他定制的能力。
组织resources
Kustomize 支持组合不同的资源。kustomization.yaml
文件的 resources
字段定义配置中要包含的资源列表。 你可以将 resources
列表中的路径设置为资源配置文件的路径。 下面是由 Deployment 和 Service 构成的 NGINX 应用的示例:
# 创建 deployment.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
# 创建 service.yaml 文件
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
# 创建 kustomization.yaml 来组织以上两个资源
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
kubectl kustomize ./
所得到的资源中既包含 Deployment 也包含 Service 对象。
定制
补丁文件(Patches)可以用来对资源执行不同的定制。 Kustomize 通过 patchesStrategicMerge
和 patchesJson6902
支持不同的打补丁机制。
patchesStrategicMerge
patchesStrategicMerge
的内容是一个文件路径的列表,其中每个文件都应可解析为 策略性合并补丁(Strategic Merge Patch)。 补丁文件中的名称必须与已经加载的资源的名称匹配。 建议构造规模较小的、仅做一件事情的补丁。 例如,构造一个补丁来增加 Deployment 的副本个数;构造另外一个补丁来设置内存限制。
# 创建 deployment.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
# 生成一个补丁 increase_replicas.yaml
cat <<EOF > increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
EOF
# 生成另一个补丁 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 ./
来查看 Deployment:
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
patchesJson6902
并非所有资源或者字段都支持策略性合并补丁。为了支持对任何资源的任何字段进行修改, Kustomize 提供通过 patchesJson6902
来应用 JSON 补丁的能力。 为了给 JSON 补丁找到正确的资源,需要在 kustomization.yaml
文件中指定资源的组(group)、 版本(version)、类别(kind)和名称(name)。 例如,为某 Deployment 对象增加副本个数的操作也可以通过 patchesJson6902
来完成:
# 创建一个 deployment.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
# 创建一个 JSON 补丁文件
cat <<EOF > patch.yaml
- op: replace
path: /spec/replicas
value: 3
EOF
# 创建一个 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 还提供定制容器镜像或者将其他对象的字段值注入到容器中的能力,并且不需要创建补丁。 例如,你可以通过在 kustomization.yaml
文件的 images
字段设置新的镜像来更改容器中使用的镜像。
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
vars-???
有些时候,Pod 中运行的应用可能需要使用来自其他对象的配置值。 例如,某 Deployment 对象的 Pod 需要从环境变量或命令行参数中读取读取 Service 的名称。 由于在 kustomization.yaml
文件中添加 namePrefix
或 nameSuffix
时 Service 名称可能发生变化,建议不要在命令参数中硬编码 Service 名称。 对于这种使用场景,Kustomize 可以通过 vars
将 Service 名称注入到容器中。
# 创建一个 deployment.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
command: ["start", "--host", "$(MY_SERVICE_NAME)"]
EOF
# 创建一个 service.yaml 文件
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
Kustomize 功能特性列表
字段 | 类型 | 解释 |
---|---|---|
namespace | string | 为所有资源添加名字空间 |
namePrefix | string | 此字段的值将被添加到所有资源名称前面 |
nameSuffix | string | 此字段的值将被添加到所有资源名称后面 |
commonLabels | map[string]string | 要添加到所有资源和选择算符的标签 |
commonAnnotations | map[string]string | 要添加到所有资源的注解 |
resources | []string | 列表中的每个条目都必须能够解析为现有的资源配置文件 |
configMapGenerator | []ConfigMapArgs | 列表中的每个条目都会生成一个 ConfigMap |
secretGenerator | []SecretArgs | 列表中的每个条目都会生成一个 Secret |
generatorOptions | GeneratorOptions | 更改所有 ConfigMap 和 Secret 生成器的行为 |
bases | []string | 列表中每个条目都应能解析为一个包含 kustomization.yaml 文件的目录 |
patchesStrategicMerge | []string | 列表中每个条目都能解析为某 Kubernetes 对象的策略性合并补丁 |
patchesJson6902 | []Patch | 列表中每个条目都能解析为一个 Kubernetes 对象和一个 JSON 补丁 |
vars | []Var | 每个条目用来从某资源的字段来析取文字 |
images | []Image | 每个条目都用来更改镜像的名称、标记与/或摘要,不必生成补丁 |
configurations | []string | 列表中每个条目都应能解析为一个包含 Kustomize 转换器配置 的文件 |
crds | []string | 列表中每个条目都应能够解析为 Kubernetes 类别的 OpenAPI 定义文件 |
使用方法(kubectl、kustomize)
使用kubectl的 Kustomize 来应用、查看和删除对象
从 1.14 版本开始,kubectl
也开始支持使用 kustomization 文件来管理 Kubernetes 对象。
Kubectl version | Kustomize version |
---|---|
< v1.14 | n/a |
v1.14-v1.20 | v2.0.3 |
v1.21 | v4.0.5 |
v1.22 | v4.2.0 |
注意:kubectl的v1.20及之前版本中集成的Kustomize版本很旧,冻结到v2.0.3,运行现在的kustomize文件会有报错,例如Error: json: unknown field "metadata"
,故若使用kubectl来管理kustomize文件,需使用kubectl的v1.21及其后续版本
要查看包含 kustomization 文件的目录中的资源,执行下面的命令:
kubectl kustomize <kustomization_directory>
要应用这些资源,在 kubectl
命令中使用 --kustomize
或 -k
参数来执行 kubectl apply
,识别被 kustomization.yaml
所管理的资源。 注意 -k
要指向一个 kustomization 目录。例如:
kubectl apply -k <kustomization 目录>/
假定使用下面的 kustomization.yaml
:
# 创建 deployment.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
# 创建 kustomization.yaml
cat <<EOF >./kustomization.yaml
namePrefix: dev-
commonLabels:
app: my-nginx
resources:
- deployment.yaml
EOF
执行下面的命令来应用 Deployment 对象 dev-my-nginx
:
kubectl apply -k ./
运行下面的命令之一来查看 Deployment 对象 dev-my-nginx
:
kubectl get -k ./
kubectl describe -k ./
执行下面的命令来比较 Deployment 对象 与清单被应用之后集群将处于的状态:
kubectl diff -k ./
执行下面的命令删除 Deployment 对象 :
kubectl delete -k ./
kustomize命令
要查看包含 kustomization 文件的目录中的资源,执行下面的命令:
kustomize build $OVERLAYS/staging
执行下面的命令来应用对象:
kustomize build $OVERLAYS/staging |kubectl apply -f -
运行下面的命令之一来查看 Deployment 对象
kustomize build $OVERLAYS/staging |kubectl get -f -
kustomize build $OVERLAYS/staging |kubectl describe -f -
执行下面的命令来比较 Deployment 对象 dev-my-nginx
与清单被应用之后集群将处于的状态:
kustomize build $OVERLAYS/staging |kubectl diff -f -
执行下面的命令删除 Deployment 对象 dev-my-nginx
:
kustomize build $OVERLAYS/staging |kubectl delete -f -
kustomize 官方示例
常见布局大致如下:
├── 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
具体判断。
nginx
# 创建 service.yaml 文件
cat <<EOF > service.yaml
kind: Service
apiVersion: v1
metadata:
name: nginx-service
namespace: csztest-dev
spec:
selector:
run: nginx
ports:
- name: http
port: 80
targetPort: 80
type: NodePort
EOF
# 创建 deployment.yaml 文件
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: csztest-dev
spec:
selector:
matchLabels:
run: nginx
replicas: 1
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
EOF
# 创建 kustomization.yaml
cat <<EOF >./kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
app: nginx
resources:
- deployment.yaml
- service.yaml
EOF
[root@hz-sd-qingzhou-dev2-08 nginx]# kubectl kustomize base
[root@hz-sd-qingzhou-dev2-08 nginx]# kubectl apply -k base
service/nginx-service created
deployment.apps/nginx-deployment created
[root@hz-sd-qingzhou-dev2-08 nginx]# kubectl get -k base
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-service NodePort 10.96.163.186 <none> 80:30132/TCP 7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 7s
# 访问hostip+NodePort,页面正常[Welcome to nginx!](http://10.167.168.156:30132/)
helloworld
Establish the base
这里使用官网的 helloWorld 的 YAML 资源文件作为示例,在 base 目录下新增几个 k8s YAML 资源文件,文件结构如下:
DEMO_HOME=helloWorld
BASE=$DEMO_HOME/base
mkdir -p $BASE
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/helloWorld\
/{configMap,deployment,kustomization,service}.yaml"
注:以下操作命令 目录 均为 [root@hz-sd-qingzhou-dev2-08 helloWorld]
Expect something like:
[root@hz-sd-qingzhou-dev2-08 helloWorld]# tree . ├── base │ ├── configMap.yaml │ ├── deployment.yaml │ ├── kustomization.yaml │ └── service.yaml └── README.md
The Base Kustomization
The base
directory has a kustomization file:
# 修改yaml文件,添加namespace: csztest-dev(按照自己环境要求,注意kustomization.yaml文件中的namespace前面没有缩进,并没有在metadata下 )
[root@hz-sd-qingzhou-dev2-08 helloWorld]# cat base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: arbitrary
namespace: csztest-dev
# Example configuration for the webserver
# at https://github.com/monopole/hello
commonLabels:
app: hello
resources:
- deployment.yaml
- service.yaml
- configMap.yaml
Optionally, run kustomize
on the base to emit customized resources to stdout
:
# 查看kustomize文件资源
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl kustomize base/
One could immediately apply these resources to a cluster:to instantiate the hello service. kubectl
would only recognize the resource files.
# 部署yaml应用
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl apply -k base
configmap/the-map created
service/the-service created
deployment.apps/the-deployment created
# 查看
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl get -k base
NAME DATA AGE
configmap/the-map 2 35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/the-service NodePort 10.96.140.133 <none> 8080:31920/TCP 35s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/the-deployment 3/3 3 3 35s
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p64LBgvl-1662432730080)(C:\Users\shaozhe.cao\AppData\Roaming\Typora\typora-user-images\image-20220830095018227.png)]
Customize the base
A first customization step could be to change the app label applied to all resources:
sed -i.bak 's/app: hello/app: my-hello/' \
$BASE/kustomization.yaml
See the effect:
kustomize build $BASE | grep -C 3 app:
Create Overlays
Create a staging and production overlay:
- Staging enables a risky feature not enabled in production.(修改namespace,namePrefix,configmap中的变量等)
- Production has a higher replica count.(修改namespace,namePrefix,replicas等)
- Web server greetings from these cluster variants will differ from each other.
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
mkdir -p $OVERLAYS/production
[root@hz-sd-qingzhou-dev2-08 helloWorld]# OVERLAYS=./overlays
[root@hz-sd-qingzhou-dev2-08 helloWorld]# mkdir -p $OVERLAYS/production
[root@hz-sd-qingzhou-dev2-08 helloWorld]# mkdir -p $OVERLAYS/staging
Staging Kustomization
In the staging
directory, make a kustomization defining a new name prefix, and some different labels.
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
namePrefix: staging-
namespace: csztest-staging
commonLabels:
variant: staging
org: staging
commonAnnotations:
note: Hello, I am staging!
resources:
- ../../base
patchesStrategicMerge:
- configMap.yaml
EOF
Staging Patch
Add a configMap customization to change the server greeting from Good Morning! to Have a pineapple!
Also, enable the risky flag.
cat <<EOF >$OVERLAYS/staging/configMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: the-map
data:
altGreeting: "Have a pineapple!"
enableRisky: "true"
EOF
Production Kustomization
In the production directory, make a kustomization with a different name prefix and labels.
cat <<EOF >$OVERLAYS/production/kustomization.yaml
namePrefix: production-
namespace: csztest-prod
commonLabels:
variant: production
org: production
commonAnnotations:
note: Hello, I am production!
resources:
- ../../base
patchesStrategicMerge:
- deployment.yaml
EOF
Production Patch
Make a production patch that increases the replica count (because production takes more traffic).
cat <<EOF >$OVERLAYS/production/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
spec:
replicas: 10
EOF
Compare overlays
DEMO_HOME
now contains:
- a base directory - a slightly customized clone of the original configuration, and
- an overlays directory, containing the kustomizations and patches required to create distinct staging and production variants in a cluster.
Review the directory structure and differences:
tree $DEMO_HOME
Expecting something like:
[root@hz-sd-qingzhou-dev2-08 helloWorld]# tree . ├── base │ ├── configMap.yaml │ ├── deployment.yaml │ ├── kustomization.yaml │ └── service.yaml ├── overlays │ ├── production │ │ ├── deployment.yaml │ │ └── kustomization.yaml │ └── staging │ ├── configMap.yaml │ └── kustomization.yaml └── README.md
Compare the output directly to see how staging and production differ:
diff \
<(kustomize build $OVERLAYS/staging) \
<(kustomize build $OVERLAYS/production) |\
more
# 或
diff \
<(kubectl kustomize $OVERLAYS/staging) \
<(kubectl kustomize $OVERLAYS/production) |\
more
The first part of the difference output should look something like
3,4c3,4 < altGreeting: Have a pineapple! < enableRisky: "true" --- > altGreeting: Good Morning! > enableRisky: "false" 8c8 < note: Hello, I am staging! --- > note: Hello, I am production! 11,14c11,14 < org: staging < variant: staging < name: staging-the-map < namespace: csztest-staging --- > org: production > variant: production > name: production-the-map > namespace: csztest-prod 20c20 < note: Hello, I am staging! --- > note: Hello, I am production! 23,26c23,26 < org: staging < variant: staging < name: staging-the-service < namespace: csztest-staging --- > org: production > variant: production > name: production-the-service > namespace: csztest-prod 35,36c35,36 < org: staging < variant: staging --- > org: production > variant: production 43c43 < note: Hello, I am staging! --- > note: Hello, I am production! 46,49c46,49 < org: staging < variant: staging < name: staging-the-deployment < namespace: csztest-staging --- > org: production > variant: production > name: production-the-deployment > namespace: csztest-prod 51c51 < replicas: 3 --- > replicas: 10 56,57c56,57 < org: staging < variant: staging --- > org: production > variant: production 61c61 < note: Hello, I am staging! --- > note: Hello, I am production! 65,66c65,66 < org: staging < variant: staging --- > org: production > variant: production 78c78 < name: staging-the-map --- > name: production-the-map 83c83 < name: staging-the-map --- > name: production-the-map
Deploy
Staging 检查部署
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl kustomize overlays/staging/
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl apply -k overlays/staging/
configmap/staging-the-map created
service/staging-the-service created
deployment.apps/staging-the-deployment created
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl get -k overlays/staging/
NAME DATA AGE
configmap/staging-the-map 2 13s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/staging-the-service NodePort 10.96.122.14 <none> 8080:31689/TCP 13s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/staging-the-deployment 3/3 3 3 13s
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0AeFPi61-1662432730082)(C:\Users\shaozhe.cao\AppData\Roaming\Typora\typora-user-images\image-20220830101621513.png)]
Production检查部署
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl kustomize overlays/production/
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl apply -k overlays/production/
configmap/production-the-map created
service/production-the-service created
deployment.apps/production-the-deployment created
[root@hz-sd-qingzhou-dev2-08 helloWorld]# kubectl get -k overlays/production/
NAME DATA AGE
configmap/production-the-map 2 25s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/production-the-service NodePort 10.96.55.81 <none> 8080:31916/TCP 25s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/production-the-deployment 10/10 10 10 25s
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8uD0sLUO-1662432730083)(C:\Users\shaozhe.cao\AppData\Roaming\Typora\typora-user-images\image-20220830102034040.png)]