Search code examples
javaspringspring-bootspring-cloud-configconfigmap

Spring not picking up changes to ConfigMap


I have an application that is using Springboot, I am trying to allow on the fly configuration updates using the following.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.3.1-RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
        <version>1.1.4.RELEASE</version>
    </dependency>

I have tried to follow this article https://medium.com/swlh/kubernetes-configmap-confuguration-and-reload-strategy-9f8a286f3a44, and have managed to get Spring pulling the config from the ConfigMap, however, if I update the ConfigMap when the application is running, spring does not pick it up. This is my bootstrap.yml

spring:
  cloud:
    kubernetes:
      config:
        enabled: true
        sources:
          - namespace: default
            name: hello-world
      reload:
        enabled: true
        mode: event
        strategy: refresh

I have also tried using mode: polling, but still no change. And I have added the view role.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "hello-world.fullname" . }}-view
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
subjects:
  # Authorize specific service accounts:
  - kind: ServiceAccount
    name: {{ include "hello-world.serviceAccountName" . }}
    namespace: default

I am thinking maybe it's the way I am loading my configuration in Java?

@ConfigurationProperties(prefix = "spring.app")
@Bean
public Properties appProperties() {
    return new Properties();
}

@Autowired
@Qualifier("appProperties")
private Properties props;

My ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: hello-world
data:
  application.yml: |-
    spring:
      app:
        message: Hello

I am then accessing values like props.getProperty("message")

UPDATE:

So I managed to get the changes picked up, by enabling the actuator refresh endpoint:

management:
  endpoint:
    restart:
      enabled: true

But now I have a new question, is this necessary? Is there any way to get this to work without including the actuator?


Solution

  • Please make sure you have the following dependency in your POM with a version.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    I had similar issue, which is resolved after adding this.