2

I am exploring the capabilities of Spring Cloud Kubernetes by using its feature to reload secrets on the fly. However, I still did not get this working.

I have a simple Spring Boot application that just prints out the contents of the secret that is mounted in the pod. Here is the configuration in bootstrap.properties

spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.reload.monitoring-secrets=true

spring.cloud.kubernetes.secrets.enabled=true
spring.cloud.kubernetes.secrets.paths=/etc/secret-volume

management.endpoint.info.enabled=true
management.endpoint.health.enabled=true
management.endpoint.restart.enabled=true

In application.properties, I have defined the property to get the value of the secret:

mysecret.password=${MY-PWD}

In the Spring Boot application, I defined a bean that will store the value of the secret:

@Configuration
@ConfigurationProperties(prefix = "mysecret")
public class MySecret {

    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

When I run the application on minikube, I see in the logs that Spring detects the declared secret and activates the profile:

16:54:30.887 [main] INFO o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: [BootstrapPropertySource@1132379993 {name='bootstrapProperties-my-pwd', properties={MY-PWD=qwerty}}] 16:54:30.899 [main] INFO c.c.r.ReloadSecretsApplication - The following profiles are active: kubernetes

After a while, I get the following log that says that it was added a watcher over the secret:

16:54:35.460 [OkHttp https://10.96.0.1/...] DEBUG i.f.k.c.d.i.WatchConnectionManager - WebSocket successfully opened 16:54:35.460 [main] INFO o.s.c.k.c.r.EventBasedConfigurationChangeDetector - Added new Kubernetes watch: secrets-watch 16:54:35.460 [main] INFO o.s.c.k.c.r.EventBasedConfigurationChangeDetector - Kubernetes event-based configuration change detector activated

Then, when I change the secret, I get this line saying that the reload won't be triggered:

11:20:15.963 [OkHttp https://10.96.0.1/...] WARN o.s.c.k.c.r.EventBasedConfigurationChangeDetector - The current number of Confimap PropertySources does not match the ones loaded from the Kubernetes - No reload will take place

The documentation is very scarce about this topic. Do I have any missing configuration here?

Link to the Spring Boot Application: https://github.com/Azlop/spring-cloud-kubernetes-reload-secrets

Azlop
  • 41
  • 4

1 Answers1

1

I know this is an old question without answer. I met the same issue and solved it after some research. Here I share my experience on this question if it can help someone in the future.

Spring Cloud Kubernetes has stored the external configmaps as several ConfigMapPropertySource instances in a CompositePropertySource or BootstrapPropertySource. When the application minitors the configmaps have been changed, it takes the ConfigMapPropertySource instances from the CompositePropertySource and compares the length of the ConfigMapPropertySource instances with the incoming instances. If the lengths are not same, the application returns an error message: "The current number of Confimap PropertySources does not match the ones loaded from the Kubernetes - No reload will take place".

But here is a potential problem: The other functions, in my case it is an encryptor, may change the type of the CompositePropertySource. Later, the application can't get the ConfigMapPropertySource instances and the comparison must be failed.

So my solution is to create a customized EventBasedConfigurationChangeDetector which has been changed the logic of the comparison. The original version is:

private void onEvent(ConfigMap configMap) {
    boolean changed = changed(locateMapPropertySources(this.configMapPropertySourceLocator, this.environment), findPropertySources(ConfigMapPropertySource.class));
    if (changed) {
            XXXX
    }
}

You should rewrite the findPropertySources function to fit in your stituation. In my instance, I unwrap the encrypted PropertySource to obtain the original ConfigMapPropertySource instances.

Finally, injecting your customized EventBasedConfigurationChangeDetector to replace the vanilla one will resolve the issue.

Roaid
  • 316
  • 5
  • 17