Kustomize is a tool designed to solve K8S YAML application management problems. Kubectl has integrated Kustomize since version 1.14. Before that, we had to install Kustomize ourselves. You can download the corresponding OS package from Github (github.com/kubernetes-…) to install the OS. .

On Windows, it is an EXE file, which can be used on the command line by placing it in a directory and adding environment variables.

$kustomize version {version: kustomize/v3.5.2 GitCommit: 79 a891f4881cfc780e77789a1d240d8f4bfa2598 BuildDate:2019-12-17T03:48:17Z GoOs:windows GoArch:amd64}Copy the code

Ok, going back to K8S, when we deploy, will we use a lot of Kubernetes objects to describe our service? For example, deployment, ingress, service, configMap, secret, and so on. This is all configured using yamL files. A typical deployment.yaml file might look something like this

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: smcp-service
  namespace: smcp-dev
spec:
  selector:
    matchLabels:
      app: smcp-service
  replicas: 1
  template:
    metadata:
      labels:
        app: smcp-service
    spec:
      containers:
        - name: smcp-service
          image: harbor.xxx.com/example/smcp-web:1.0
          imagePullPolicy: Always
          livenessProbe:
            httpGet:
              path: /api/anon/health
              port: 9000
            initialDelaySeconds: 80
            periodSeconds: 20
            timeoutSeconds: 2
          readinessProbe:
            httpGet:
              path: /api/anon/health
              port: 9000
            initialDelaySeconds: 90
            timeoutSeconds: 2
          ports:
            - containerPort: 9000
          envFrom:
            - configMapRef:
                name: smcp-config
            - secretRef:
                name: smcp-service-secret

Copy the code

For example, when we deploy the Springboot application to dev, we can see that namespace is smcp-dev. However, when we deploy to other environments, such as beta,staging,production, it means that we need to copy all the files mentioned above. Then modify the minor variables (namespace, Replica,image, etc.).

Also, when the contents of our environment variables are updated, the Deployment does not roll over because their names are unchanged (smcp-config,smcp-service-secret).

We put the contents of the application.properties file into the environment variable using configMap.

Kustomize came along to solve our problem. It lays out the common part as the base, or base layer, and then overlays the content of the base on overlays, somewhat similar to the concept of docker image layer. But base was insensitive to overlays. The resulting directory structure looks like this

$ tree . |-- base | |-- deployment.yaml | |-- ingress.yaml | |-- kustomization.yaml | `-- service.yaml `-- overlays |-- devlopment | |-- cert | | |-- tls.crt | | `-- tls.key | |-- config.properties | |-- ingress-patch.yaml | |-- kustomization.yaml | `-- secret.properties `-- production |-- cert | |-- tls.crt | `-- tls.key |-- config.properties |--  ingress-patch.yaml |-- kustomization.yaml `-- secret.properties 6 directories, 16 filesCopy the code

The base/kustomization.yaml file introduces only a few other files, and its YAMl file reads as follows

resources:
- deployment.yaml
- ingress.yaml
- service.yaml
Copy the code

Yaml or service.yaml files only define deployment objects and service objects. For some parameters that need to be specified in different environments, such as namespace,replicas, you can set a default value first. And then edit it in overlays.

Kustomize create generates kustomization.yaml files

While in overlays can see us in overlays folder placed two environment configuration, are stored in the environment that is both unique configuration (config. The properties, secret. Properteis), and kustomizatiion. This is in yaml files With some changes to the contents of the template file (base), let’s look at the configuration in the Development environment

resources:
- . /.. /base

# set the namespace
namespace: smcp-example-dev


replicas:
- name: smcp-service
  count: 2

# set configMap
configMapGenerator:
- name: smcp-config
  files:
  - config.properties

# set the secret
secretGenerator:
- name: smcp-service-secret
  envs:
  - secret.properties
- name: smcp-service-cert
  files:
  - cert/tls.crt
  - cert/tls.key
  type: kubernetes.io/tls

The value of group/version is equal to the value of apiVersion in ingress.yaml
patchesJson6902:
- target:
    group: extensions
    version: v1beta1
    kind: Ingress
    name: smcp-service-ingress
  path: ingress-patch.yaml

# Set the mirroring version
images:
- name: harbor.xxx.com/example/smcp-web
  newTag: 0.10. 0-test
Copy the code

The ingress-patch.yaml file contains the following information:

- op: replace
  path: /spec/tls/0/hosts/0
  value: test.example.com

- op: replace
  path: /spec/rules/0/host
  value: test.example.com

Copy the code

Kustomize documentation address: github.com/kubernetes-…

Finally when we execute kustomize Build overlays/devlopment the newly generated API object (Deployment,ingress, etc.) will replace the values in the template as we set them.

The newly generated Deployment object is as follows

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: smcp-service
  namespace: smcp-example-dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: smcp-service
  template:
    metadata:
      labels:
        app: smcp-service
    spec:
      containers:
      - envFrom:
        - configMapRef:
            name: smcp-config-f5thmfmkb6
        - secretRef:
            name: smcp-service-secret-66m2658btb
        image: harbor.xxx.com/example/smcp-web:0.10.0-test
        imagePullPolicy: Always
        livenessProbe:
          httpGet:
            path: /api/anon/health
            port: 9000
          initialDelaySeconds: 80
          periodSeconds: 20
          timeoutSeconds: 2
        name: smcp-service
        ports:
        - containerPort: 9000
        readinessProbe:
          httpGet:
            path: /api/anon/health
            port: 9000
          initialDelaySeconds: 90
          timeoutSeconds: 2
Copy the code

You can see that compared to deployment.yaml in base, Replicas becomes 2 and namespace becomes smcp-example-dev,configMap, and secret. This is ${name}-hash, and everything is modified according to the configuration of kustomization.yaml.

Also, rolling updates can now be triggered whenever configMap and Secret are updated (rolling updates can only be triggered in deployment if the contents of the spec. Spec are updated).

Can be used with kubectl command: kustomize build overlays/devlopment | kubectl apply – f –

At this point, we are done with kustomization. With kustomization, we can quickly deploy a system to another environment and change the base configuration only once, instead of having to change it in different environments.