侧边栏壁纸
博主头像
背锅小王子博主等级

我从事运维工作有十年之久,主要从事云原生相关的工作,对k8s、devops、servicemesh、可观察性等较为熟悉!

  • 累计撰写 59 篇文章
  • 累计创建 64 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Kustomize企业实战教程(一)

背锅小王子
2023-04-02 / 0 评论 / 1 点赞 / 591 阅读 / 3,331 字
温馨提示:
本文最后更新于 2023-04-03,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1、介绍

Kustomize 允许您为多种用途定制原始的、无模板的 YAML 文件,保持原始 YAML 不变,提供了一种无需模板和 DSL 即可自定义 Kubernetes 资源配置的解决方案,包含了许多方便的方法,例如生成器,使定制更容易。

2、安装

下载kustomize

wget https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.0.1/kustomize_v5.0.1_linux_amd64.tar.gz

tar xf kustomize_v5.0.1_linux_amd64.tar.gz

mv kustomize /usr/local/bin/

查看kustomize版本

kustomize version

图片-1680434001358

另外:从 k8s 的 1.14 版本开始,kubectl 也开始支持使用 kustomization 文件来管理 Kubernetes 对象,具体的对应关系如下:

Kubectl 版本 kustomize版本
< v1.14 不适用
v1.14-v1.20 v2.0.3
v1.21 v4.0.5
v1.22 v4.2.0
v1.24 v4.5.4

要查看自己的kubectl自带的版本,可以使用这个命令

kubectl version --short --client

图片-1680433519702

使用kustomize来部署应用,可以使用如下命令:

kustomize build folder | kubectl apply -f -

使用kubectl来部署kustomize应用,可以使用如下命令:

kubectl apply -k folder

3、功能特性

命令 说明 备注
namespace 为所有资源添加统一命名空间
namePrefix 为所有资源的name添加统一前缀
nameSuffix 为所有资源的name添加统一后缀
commonLabels 为所有资源添加统一标签
commonAnnotations 为所有资源添加统一注解
configMapGenerator 用于生成configmap配置
secretGenerator 用于生成secret配置
images 修改镜像信息
replicas 修改副本数
labels 为所有资源添加标签和可选的选择器
resources 设置资源的执行顺序
generatorOptions 为configMapGenerator/secretGenerator添加属性,例如labels、 annotations等
helmCharts 部署helm chat资源
patchesStrategicMerge 定义策略性合并补丁 该字段在 v5.0.0 中已弃用,推荐使用patches替代
patchesJson6902 定义JSON 补丁 该字段在 v5.0.0 中已弃用,推荐使用patches替代
patches 通过补丁来添加或覆盖资源上的字段
vars vars 用于从一个资源的字段中捕获文本并将该文本插入到其他地方 - 一种反射功能 该字段在 v5.0.0 中已弃用,推荐使用replacements替代
replacements 用来替换源中的字段
crds 添加 CRD 支持

说明:在Kustomize的5.0.0版本已弃用的命令,不在本次测试的范围中,如果你还有使用,也建议升级到最新版本,可以运行 kustomize edit fix 以自动转换为相应的命令

4、实践

设置贯穿性字段

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

  • 为所有资源设置相同的名字空间 namespace
  • 为所有对象添加相同的前缀 namePrefix 或后缀 nameSuffix
  • 为对象添加相同的标签集合 commonLabels
  • 为对象添加相同的注解集合 commonAnnotations

namespace、namePrefix、nameSuffix、commonLabels、commonAnnotations

创建一个测试cm-svc.yml文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cm
data:
  key: YWJjZA==
---
apiVersion: v1
kind: Service
metadata:
  name: test-svc
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx

创建kustomization.yaml

namespace: wwdz
namePrefix: start-
nameSuffix: -end
commonLabels: 
  app: add-label
commonAnnotations:
  app: add-annotation
  
resources:
- cm-svc.yml

执行命令,kustomize build,输出结果如下,说明字段信息已添加成功

apiVersion: v1
data:
  key: YWJjZA==
kind: ConfigMap
metadata:
  annotations:
    app: add-annotation
  labels:
    app: add-label
  name: start-test-cm-end
  namespace: wwdz
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    app: add-annotation
  labels:
    app: add-label
  name: start-test-svc-end
  namespace: wwdz
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: add-label

images

