Access an application running on a random port in Kubernetes

Viewed 444

My application is running within a pod container in a kubernetes cluster. Every time it is started in the container it allocates a random port. I would like to access my application from outside (from another pod or node for example) but since it allocates a random port I cannot create a serivce (NodePort or LoadBalancer) to map the application port to a specific port to be able to access it.

What are the options to handle this case in a kubernetes cluster?

4 Answers

Not supported, checkout the issue here. Even with docker, if your range is overly broad, you can hit issue as well.

One option to solve this would be to use a dynamically configured sidecar proxy that takes care of routing the pods traffic from a fixed port to the dynamic port of the application.

enter image description here

This has the upside that the service can be scaled even if all instances have different ports. But this also has the potentially big downside that every request has an added overhead due to the extra network step and even if it's just some milliseconds this can have quite an impact depending on how the application works.

Regarding the dynamic configuration of the proxy you could e.g. use shared pod volumes.

Edit:

Containers within a pod are a little bit special. They are able to share predefined volumes and their network namespace.

For shared volumes this means. you are able to define a volume e.g. of type emptyDir and mount it in both containers. The result is that you can share information between both containers by writing them into that specific volume in the first pod and reading the information in the second.

For networking this makes communication between containers of one pod easier because you can use the loopback to communicate with between your containers. In your case this means the sidecar proxy container can call your service by calling localhost:<dynamic-port>.

For further information take a look at the official docs.

So how is this going to help you?

You can use a proxy like envoy and configure it to listen to dynamic configuration changes. The source for the dynamic configuration should be a shared volume between both your application container and the sidecar proxy container. After your application started and allocated the dynamic port you can now automatically create the configuration for the envoy proxy and save it in the shared volume. The same source envoy is listening to due to the aforementioned configuration. Envoy itself acts as a reverse proxy and can listen statically on port 8080 (or any other port you like) and routes the incoming network traffic to your application with dynamic port by calling localhost:<dynamic-port>.

Unfortunately I don't have any predefined configuration for this use case but if you need some inspiration you can take a look at istio - they use something quite similar.

As gohm'c mentioned there is no built in way to do this.

As a workaround you can run a script to adjust the service:

  1. Start the application and retrieve the choosen random port from the application
  2. Modify the Kubernetes service, loadbalancer, etc. with the new port

The downside of this is that if the port changes there will be short delay to update the service afterwards.

How about this:

  1. Deploy and start your application in a Kubernetes cluster.

  2. run kubectl exec <pod name here> -- netstat -tulpn | grep "application name" to identify the port number associated with your application.

  3. run kubectl port-forward <pod name here> <port you like>:<random application port> to access the pod of your application.

Would this work for you?

Edit. This is very similar to @Lukas Eichler's response.

Related