1

Problem: I have a VERY simple spring boot api with hard coded db connection strings. I would like to feed these connection strings FROM a pod in my K8s cluster but I am having issues with telling the api to read from env variables.

My Dockerfile:

FROM gcr.io/distroless/java:8
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

This is the db-secret.yaml file:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  host: XXXX
  user: XXXX
  password: XXXX
  database: XXXX

This is the env section of my api pod my deployment file:

          env:
            - name: ORIGIN
              value: https://myclient.app.com
            - name: HOST
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: host
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
            - name: USERNAME
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: user
            - name: DATABASE
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: database

This is my Java application.properties file:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=${HOST}/"todos"
spring.datasource.username=${USERNAME}
spring.datasource.password=${PASSWORD}

However...when I try to build the app using ./mvnw clean package i get: * java.lang.IllegalStateException: Failed to load ApplicationContext * BeanCreationException: Error creating bean with name 'entityManagerFactory'

I tried exporting the variables via command line but that didn't work. I know node has process.env.SOME_VAR. Is there something like this for Java? I've been combing through the interwebs for a while and trying different solutions but not much is working at this point.

  • https://stackoverflow.com/questions/3965446/how-to-read-system-environment-variable-in-spring-applicationcontext – Matt Apr 10 '20 at 05:37
  • Your build is failing so you haven't even reached the Kubernetes cluster so your issue is probably related to something else. If you directly inject your credentials and URL, do you still have the same error? Also, there must be a continuation of that error message, stating the reason why the `entityManagerFactory` cannot be created. Can you check? – Urosh T. Apr 10 '20 at 09:30
  • Did you configure your secrets as written in this article: https://developers.redhat.com/blog/2017/10/04/configuring-spring-boot-kubernetes-secrets/ ? – kool Apr 10 '20 at 13:44

1 Answers1

0

Loading environment variables requires some configuration, otherwise there won't be anything looking for a db-secret.yaml file.

One approach is to place the configuration values directly into application.properties or application.yml. You will probably also need to make sure that those files are not committed into a repository (.e.g. added to .gitignore).

VirtualMichael
  • 719
  • 9
  • 18
  • So I have a running pod in my K8s cluster that takes the contents of the db-secret.yaml and injects into the container that is hosting my spring boot api. If this were a node api i could read from process.env.DB_HOST. I think i'm missing something between my running pod and the running container. Perhaps the container isn't built properly? I'm not sure. I need to get the creds from the pod => container => application code... and i haven't found a way yet :( – Kolton Starr Apr 10 '20 at 01:33