创建一个nginx.yml文件,用来测试修改镜像Tag

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:alpine

修改 kustomization.yaml 文件如下:

namespace: wwdz

images:
- name: nginx
  # 设置镜像tag
  newTag: 1.23-alpine
  
resources:
- nginx.yml

执行命令,kustomize build,输出结果为如下,说明字段信息已修改成功

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: wwdz
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # 镜像tag已经更新
      - image: nginx:1.23-alpine
        name: nginx

测试修改镜像,修改kustomization.yaml 文件如下:

namespace: wwdz

images:
- name: nginx
  # 设置镜像名称
  newName: busybox
  newTag: latest
  
resources:
- nginx.yml

执行命令,kustomize build,输出结果为如下,说明字段信息已修改成功

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: wwdz
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # 镜像已经更新
      - image:  busybox:latest
        name: nginx

replicas

修改kustomization.yaml 文件如下:

namespace: wwdz

# 设置副本数
replicas:
- name: nginx
  count: 2
  
images:
- name: nginx
  # 设置镜像tag
  newTag: 1.23-alpine
  
resources:
- nginx.yml

执行命令,kustomize build,输出结果为如下,说明字段信息已修改成功

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: wwdz
spec:
  # 副本已经更新
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # 镜像tag已经更新
      - image: nginx:1.23-alpine
        name: nginx

configMapGenerator

configMapGenerator支持从file、env file、literals来生成相应的configmap

创建 application.yaml 和 application.env,用来测试上面三种方式创建configmap

# application.yaml
a: 123
b: 456
# application.env
aaa=123456
bbb=654321

修改kustomization.yaml 文件如下:

namespace: wwdz

configMapGenerator:
- name: test-configmap-1
  files:
  - application.yaml

- name: test-configmap-2
  envs:
  - application.env

# 说明:键 / 值用符号分隔 =
- name: test-configmap-3
  literals:
  - ak=123
  - sk=456

执行命令,kustomize build,输出结果为如下,说明字段信息已添加成功

apiVersion: v1
data:
  application.yaml: |
    a: 123456
    b: 456
kind: ConfigMap
metadata:
  name: test-configmap-1-dh8hb6c9bm
  namespace: wwdz
---
apiVersion: v1
data:
  bbb: 654321fajlfajl
  ccc: "82381038"
kind: ConfigMap
metadata:
  name: test-configmap-2-m7d27g2gkh
  namespace: wwdz
---
apiVersion: v1
data:
  ak: "123"
  sk: "456"
kind: ConfigMap
metadata:
  name: test-configmap-3-d6g29t879d
  namespace: wwdz

通过上面几个生成configmap的例子,你可能已经发现,每次生成的configmap的name都和我们自己定义的不符,而且都是在后面添加了一段随机的字符串,这是为了安全起见,避免误操作导致更新,但是这样的方式,明显无法满足企业的需求,因此可以使用options 或者 generatorOptions 来覆盖默认的参数

  • options:只对在 options 中添加了 disableNameSuffixHash: true 的资源有效

  • generatorOptions:在 generatorOptions 中添加了 disableNameSuffixHash: true 则对所有的资源有效

测试 options 参数:

namespace: wwdz

configMapGenerator:
- name: test-configmap-1
  literals:
  - ak=123
  - sk=456

- name: test-configmap-2
  files:
  - application.yaml
  options:
    disableNameSuffixHash: true

执行命令,kustomize build,输出结果为如下:

apiVersion: v1
data:
  ak: "123"
  sk: "456"
kind: ConfigMap
metadata:
  name: test-configmap-1-d6g29t879d
  namespace: wwdz
---
apiVersion: v1
data:
  application.yaml: |
    a: 123
    b: 456
kind: ConfigMap
metadata:
  name: test-configmap-2
  namespace: wwdz

测试 generatorOptions 参数:

namespace: wwdz

generatorOptions:
  disableNameSuffixHash: true

configMapGenerator:
- name: test-configmap-1
  literals:
  - ak=123
  - sk=456
- name: test-configmap-2
  files:
  - application.yaml

执行命令,kustomize build,输出结果为如下:

apiVersion: v1
data:
  ak: "123"
  sk: "456"
kind: ConfigMap
metadata:
  name: test-configmap-1
  namespace: wwdz
---
apiVersion: v1
data:
  application.yaml: |
    a: 123
    b: 456
