Kubernetes and spring boot variable parsing conflict

5/28/2018

I have a Kubernetes's and spring boot's env variables conflict error. Details is as follows:

When creating my zipkin server pod, I need to set env variable RABBITMQ_HOST=http://172.16.100.83,RABBITMQ_PORT=5672.

Initially I define zipkin_pod.yaml as follows:

apiVersion: v1
kind: Pod
metadata:
  name: gearbox-rack-zipkin-server
  labels:
    app: gearbox-rack-zipkin-server
    purpose: platform-demo
spec:
  containers:
  - name:  gearbox-rack-zipkin-server
    image: 192.168.1.229:5000/gearboxrack/gearbox-rack-zipkin-server
    ports:
    - containerPort: 9411
    env:
      - name: EUREKA_SERVER
        value: http://172.16.100.83:31501
      - name: RABBITMQ_HOST
        value: http://172.16.100.83
      - name: RABBITMQ_PORT
        value: 31503

With this configuration, when I do command

kubectl apply -f zipkin_pod.yaml

The console throws error:

[root@master3 sup]# kubectl apply -f zipkin_pod.yaml
Error from server (BadRequest): error when creating "zipkin_pod.yaml": Pod in version "v1" cannot be handled as a Pod: v1.Pod: Spec: v1.PodSpec: Containers: []v1.Container: v1.Container: Env: []v1.EnvVar: v1.EnvVar: Value: ReadString: expects " or n, parsing 1018 ...,"value":3... at {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"gearbox-rack-zipkin-server\",\"purpose\":\"platform-demo\"},\"name\":\"gearbox-rack-zipkin-server\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"EUREKA_SERVER\",\"value\":\"http://172.16.100.83:31501\"},{\"name\":\"RABBITMQ_HOST\",\"value\":\"http://172.16.100.83\"},{\"name\":\"RABBITMQ_PORT\",\"value\":31503}],\"image\":\"192.168.1.229:5000/gearboxrack/gearbox-rack-zipkin-server\",\"name\":\"gearbox-rack-zipkin-server\",\"ports\":[{\"containerPort\":9411}]}]}}\n"},"labels":{"app":"gearbox-rack-zipkin-server","purpose":"platform-demo"},"name":"gearbox-rack-zipkin-server","namespace":"default"},"spec":{"containers":[{"env":[{"name":"EUREKA_SERVER","value":"http://172.16.100.83:31501"},{"name":"RABBITMQ_HOST","value":"http://172.16.100.83"},{"name":"RABBITMQ_PORT","value":31503}],"image":"192.168.1.229:5000/gearboxrack/gearbox-rack-zipkin-server","name":"gearbox-rack-zipkin-server","ports":[{"containerPort":9411}]}]}}

so I modified the last line of zipkin_pod.yaml file as follows: Or use brutal force to make port number as int.

apiVersion: v1
kind: Pod
metadata:
  name: gearbox-rack-zipkin-server
  labels:
    app: gearbox-rack-zipkin-server
    purpose: platform-demo
spec:
  containers:
  - name:  gearbox-rack-zipkin-server
    image: 192.168.1.229:5000/gearboxrack/gearbox-rack-zipkin-server
    ports:
    - containerPort: 9411
    env:
      - name: EUREKA_SERVER
        value: http://172.16.100.83:31501
      - name: RABBITMQ_HOST
        value: http://172.16.100.83
      - name: RABBITMQ_PORT
        value: !!31503

Then pod is successfully created, but spring getProperties throws exception.

[root@master3 sup]# kubectl apply -f zipkin_pod.yaml
pod "gearbox-rack-zipkin-server" created

When I check logs:

[root@master3 sup]# kubectl logs gearbox-rack-zipkin-server
2018-05-28 07:56:26.792  INFO [zipkin-server,,,] 1 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4ac68d3e: startup date [Mon May 28 07:56:26 UTC 2018]; root of context hierarchy

...

***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.autoconfigure.amqp.RabbitProperties@324c64cd failed:
    Property: spring.rabbitmq.port
    Value:
    Reason: Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'port'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [int]
Action:
Update your application's configuration

My question is how to let kubernetes understand the port number as int, while not breaking spring boot convert rule from string to int? because spring boot could not convert !!31503 to int 31503.

-- user84592
kubernetes
spring-boot

1 Answer

5/29/2018

As @Bal Chua and @Pär Nilsson mentioned, for environmental variables you can use only string variables because Linux environmental variables can be only strings.

So, if you use yaml, you need to place value into quotes to force Kubernetes to use string.

For example:

- name: RABBITMQ_PORT
  value: '31503'
-- Artem Golenyaev
Source: StackOverflow