Kustomize

Kustomize

参考文档

  1. 使用 Kustomize 对 Kubernetes 对象进行声明式管理 | Kubernetes
  2. kubernetes-sigs/kustomize: Customization of kubernetes YAML configurations (github.com)
  3. Kustomize - Kubernetes native configuration management
  4. 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 提供 secretGeneratorconfigMapGenerator,可以基于文件或字面值来生成 Secret 和 ConfigMap。

configMapGenerator
files

要基于文件来生成 ConfigMap,可以在 configMapGeneratorfiles 列表中添加表项。 下面是一个根据 .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, 在 configMapGeneratorliterals 列表中添加表项。下面是一个例子, 展示如何使用键值偶对中的数据条目来生成 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,先要在 secretGeneratorliterals 列表中添加表项。下面是基于键值偶对中数据条目来生成 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 通过 patchesStrategicMergepatchesJson6902 支持不同的打补丁机制。

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 文件中添加 namePrefixnameSuffix 时 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 功能特性列表

字段类型解释
namespacestring为所有资源添加名字空间
namePrefixstring此字段的值将被添加到所有资源名称前面
nameSuffixstring此字段的值将被添加到所有资源名称后面
commonLabelsmap[string]string要添加到所有资源和选择算符的标签
commonAnnotationsmap[string]string要添加到所有资源的注解
resources[]string列表中的每个条目都必须能够解析为现有的资源配置文件
configMapGenerator[]ConfigMapArgs列表中的每个条目都会生成一个 ConfigMap
secretGenerator[]SecretArgs列表中的每个条目都会生成一个 Secret
generatorOptionsGeneratorOptions更改所有 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 versionKustomize version
< v1.14n/a
v1.14-v1.20v2.0.3
v1.21v4.0.5
v1.22v4.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

devprod 以及 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)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值