Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configtree not working with Kubernetes projected volume #24530

Closed
henriqueof opened this issue Dec 16, 2020 · 0 comments
Closed

configtree not working with Kubernetes projected volume #24530

henriqueof opened this issue Dec 16, 2020 · 0 comments
Assignees
Milestone

Comments

@henriqueof
Copy link

@henriqueof henriqueof commented Dec 16, 2020

Spring boot version: 2.4.1
Tested on Kubernetes v1.18.8 and locally reproduced on Windows file system

Kubernetes volume projection can be used to aggregate many secrets or configmaps under the same root folder to facilitate configuration usage and filtering.

This problem arises when subpaths are used to project the value. Since the first directory level is a symbolic link, Spring does not follow it, and no properties are loaded past it.

For example, following pod:

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: projected-volume
      mountPath: "/etc/config"
      readOnly: true
  volumes:
  - name: projected-volume
    projected:
      sources:
      - secret:
          name: user-secret
          items:
            - key: username
              path: my/application/credentials/username
          name: pass-secret
          items:
            - key: password
              path: my/application/credentials/password

Will generate this directory tree:

etc/
  +- config/ (volume mount point)
    +- my/ (secret projected/symlink)
      +- application/
        +- credentials/
          +- username
          +- password

Using the following application.yaml

spring:
  config:
    import:
      - configtree:/etc/config/

Spring will not load any values past the my directory and will eventually throw an exception when the property is referenced.

As a workaround we added two other levels to the projection path and added it to the configtree option forcing Spring to read past the symlink directory.

For example, following pod:

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: projected-volume
      mountPath: "/etc/config"
      readOnly: true
  volumes:
  - name: projected-volume
    projected:
      sources:
      - secret:
          name: user-secret
          items:
            - key: username
              path: a/b/my/application/credentials/username
          name: pass-secret
          items:
            - key: password
              path: a/b/my/application/credentials/password

Will generate this directory tree:

etc/
  +- config/ (volume mount point)
    +- a/  (secret projected/symlink)
      +- b/
        +- my/
          +- application/
            +- credentials/
              +- username
              +- password

Using the following application.yaml

spring:
  config:
    import:
      - configtree:/etc/config/a/b/

The two directory levels were necessary because the a directory itself is a symlink. Since b is a regular folder the properties past it will be loaded successfully.

I suspect the problem could be in the method call Files.find here where it does not use the java.nio.file.FileVisitOption.FOLLOW_LINKS option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants