Gymterview
middle

Как передать конфигурацию в Java/Spring Boot приложение через ConfigMap и Secret?

Spring Boot приложения гибко работают с конфигурацией из Kubernetes. Существует три основных подхода, различающихся по сложности и возможностям.

1. Переменные окружения

Spring Boot автоматически подхватывает переменные окружения. Переменная SPRING_DATASOURCE_URL маппится на свойство spring.datasource.url.

Пример Deployment с envFrom
apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-config
data:
  SPRING_DATASOURCE_URL: "jdbc:postgresql://postgres-service:5432/mydb"
  SPRING_JPA_HIBERNATE_DDL_AUTO: "validate"
  SERVER_PORT: "8080"
---
apiVersion: v1
kind: Secret
metadata:
  name: spring-secret
type: Opaque
stringData:
  SPRING_DATASOURCE_USERNAME: "postgres"
  SPRING_DATASOURCE_PASSWORD: "secret123"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-spring-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-spring-app
  template:
    metadata:
      labels:
        app: my-spring-app
    spec:
      containers:
        - name: app
          image: my-registry/my-spring-app:1.0.0
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: spring-config
            - secretRef:
                name: spring-secret

2. Монтирование application.yml как файл

ConfigMap содержит полный application.yml, который монтируется в контейнер и указывается через SPRING_CONFIG_LOCATION.

Пример с монтированием application.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-app-config
data:
  application.yml: |
    server:
      port: 8080
      shutdown: graceful
    spring:
      datasource:
        url: jdbc:postgresql://postgres-service:5432/mydb
        hikari:
          maximum-pool-size: 10
      jpa:
        hibernate:
          ddl-auto: validate
    management:
      endpoints:
        web:
          exposure:
            include: health,info,prometheus
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-spring-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-spring-app
  template:
    metadata:
      labels:
        app: my-spring-app
    spec:
      containers:
        - name: app
          image: my-registry/my-spring-app:1.0.0
          ports:
            - containerPort: 8080
          volumeMounts:
            - name: config
              mountPath: /app/config
              readOnly: true
          env:
            - name: SPRING_CONFIG_LOCATION
              value: "file:/app/config/application.yml"
      volumes:
        - name: config
          configMap:
            name: spring-app-config

3. Spring Cloud Kubernetes

Библиотека Spring Cloud Kubernetes позволяет напрямую читать ConfigMap и Secret как PropertySource. При изменении ConfigMap приложение может автоматически перезагрузить конфигурацию без перезапуска Pod’а.

Пример
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>
</dependency>
Пример
# bootstrap.yml
spring:
  cloud:
    kubernetes:
      config:
        enabled: true
        name: my-app-config
      secrets:
        enabled: true
        name: my-app-secret
      reload:
        enabled: true
        strategy: refresh

Сравнение подходов

Подход Простота Hot reload Когда использовать
Переменные окружения Высокая Нет (нужен рестарт Pod’а) Простые случаи, секреты
Монтирование файла Средняя Частично (ConfigMap обновляется, но Spring Boot нужно перечитать) Сложная конфигурация
Spring Cloud Kubernetes Низкая Да (автоматически) Когда нужен hot reload без рестарта

На собеседовании: достаточно описать подходы через env и volume mount. Spring Cloud Kubernetes — бонус. Частая ошибка — не знать, что Spring Boot автоматически маппит SPRING_DATASOURCE_URL на spring.datasource.url.