Openshift 4.19 (Kubernetes 1.19) Tomcat spring app overwrite deployed file with config map entry clears complete deployment directory

5/5/2021

I have a Spring Boot app deployed under a Tomcat server inside a POD with Openshift 4.19 (which uses Kubernetes 1.19). My goal is to externalize the logback configuration to a configmap, so that I can change the loglevel as needed in production without restarting the pods.

I used the following configuration:

ConfigMap

    kind: ConfigMap
apiVersion: v1
metadata:
  name: logback-configmap
[..]
data:
  logback: |
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds">
[...]

Deployment Config

[...]
spec:
      volumes:
        - name: logback-configmap-volume
          configMap:
            name: logback-configmap
            items:
              - key: logback
                path: logback.xml
            defaultMode: 420
[..]
         volumeMounts:
            - name: logback-configmap-volume
              mountPath: /deployments/zfaRouter/WEB-INF/classes/logback.xml
              subPath: logback.xml
[..]

The problem is, that the above config clears the complete directory structure under /deployments/zfaRouter/WEB-INF/classes/:

sh-4.4$ ls -la /deployments/zfaRouter/WEB-INF/classes/
total 4
drwxr-xr-x. 2 root root         25 May  4 16:35 .
drwxr-xr-x. 3 root root         21 May  4 16:35 ..
-rw-r--r--. 1 root 1015170000 1084 May  4 16:35 logback.xml

I tried every possible combination (eg. without subPath element, without the filename in the mountPath, without the items element in the volumes section) without any luck. From what a read here and in the official Kubernetes docs, it should work like the configuration above.

Any ideas on this problem?

-- Thorsten Kitz
configmap
kubernetes
logback
openshift
spring-boot

1 Answer

5/5/2021

The directory that is used as mount point shadows all other content, therefore it appears like overwriting what you expect to be there. Even if you want to 'just' have a single file mounted, a mount point must exist.

For your specific scenario you could either mount to a different directory, like /config and add it to the classpath, or you can use a subdirectory like /deployments/zfaRouter/WEB-INF/classes/config and add that to the classpath.

If you don't want to change the classpath you could mount the config file to, f.e. /config and change your application start script to copy it to a fitting location, for example to the tomcat shared lib folder that is picked up by the tomcat classloader.

-- Thomas
Source: StackOverflow