First, ☀️ overview

Spring Boot applications running as containers on a K8S cluster are very convenient, but different environments require different configuration files. We can use external configuration centers such as NACOS and Apollo. K8s also provides ConfigMap to decouple environment configuration information from container images for easy modification of application configuration. This paper mainly introduces how Spring Boot uses K8S ConfigMap as the external configuration:

  • spring bootLoading configuration file introductions
  • k8sconfigMapintroduce
  • usek8sconfigMapAs an external configuration file

☀️ Spring Boot load configuration file introduction

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

The priority of the configuration file is as follows:

  1. file:./config/– Highest priority (under the project root path/configSubdirectories)
  2. file:./– Priority 2 (under project root path)
  3. classpath:/config/– Priority No. 3 (Projectresources/configBelow)
  4. classpath:/– Priority number four (itemresourcesThe root directory)

A high-priority configuration overrides a low-priority configuration

Coexist in the same level directory
application.properties
application.yamlFile, so
application.propertiesoverwrite
application.yamlfile

If our runtime wants to specify which environment to run the configuration file in, we can do it in three ways:

  1. It’s in the Resources folder of the projectapplication.propertiesIn-file configurationspring.profiles.active=devSpecify the loading environment
  2. Specifies when the JAR is started--spring.profiles.active=prodLoading environment
  3. Specifies when the JAR is started--spring.config.location=target/application.propertiesLoad the configuration file location

Third, ☀ ️ k8sconfigMapintroduce

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

Note:

ConfigMap does not provide privacy or encryption capabilities. If the data you want to store is confidential, please use Secret or other third party tools to ensure the privacy of your data instead of ConfigMap.

ConfigMap is not designed to store large amounts of data. You cannot store more than 1 MIB of data in ConfigMap. If you need to store more than this, you can consider mounting the volume or using a separate database or file service.

ConfigMap can be created in several ways:

  1. ConfigMap is used to create as many key and value pairs as there are files in the directory. The key name is the file name and the value is the contents of the file.

    Kubectl create cm [configMap name] --from-file=[directory]
  2. Create it with a file (you can use the –from-file parameter multiple times, just as you would specify the entire directory)

    Kubectl create cm [configMap name] --from-file=[file] --from-file=[file]
  3. Create from literal value (–from-literal can be used multiple times)

    Kubectl create cm [configMap name] --from-literal=[key = value] --from-literal=[key = value]

Example: Create a ConfigMap using literals

 kubectl create cm myconfigMap --from-literal=env=dev --from-literal=name=test
[root@node01 test]# kubectl describe cm myconfigMap
Name:         myconfigmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
env:
----
dev
name:
----
test
Events:  <none>
  1. useyamlManifest file creation

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

    API Version: V1 Kind: ConfigMap Metadata: Name: Game-demo Data: # API Version: V1 Kind: ConfigMap Metadata: Name: Game-demo Data: # Each key maps to a simple value player_initial_lives: "3" ui_properties_file_name: "User-interface. properties" # class file key, the name of the key is the file name, the value is the contents of the file. | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true

Create a configMap using the following command:

kubectl apply -f game-demo.yaml

Four, ☀️ use K8SconfigMapAs an external configuration file

As we can see from the previous introduction, the highest priority for Spring Boot to load configuration files is the /config subdirectory under the project root path, so you can mount configuration files in configMap into the config subdirectory under the project root path in the container.

  1. You can create one from a file using the following commandconfigMap:
kubectl create cm  spring-boot-demo  --from-file=application.yaml
  1. To create aspring-boot-demo.yamlThe 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: VolumeMounts: -mountpath: /app/config name: /app/config name: -mountpath: /app/config name: Config imagePullSecrets: -name: docker-password volumes: -configmap: # Config imagePullSecrets: -name: docker-password volumes: -configmap: Name: config -- API version: v1 kind: Service metadata: name: API version: v1 kind: Service metadata: name: API version: 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
  1. Create a mounted deployment using the following command:
kubectl apply -f spring-boot-demo.yaml
  1. Use the following command to enter the container to verify that it is mounted to the configured directory:
Kubectl exec -it spring-boot-demo-76bd6c8857-kwss6 bash

Five, ☀️ is mountedconfigMapThe content will be updated automatically

When the configMap used in the volume is updated, the projected key will eventually be updated as well. The Kubelet component checks whether the mounted ConfigMap 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 can be used to propagate content through watch operations (the default form), implement TTL based caching, and redirect to the API server directly through all requests. Therefore, the time span from the moment ConfigMap is updated until the new primary key is projected into the POD is probably equal to the synchronization cycle of Kubelet plus the propagation delay of the cache. The propagation delay here depends on the type of cache selected (corresponding to the propagation delay of the watch operation, the TTL length of the cache, or 0 respectively).

Used as an environment variableconfigMapData is not automatically updated, and updating this data requires a reboot of POD.

Reference documents:

K8s website

Spring boot website