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?
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`