1

I'm configuring app to works in Kubernetes google cloud cluster. I'd like to pass parameters to application.properties in Spring boot application via configMap. I'm trying to pass value by Environment Variable.

I've created config map in google cloud Kubernetes cluster in namespace default like below:

apiVersion: v1
kind: ConfigMap
metadata: 
  name: app-config
data:
  config-key: 12345789abde 

kubectl create -f app-config.yaml -n default
configmap/app-config created

I'm checking if configMap has been created:

enter image description here

key value pair looks fine:

enter image description here

I'm trying to deploy Spring boot app with using cloudbuild.yaml(it works when I not use configMap). The content is:

substitutions:
  _CLOUDSDK_COMPUTE_ZONE: us-central1-c  # default value
  _CLOUDSDK_CONTAINER_CLUSTER: kubernetes-cluster-test      # default value

steps:
  - id: 'Build docker image'
    name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA', '.']
  - id: 'Push image to Container Registry'
    name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA']
  - id: 'Set image in yamls'
    name: 'ubuntu'
    args: ['bash','-c','sed -i "s,${_TECH_CONTAINER_IMAGE},gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA," deployment.yaml']
  - id: 'Create or update cluster based on last docker image'
    name: 'gcr.io/cloud-builders/kubectl'
    args: ['apply', '-f', 'deployment.yaml']
    env:
      - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}'
      - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}'
  - id: 'Expose service to outside world via load balancer'
    name: 'gcr.io/cloud-builders/kubectl'
    args: [ 'apply', '-f', 'service-load-balancer.yaml' ]
    env:
      - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}'
      - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}'
options:
  logging: CLOUD_LOGGING_ONLY

deployment.yaml with reference to config map (container is also in default namespace) is:

apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "java-kubernetes-clusters-test"
  namespace: "default"
  labels:
    app: "java-kubernetes-clusters-test"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "java-kubernetes-clusters-test"
  template:
    metadata:
      labels:
        app: "java-kubernetes-clusters-test"
    spec:
      containers:
        - name: "app"
          image: "kubernetes-cluster-test-image"
          env:
            - name: CONFIG_KEY
              valueFrom:
                configMapKeyRef:
                  name: app-config
                  key: config-key

Spring boot is not able to read placeholder and I'm obtaining an error in attempt to deply app to google cloud like below:

enter image description here

I'm trying to reference to env with name CONFIG_KEY in application.properties:

com.example.dockerkubernetes.property.value=${CONFIG_KEY}

and then in Spring Boot controller:

@RestController
@RequiredArgsConstructor
public class MyController {

    @Value("${com.example.dockerkubernetes.property.value}")
    private String testValue;

    public String getConfigMapTestKey() {
        return this.testValue;
    }
}

Has anyone any idea why it dosen't work? Maybe some permissions are missing? I would be grateful for help.

Krzysztof Michalski
  • 791
  • 1
  • 9
  • 25
  • not sure if applciation.properties can read env variables or not. Code can directly read env variables or you can mount the configmap to file system. your configmap could store whole application properties file and could be injected and used by application :https://github.com/redhat-developer-demos/spring-boot-configmaps-demo – Harsh Manvar Dec 19 '22 at 09:15
  • Hi Harsh, I've observed that environment variables are present inside the container. Bu question is why Spring is not able to read them in application.properties? spring.datasource.username=${MYSQL_ROOT_USERNAME} spring.datasource.password=${MYSQL_ROOT_PASSWORD} spring.jpa.hibernate.ddl-auto=update com.example.dockerkubernetes.property.value=testlocal config.key = ${CONFIG_KEY} – Krzysztof Michalski Dec 19 '22 at 15:01

1 Answers1

1

You can read properties from the environment, but that could require a bit of coding & refactoring (depending on the rest of your code) to import and use such values, i.e. into a Properties object.

If you want to use an application.properties file directly you're better off mounting the single file into the app's container by using SubPath.

Make sure you mount the file exactly as specified in the linked official docs or you are likely to get errors related to the container's FS permissions

LeoD
  • 86
  • 1
  • 4