In Kubernetes, configmap is used for keeping properties for an application. Once Spring applications required restart just due to change in properties file to take effect. Now in cloud with the help of fabric8 Kubernetes client, restart is not required anymore. We can reflect changes in configuration to Spring Boot live without downtime.
There are two reload modes: polling and event. Polling as the name implies polls Kubernetes API periodically. Event is more effective since it takes effect when configmap changed. We will cover event mode reload in this post.
How events arrive Spring Boot? Does Kubernetes aware of our Spring Boot app? No. Don’t confuse this event with Kubernetes event.
Above you can see Websocket is used between Spring Boot and Kubernetes API Server. Assuming we are using namespace “default” in this example, changes to response in this address reflected to KubernetesClient https://{api_server_clusterip}/api/v1/namespaces/default/configmaps/k8s-live-reload-configmap . If kube-proxy does not allow WebSocket then API Server is polled by HttpClient.
In Spring side, bootstrap.yaml reload mode and configmap name given. I deliberately disabled actuator endpoints, because most examples include actuator endpoints, however it is not required because fabric8-client refreshes bean internally. In pom.xml however actuator dependencies needed since fabric8-config depends on actuator configuration classes. See example
Beans annotated with @ConfigurationProperties are refreshed.
Run example
We need to build and push our application image to Docker and Kubernetes need to see this image. I suggest using Minikube 1.16.0. There are problems in prior versions due to DNS and VM(Hyper-V, VirtualBox). This version allows to run minikube as a docker container.
It can be download from here: https://github.com/kubernetes/minikube/releases Assuming you are not behind proxy or VPN (you may have network problems), following installation start minikube with this command.
You must have docker running.
This will download images and start minikube. Then install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl
First we need rolebinding for querying API Server. Otherwise KubernetesClient cannot reach API Server. default is the namespace here.
Get example project
Now add configmap named “k8s-live-reload-configmap” to kubernetes
Switch to kubernetes docker daemon in active shell to make Kubernetes reach application image. Run the command below, then run the last command in the output.
Build application image
Deployment and service
Test
Now see config before it has changed Deployment and service
It should return oldvalue. Now edit config map through command below or through minikube dashboard
After editing configmap, recheck application
It returns new value.