An overview,

It is convenient for spring Boot applications to run as containers on top of K8S clusters, but different environments require different configuration files. We can use external configuration centers such as NACOS and Apollo. K8s also provides configMap to decouple the environment configuration information from the container image, making it easy to apply configuration changes. This article mainly introduces how to use K8S configMap as external configuration in Spring Boot from the following aspects:

  • Spring Boot Describes how to load a configuration file

  • This section describes k8S configMap

  • Use k8S configMap as the external configuration file

2. Introduction to spring Boot loading configuration files

When the application starts, Spring Boot automatically finds and loads the application.properties and application.yaml files from the following locations.

The priorities of configuration files are as follows:

  1. File :./config/ – Highest priority (/config subdirectory under the root of the project)

  2. File :./ – Second priority (under project root path)

  3. Classpath :/config/ – priority 3 (resources/config under project)

  4. Classpath :/ – Priority 4 (project resources root directory)

The high-priority configuration overrides the low-priority configuration

Properties will override the application.yaml file if both application.properties and application.yaml files exist in the same directory

If our runtime wants to specify which environment configuration files to run, we can do so in three ways:

  1. Configure Spring.profiles. Active =dev in the application.properties file under the resources folder of the project to specify the environment to load

  2. When starting the JAR, specify –spring.profiles. Active = the environment in which prod loads

  3. Start the jar, specify – spring. Config. Location = target/application. The properties loading configuration file location

Third, k8sconfigMapintroduce

ConfigMap is an API object used to store unconfidential data in key-value pairs. Pod can be used as an environment variable, a command line parameter, or a configuration file in a storage volume.

Note:

ConfigMap does not provide privacy or encryption. If you want to store data that is confidential, use Secret or another third-party tool to keep your data private instead of ConfigMap.

ConfigMap is not designed to store a large amount of data. You cannot store more than one MiB of data in ConfigMap. If you want to store more data than this limit, you can mount a storage volume or use a separate database or file service.

There are several ways to create a configMap:

  1. –from-file Specifies that all files in the directory will be used to create a key-value pair in ConfigMap. The key name is the file name and the value is the contents of the file.

    Kubectl create configmap --from-file=[directory]Copy the code
  2. Create with file (–from-file can be used multiple times, as if specifying the entire directory)

    Kubectl create configmap [configmap name] --from-file=[file] --from-file=[file]Copy the code
  3. Create from literals (the –from-literal argument can be used multiple times)

    Kubectl create configmap [configmap name] --from-literal=[key = value] --from-literal=[key = value]Copy the code

    Example: Create a configMap using literals

     kubectl create configmap myconfigMap --from-literal=env=dev --from-literal=name=test
    Copy the code
    [root@node01 test]# kubectl describe cm myconfigMap
    Name:         myconfigmap
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    env:
    ----
    dev
    name:
    ----
    test
    Events:  <none>
    
    Copy the code
  4. useyamlManifest file creation

    Create a game-demo.yaml file with the following contents:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: game-demo
    data:
      # class attribute key; Each key maps to a simple value
      player_initial_lives: "3"
      ui_properties_file_name: "user-interface.properties"
    
      Class file key, the key name is the file name, the value is the file content
      game.properties: | enemy.types=aliens,monsters player.maximum-lives=5  user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=trueCopy the code

    Create configMap using the following command:

    kubectl apply -f game-demo.yaml
    Copy the code

Iv. Those using K8SconfigMapAs an external configuration file

As you can see from the previous section, the highest priority for spring Boot to load configuration files is the /config subdirectory under the root of the project, so you can mount configuration files from configMap to the Config subdirectory under the root of the project in the container.

  1. You can create one from the file using the following commandconfigMap:
kubectl create configMap  spring-boot-demo  --from-file=application.yaml
Copy the code
  1. To create aspring-boot-demo.yamlThe content of the document is as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-demo
  namespace: default
  labels:
    app: spring-boot-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-demo
  template:
    metadata:
      labels:
        app: spring-boot-demo
    spec:
      containers:
        - name: spring-boot-demo
          image: ${ORIGIN_REPO}/spring-boot-demo:${IMAGE_TAG}
          imagePullPolicy: Always
          env:
            - name: TZ
              value: Asia/Shanghai
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 200m
              memory: 500Mi
          /app/config = /app/ jar = /app/ jar = /app
          volumeMounts:
            - mountPath: /app/config
              name: config
      imagePullSecrets:
        - name: docker-password
      volumes:
        - configMap:
        	# specify the name of the configMap we created
            name: spring-boot-demo
          Volumemounts.name = volumemounts.name
          name: config

---
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo
  namespace: default
  labels:
    app: spring-boot-demo
spec:
  ports:
    - name: port
      port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: spring-boot-demo
  type: ClusterIP

Copy the code
  1. Create the deployment with the configuration mounted using the following command:
kubectl apply -f spring-boot-demo.yaml
Copy the code
  1. Use the following command to enter the container to verify that it is mounted to the configured directory:
# to check the pod
kubectl get pod -n default
# Enter container
kubectl exec -it spring-boot-demo-76bd6c8857-kwss6  bash

Copy the code

V. MountedconfigMapThe content is automatically updated

When the configMap used in the volume is updated, the projected keys are eventually updated as well. The Kubelet component checks whether the configMap mounted is up to date at each periodic synchronization. However, Kubelet uses its local cache to get the current value of configMap. The type of caching can configure by ConfigMapAndSecretChangeDetectionStrategy KubeletConfiguration structure field.

ConfigMap allows content propagation through watch operations (the default), TTL-based caching, and direct redirection to the API server through all requests. Thus, the time span from the time the configMap is updated to the time the new primary key is projected into the Pod may be equal to kubelet’s synchronization cycle plus the propagation delay of the cache. The propagation delay here depends on the selected cache type (corresponding to the propagation delay of the watch operation, the TTL of the cache, or 0, respectively).

Used as an environment variableconfigMapData is not automatically updated, and updating this data requires a Pod restart.

Reference Documents:

K8s website

Spring boot website