kind: ConfigMap
metadata:
  name: test-configmap-2
  namespace: wwdz

另外每个 configMapGenerator 项都接受一个参数 behavior: [create|replace|merge]。这允许覆盖修改或替换来自父级的现有 configMap,默认使用的是create。

创建一个configmap文件,cm.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cm
data:
  a: b
  c: d

测试behavior的merge功能,只会替换父级指定key的value,其他父级key和value会自动继承

namespace: wwdz

generatorOptions:
  disableNameSuffixHash: true

configMapGenerator:
- name: test-configmap
  literals:
  - ak=123
  - sk=456
- name: test-cm
  behavior: merge
  literals:
  - a=123

resources:
- cm.yml

执行命令,kustomize build,输出结果为如下,说明字段信息已修改成功

apiVersion: v1
data:
  a: "123"
  c: d
kind: ConfigMap
metadata:
  name: test-cm
  namespace: wwdz
---
apiVersion: v1
data:
  ak: "123"
  sk: "456"
kind: ConfigMap
metadata:
  name: test-configmap
  namespace: wwdz

测试 behavior 的 replace 功能,会替换掉父级的这个key的value值,其他父级的key和value都会被丢弃

namespace: wwdz

generatorOptions:
  disableNameSuffixHash: true

configMapGenerator:
- name: test-configmap
  literals:
  - ak=123
  - sk=456
- name: test-cm
  behavior: merge
  literals:
  - a=123

resources:
- cm.yml

执行命令,kustomize build,输出结果为如下,说明字段信息已修改成功

apiVersion: v1
data:
  a: "123"
kind: ConfigMap
metadata:
  name: test-cm
  namespace: wwdz
---
apiVersion: v1
data:
  ak: "123"
  sk: "456"
kind: ConfigMap
metadata:
  name: test-configmap
  namespace: wwdz

测试configMapGenerator中内容的增、删、改

namespace: wwdz

generatorOptions:
  disableNameSuffixHash: true

configMapGenerator:
- name: test-configmap
  literals:
  # 删除
  #- ak=123
  # 修改
  - sk=456789
  # 新增
  - key=123

执行命令,kustomize build,输出结果为如下,说明字段信息已应用成功

apiVersion: v1
data:
  key: "123"
  sk: "456789"
kind: ConfigMap
metadata:
  name: test-configmap
  namespace: wwdz

secretGenerator

secretGenerator与configMapGenerator的配置类似

创建一个configmap文件

namespace: wwdz

generatorOptions:
  disableNameSuffixHash: true

secretGenerator:
- name: app-tls
  files:
  - tls.crt
  - tls.key
  type: "kubernetes.io/tls"
- name: env_file_secret
  envs:
  - application.env
  type: Opaque
- name: secret-with-annotation
  files:
  - application.yaml
  type: Opaque
  options:
    annotations:
      app_config: "true"
    labels:
      app.kubernetes.io/name: "app"

执行命令,kustomize build,输出结果为如下,说明字段信息已应用成功

apiVersion: v1
data:
  tls.crt: TFMwdExTMUNSVWQuLi50Q2c9PQo=
  tls.key: TFMwdExTMUNSVWQuLi4wdExRbz0K
kind: Secret
metadata:
  name: app-tls
  namespace: wwdz
type: kubernetes.io/tls
---
apiVersion: v1
data:
  aaa: MTIzNDU2
  bbb: NjU0MzIx
kind: Secret
metadata:
  name: env_file_secret
  namespace: wwdz
type: Opaque
---
apiVersion: v1
data:
  application.yaml: YTogMTIzNDU2CmI6IDQ1Ngo=
kind: Secret
metadata:
  annotations:
    app_config: "true"
  labels:
    app.kubernetes.io/name: app
  name: secret-with-annotation
  namespace: wwdz
type: Opaque

说明:secretGenerator与configMapGenerator的增、删、改类似,可以参考configMapGenerator配置

patches

patches可以是 strategic merge 补丁或者 JSON6902 补丁,可以是文件,也可以是内联字符串,针对单个资源或多个资源

使用内联战略合并打补丁

Json6902支持以下几个方法:

  • add: 添加新的路径
  • replace:使用新值替换旧值
  • copy:复制指定值到目标路径
  • move:移除节点
  • remove:移除特定路径
  • test:测试路径

创建的nginx测试应用

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:
        - name: nginx
          image: nginx:alpine

