user787267
user787267

Reputation: 2990

Kubernetes ingress for dynamic URL

I am developing an application that allows users to play around in their own sandboxes with a finite life time. Conceptually, it can be thought as if users were playing games of Pong. Users can interact with a web interface hosted at main/ to start a game of Pong. Each game of Pong will exist in its own pod. Since each game has a finite lifetime, the pods are dynamically created on-demand (through the Kubernetes API) as Kubernetes jobs with a single pod. There is therefore a one-to-one relationship between games of Pong and pods. Up to this point I have it all figured out.

My problem is, how do I set up an ingress to map dynamically created URLs, for example main/game1, to the corresponding pods? That is, if a user starts a game through the main interface, I would like him to be redirected to the URL of the corresponding pod where his game is hosted.

I could pre-allocate a set of urls, check if they have active jobs, and redirect if they do not, but the does not scale well. I am thinking dynamically assigning URLs is a common pattern in Kubernetes, so there must be a standard way to do this. I have looked at using nginx-ingress, but that is not a requirement.

Upvotes: 2

Views: 2090

Answers (2)

Mark
Mark

Reputation: 4067

I agree with Efrat Levitan. It's not the task for ingress/kubernetes itself.

You need another application (different layer of abstraction) to distinguish where the traffic should be routed for example istio and Routing rule for HTTP traffic based on cookies.

Upvotes: 1

prometherion
prometherion

Reputation: 2299

Furthermore the comment, I created for you a little demo on minikube providing a working Ingress Class controller (enabled via minikube addons enable ingress).

Replicating the multiple Deployment that simulates the games.

kubectl create deployment deployment-1 --image=nginxdemos/hello
kubectl create deployment deployment-2 --image=nginxdemos/hello
kubectl create deployment deployment-3 --image=nginxdemos/hello
kubectl create deployment deployment-4 --image=nginxdemos/hello
kubectl create deployment deployment-5 --image=nginxdemos/hello

Same for Services resources:

kubectl create service clusterip deployment-1 --tcp=80:80
kubectl create service clusterip deployment-2 --tcp=80:80
kubectl create service clusterip deployment-3 --tcp=80:80
kubectl create service clusterip deployment-4 --tcp=80:80
kubectl create service clusterip deployment-5 --tcp=80:80

Finally, it's time for the Ingress one but we have to be quite hacky since we don't have the subcommand create available.

for number in `seq 5`; do echo "
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: deployment-$number
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
 rules:
 - host: hello-world.info
   http:
     paths:
     - path: /game$number
       backend:
         serviceName: deployment-$number
         servicePort: 80
" | kubectl create -f -; done

Now you have Pod, Service and Ingress: obviously, you have to replicate the same result using Kubernetes API but, as I suggested in the comment, you should create a single Ingress resource and update accordingly Path subkey in a dynamic way.

However, if you try to simulate the cURL call faking the Host header, you can see the working result:

# curl `minikube ip`/game2 -sH 'Host: hello-world.info'|grep -i server
<p><span>Server&nbsp;address:</span> <span>172.17.0.5:80</span></p>
<p><span>Server&nbsp;name:</span> <span>deployment-2-5b98b954f6-8g5fl</span></p>

# curl `minikube ip`/game4 -sH 'Host: hello-world.info'|grep -i server
<p><span>Server&nbsp;address:</span> <span>172.17.0.7:80</span></p>
<p><span>Server&nbsp;name:</span> <span>deployment-4-767ff76774-d2fgj</span></p>

You can see the Pod IP and name as well.

Upvotes: 1

Related Questions