Search code examples
spring-bootkubernetesopenshiftlogbackconfigmap

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


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?


Solution

  • 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.