Yesterday I blogged about configmaps and how changing the configmap is not picked up by ASP.NET Core. In this post I want to dig deeper in why this is the case and suggest a possible solution.
The CreateDefaultBuilder() method in ASP.NET Core will load your appsettings.json file and monitor it for changes (see the reloadOnChange: true):
Behind the scenes the reloadOnChange setting will monitor the config file for changes based on the last modified date. Seems logical…
Let’s continue to find out why this doesn’t work with Kubernetes. In Kubernetes a config map is mounted as a symlink:
kubectl exec -it <pod-name> -- bash
root@example-deployment-839f6c6546-c783b:/appg# ls -la
rwxrwxrwx 3 root root 4096 Mar 25 10:01 .
drwxr-xr-x 1 root root 4096 Mar 25 10:47 ..
drwxr-xr-x 2 root root 4096 Mar 25 10:01 ..2021_03_25_10_01_16.386067924
lrwxrwxrwx 1 root root 31 Mar 25 10:01 ..data -> ..2021_03_25_10_01_16.386067924
lrwxrwxrwx 1 root root 53 Mar 25 10:47 appsettings.json -> ..data/appsettings.json
Unfortunately when you update the config map, the last modified date doesn’t change, although the file reference itself is updated. This is a known issue as discussed here.
One suggested workaround for this problem is to use a a configuration provider that understand symlinks(notice that this solution only works on linux):
Another possible solution is mentioned by Francisco Beltrao and uses the content itself to detect changes instead of the last modified date:
The code required for this solution can be found in this GitHub repo: https://github.com/fbeltrao/ConfigMapFileProvider