Deploying Spring Boot App on Kubernetes: App uses wrong port property from environment variable

3/20/2018

I am trying to deploy a "Hello world" Spring Boot app on Kubernetes (Minikube). The app is really simple, just one method, which is mapped on a GET resource. I even do not specify a port.

I am now trying to deploy the app on Minikube, and making it available using a Service:

kind: Service
apiVersion: v1
metadata:
  name: server
spec:
  selector:
    app: server
  ports:
  - protocol: TCP
    port: 8080
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: server
spec:
  selector:
      matchLabels:
        app: server
  replicas: 3
  template:
    metadata:
      labels:
        app: server
    spec:
      containers:
        - name: server
          image: kubernetes-server:latest
          imagePullPolicy: Never
          ports:
            - name: http
              containerPort: 8080

If I start the deployment using this configuration (i. e. the service is started first, then the Deployment), the pods fail during startup. In the logs, I can find the following message:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target         
org.springframework.boot.autoconfigure.web.ServerProperties@42f93a98 failed:

    Property: server.port
    Value: tcp://10.98.151.181:8080
    Reason: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'port'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.lang.Integer]

Note: 10.98.151.181 is the cluster IP of the Service, as a can see in the Minikube dashboard.

If I first trigger the actual Deployment, the app starts successfully, and after that, I can start the Service. However, the official documentation recommends to start the service first, and after that the deplyoment: https://kubernetes.io/docs/concepts/configuration/overview/#services

For me, it looks like the Service sets a property server.port as environment variable, and the Spring Boot app, which start after the Service, interprets that accidentially as the Spring server.port.

Any ideas how to solve that?

-- markusgulden
kubernetes
minikube
spring-boot

1 Answer

3/21/2018

For me, it looks like the Service sets a property server.port as environment variable

No, kubernetes it is exposing "docker compatible" link env-vars which, because your Service is named server, end up being SERVER_PORT=tcp://thing:8080 because it is trying to be "helpful"

The solution is either give your Service a much more descriptive name, or mask-off the offending env-var:

containers:
- name: server
  env:
  - name: SERVER_PORT
    value: ''  # you can try the empty string,
    # or actually place the port value with
    # value: '8080'
    # ensure it is a **string** and not `value: 8080`
-- mdaniel
Source: StackOverflow