修改 kustomization.yaml 配置如下:

namespace: wwdz

resources:
- nginx.yml

patches:
  - patch: |-
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
        labels:
          app: 1.21.0      
  - patch: |-
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
      spec:
        template:
          spec:
            containers:
              - name: nginx
                image: nginx:1.21.0      

使用内联 JSON6902 的补丁

使用前面创建的nginx文件,然后修改 kustomization.yaml 配置如下:

namespace: wwdz

resources:
- nginx.yml

patches:
  - patch: |-
      - op: add
        path: /metadata/labels/app
        value: 1.21.0
    target:
      group: apps
      version: v1
      kind: Deployment
  - patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/image
        value: nginx:1.21.0
    target:
      labelSelector: "app=nginx"   

使用 Path Strategic Merge 打补丁

修改 kustomization.yaml 文件如下:

namespace: wwdz

resources:
- nginx.yml

patches:
  - path: add-label.patch.yaml
  - path: fix-version.patch.yaml
    target:
      labelSelector: "app=nginx"

创建add-label.patch.yaml和fix-version.patch.yaml文件

# add-label.patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: 1.21.0
# fix-version.patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
    spec:
      containers:
        - name: nginx
          image: nginx:1.21.0

使用JSON6902方式来打补丁,target 字段是必填字段

修改 kustomization.yaml 文件如下:

resources:
- nginx.yml
patches:
  - path: add-label.patch.yaml
  - path: fix-version.patch.yaml
    target:
      labelSelector: "app=nginx"
# add-label.patch.json
[
  {"op": "add", "path": "/metadata/labels/app", "value": "1.21.0"}
]
# fix-version.patch.yaml
- op: replace
  path: /spec/template/spec/containers/0/image
  value: nginx:1.21.0

执行命令,kustomize build,以上所有方式的执行结果都如下,说明字段信息已应用成功

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: 1.21.0
  name: nginx
  namespace: wwdz
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.21.0
        name: nginx

说明:JSON6902 补丁必须包含target 字段,其中的一个特殊字符 / 可以使用 ~1 来替换

replacements

常用字典如下:

  • source:源字段是一个选择器,它通过查找与指定 GVKNN 的匹配来确定值的来源的所有子字段source都是可选的,但源选择必须解析为单个资源
  • target:替换将应用于与该select字段匹配且与该字段不匹配的所有目标reject,并将应用于所有列出的fieldPaths
  • reject:reject 字段是一个选择器,丢弃由 select 选择的目标
  • delimiter:该字段旨在与用于部分字符串替换的字段结合 index 使用
  • index:该字段旨在与 delimiter 字段结合使用以进行部分字符串替换。默认值为 0
  • Field Path format:fieldPath 和 fieldPaths 字段支持以“.”分隔的值路径格式

replacements支持的格式参数如下:

replacements:
- source:
    group: string
    version: string
    kind: string
    name: string
    namespace: string
    fieldPath: string
    options:
      delimiter: string
      index: int
      create: bool
  targets:
  - select:
      group: string
      version: string
      kind: string
      name: string
      namespace: string
    reject:
    - group: string
      version: string
      kind: string
      name: string
      namespace: string
    fieldPaths:
    - string
    options:
      delimiter: string
      index: int
      create: bool

创建测试资源:

apiVersion: v1
data:
  AK: 123
kind: ConfigMap
metadata:
  name: test-cm
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - image: busybox
    name: busybox
  restartPolicy: OnFailure

修改 kustomization.yaml 文件如下:

namespace: wwdz

resources:
- cm.yml
- pod.yml
- nginx.yml

replacements:
- path: replacement.yaml
- source:
    kind: ConfigMap
    name: test-cm
  targets:
  - select:
      name: nginx
      kind: Deployment
    fieldPaths:
    - spec.template.spec.containers.[name=nginx].env.[name=AK].value

执行命令,kustomize build,执行结果都如下,说明字段信息已应用成功

apiVersion: v1
data:
  AK: 123
kind: ConfigMap
metadata:
  name: test-cm
  namespace: wwdz
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: wwdz
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - env:
        - name: AK
          value: test-cm
        image: nginx:alpine
        name: nginx
      restartPolicy: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: wwdz
spec:
  containers:
  - image: busybox
    name: busybox
  restartPolicy: OnFailure
1

评论区