原文链接:https://www.cpweb.top/2504 |
---|
官方文档:
https://kubernetes.io/zh-cn/docs/tasks/manage-kubernetes-objects/kustomization/ https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/
https://github.com/kubernetes-sigs/kustomize
Kustomize 是一个独立的工具,用来通过 kustomization 文件定制 Kubernetes 资源对象配置。它提供了一种无需模板和 DSL(领域特定语言) 即可自定义 Kubernetes 资源对象配置的解决方案。
它提供以下功能特性来管理应用配置文件:
Kustomize 中有基准(bases)和覆盖(overlays)的概念区分。
基准是包含 kustomization.yaml 文件的一个目录,其中包含一组资源及其相关的定制。 基准可以是本地目录或者来自远程仓库的目录,只要其中存在 kustomization.yaml 文件即可。 覆盖也是一个目录,其中包含将其他 kustomization 目录当做 bases 来引用的 kustomization.yaml 文件。
基准不了解覆盖的存在,且可被多个覆盖所使用。 覆盖则可以有多个基准,且可针对所有基准中的资源执行组织操作,还可以在其上执行定制。
所以我们通常使用 base + overlays 的结构来管理 yaml 文件。base 中包含基准 yaml 文件,overlays 中则是继承 base 的 yaml 并向其中加入定制元素进行修改,已适应于不同的环境。
结构如下:
nginx-kustomize
├── base # 基准文件
│ ├── kustomization.yaml
│ └── nginx-deploy.yaml
└── overlays
├── development # 开发环境
│ ├── kustomization.yaml
│ ├── ns.yaml
│ ├── path_env.yaml
│ └── path_nginx-ing.yaml
└── production # 生产环境
├── kustomization.yaml
├── ns.yaml
├── path_env.yaml
└── path_nginx-ing.yaml
以上述结构做为示例,简单演示下。
定义 kustomization.yaml,指定要包含那些文件做为基准 yaml 文件。
[root@cp nginx-kustomize]# cat base/kustomization.yaml
resources:
- nginx-deploy.yaml
注:
resources:要包括的资源,资源可以是文件、目录、URL。
资源将按深度优先顺序读取和处理。
文件应包含 YAML 形式的 k8s 资源,一个文件可能包含由文档标记分隔的多个资源---。
目录规范可以是相对的、绝对的或 URL 的一部分,目录必须包含一个 kustomization.yaml 文件。
URL 规范应遵循 hashcorp URL 格式。
nginx 部署文件,包含 svc、ing、deploy:
[root@cp nginx-kustomize]# cat base/nginx-deploy.yaml
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: nginx
name: nginx
spec:
type: ClusterIP
selector:
k8s-app: nginx
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
spec:
rules:
- host: dev.nginx.example
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.18
ports:
- containerPort: 80
env:
- name: ENV
value: "dev"
以 production 为例,要在生产环境部署,我们要在基准文件上定制如下:
创建 kustomization.yml 文件以定义生产环境:
[root@cp nginx-kustomize]# cat overlays/production/kustomization.yaml
resources: # 包含的资源
- ../../base
- ns.yaml
patchesStrategicMerge: # 策略合并补丁
- patch_nginx-ing.yaml
- patch_env.yaml
namespace: nginx-prod # 为所有资源设置命名空间
replicas: # 配置资源副本数
- name: nginx
count: 2
images: # 设置镜像
- name: nginx
newName: nginx
newTag: 1.20
注:
1、patchesStrategicMerge
注意,只用于修改已知资源。
即此条目下的文件中的 name 必须和 resources 加载的 name 字段匹配,或者通过 bases 中的 name 字段匹配。
2、namespace
为所有资源设置相同的名字空间。
如果在资源上设置了现有 namespace,则将覆盖现有 namespace。
如果在资源上未设置现有 namespace,则使用现有 namespace。
3、replicas
修改资源的副本数。该字段内容为列表,所以可以同时修改许多资源。
只能作用于:Deployment、ReplicationController、ReplicaSet、StatefulSet
4、images
修改镜像的名称、tag 或 image digest。
如果一个资源对象下面定义了多个镜像,则所有镜像都会被改变。
其它文件:
[root@cp nginx-kustomize]# cat overlays/production/ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: nginx-prod
[root@cp nginx-kustomize]# cat overlays/production/path_env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ENV
value: "prod"
[root@cp nginx-kustomize]# cat overlays/production/path_nginx-ing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
spec:
rules:
- host: prod.nginx.example
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
下面我们来部署生产环境:
# 检查,会定制化生成 yaml 到标准输出
kubectl kustomize overlays/production/
# 部署
kubectl apply -k overlays/production/
验证:
[root@cp nginx-kustomize]# kubectl get deploy,svc,ing -n nginx-prod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 2/2 2 2 41s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx ClusterIP 10.1.89.78 <none> 80/TCP 41s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/nginx <none> prod.nginx.example 80 41s
[root@cp nginx-kustomize]# kubectl describe deploy -n nginx-prod nginx | grep Image
Image: nginx:1.20
[root@cp nginx-kustomize]# kubectl exec -n nginx-prod nginx-5cbc6c98f6-24r9h -- env | grep ENV
ENV=prod
官方给了不少示例:https://github.com/kubernetes-sigs/kustomize/tree/master/examples
官方文档:https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/
target 字段通过对象的组、版本、种类、名称和命名空间来筛选需要 patch 的资源对象。
path 字段是 JSON 补丁文件的相对文件路径。此补丁文件中的内容可以是 JSON 格式
patchesJson6902:
- target:
group: >
version: >
kind: >
name: >
namespace: >
labelSelector: >
annotationSelector: >
path: >
patch: -|
示例:
patches:
- target:
group: apps
version: v1
kind: Deployment
name: deploy.*
labelSelector: "env=dev"
annotationSelector: "zone=west"
path: patch.yaml
- target:
kind: MyKind
labelSelector: "env=dev"
patch: |-
- op: replace
path: /some/existing/path
value: new value
如果单个资源对象下有多个容器,对于不同容器镜像怎么在 kustomization.yaml 文件中设置,使用 images 肯定是不行的,它会修改所有镜像。这种情况下,我们可能会想到用 patchesStrategicMerge,但是我们需要额外定义文件。
这种情况使用 patchesJson6902 可以达成我们想要的效果,如下示例将 nginx1 容器镜像版本改成 1.20,将 nginx2 容器镜像版本改成 1.18。
示例 Deployment:
[root@cp test-kustomize]# cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx1
image: nginx:1.18
- name: nginx2
image: nginx:1.20
kustomization.yaml:
[root@cp test-kustomize]# cat kustomization.yaml
resources:
- nginx-deploy.yaml
patchesJson6902:
- target: # 匹配名为 nginx 的 Deployment
kind: Deployment
name: nginx
patch: |-
- op: replace
path: /spec/template/spec/containers/0/image
value: nginx:1.20
- op: replace
path: /spec/template/spec/containers/1/image
value: nginx:1.18
验证:
[root@cp test-kustomize]# kubectl kustomize .
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.20
name: nginx1
- image: nginx:1.18
name: nginx2
目前有两个微服务,现在要上生产,需要批量修改相关变量:
示例 Deployment:
[root@cp test-kustomize]# cat auth-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth
labels:
app: auth
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- name: auth
image: auth
env:
- name: JVM_OPTS
value: -Xms512m -Xmx512m
- name: JAVA_OPTS
value: --spring.profiles.active=dev
[root@cp test-kustomize]# cat admin-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: admin
labels:
app: admin
spec:
replicas: 1
selector:
matchLabels:
app: admin
template:
metadata:
labels:
app: admin
spec:
containers:
- name: admin
image: admin
env:
- name: JVM_OPTS
value: -Xms512m -Xmx512m
- name: JAVA_OPTS
value: --spring.profiles.active=dev
kustomization.yaml:
[root@cp test-kustomize]# cat kustomization.yaml
resources:
- auth-deploy.yaml
- admin-deploy.yaml
patchesJson6902:
- target: # 匹配所有类型为 Deployment 的资源
kind: Deployment
name: .*
patch: |-
- op: replace
path: /spec/template/spec/containers/0/env/0/value
value: -Xms1024m -Xmx1024m
- op: replace
path: /spec/template/spec/containers/0/env/1/value
value: --spring.profiles.active=prod
- op: add
path: /spec/template/spec/containers/0/env/-
value: {"name":"ENV","value":"prod"}
验证:
[root@cp test-kustomize]# kubectl kustomize .
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: admin
name: admin
spec:
replicas: 1
selector:
matchLabels:
app: admin
template:
metadata:
labels:
app: admin
spec:
containers:
- env:
- name: JVM_OPTS
value: -Xms1024m -Xmx1024m
- name: JAVA_OPTS
value: --spring.profiles.active=prod
- name: ENV
value: prod
image: admin
name: admin
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: auth
name: auth
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- env:
- name: JVM_OPTS
value: -Xms1024m -Xmx1024m
- name: JAVA_OPTS
value: --spring.profiles.active=prod
- name: ENV
value: prod
image: auth
name: auth
以上例的两个微服务为例,给它们添加一个 nginx 容器:
方式1:
[root@cp test-kustomize]# cat kustomization.yaml
resources:
- auth-deploy.yaml
- admin-deploy.yaml
patchesJson6902:
- target:
kind: Deployment
name: .*
patch: |-
- op: add
path: /spec/template/spec/containers/-
value: {"name":"nginx","image":"nginx:1.20"}
[root@cp test-kustomize]# kubectl kustomize .
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: auth
name: auth
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- env:
- name: JVM_OPTS
value: -Xms512m -Xmx512m
- name: JAVA_OPTS
value: --spring.profiles.active=dev
image: auth
name: auth
- image: nginx:1.20
name: nginx
......
方式2,注意使用此方式添加容器,会将添加的容器排列在第一位:
[root@cp test-kustomize]# cat kustomization.yaml
resources:
- auth-deploy.yaml
- admin-deploy.yaml
patches:
- target:
kind: Deployment
name: .*
path: add_nginx_container.yaml
[root@cp test-kustomize]# cat add_nginx_container.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: add-nginx-container # 这个名称无所谓,会作用到所有 Deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.20
[root@cp test-kustomize]# kubectl kustomize .
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: admin
name: admin
spec:
replicas: 1
selector:
matchLabels:
app: admin
template:
metadata:
labels:
app: admin
spec:
containers:
- image: nginx:1.20
name: nginx
- env:
- name: JVM_OPTS
value: -Xms512m -Xmx512m
- name: JAVA_OPTS
value: --spring.profiles.active=dev
image: admin
name: admin