User based deploying in Kubernetes

3/26/2020

I am slightly newbie on kubernetes. And we want the present some of our products as SaaS to our costumers. So i need the user based isolated deployments. After some research i decided to create a namespace to each user. Then deploy what user wants from our template to user's namespace. But there is a problem about port mapping. Lets say we have 6 user and all of them want's the deploy django app. So all of them wants to access their project from 80 and 443 ports. Is there any solution for this in kubernetes? If it is how should i proceed?

And how can i seperate each users deployments to diffrent networks or vlans to isolate their networks from each other?

-- Zekeriya Akgül
docker
kubernetes
kubernetes-pod

2 Answers

3/26/2020

You can either put a dedicated load balancer to each of them (the expensive solution, but straight forward), or make your Ingress Controller to only accept requests with a hostname, and point each hostname to it's service, in its namespace (cheap solution but complicate).

Load Balancer Solution:

This one is easy, if you are with a cloud provider, so every time a client exposes the app, you just create a LoadBalancer type service pointing to his app. Since for each app you get a new load balancer, you have no problem of port collision. Now, the drawbacks are that this you can do only with a cloud provider, and it will be quite expensive.

Ingress Solution:

This one is the pro solution. It's cheap, but it's also more complex. So, you would create an Ingress resource like this:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  tls:
  - secretName: tls 
  rules:
  - host: site1.domain.com
    http:
      paths:
      - path: /path1/
        backend:
          serviceName: service1
          servicePort: 80
  - host: site2.domain.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
    ...

Here, you just have one L7 load balancer, and that's Ingress Controller doing all the routing. Depending on Ingress Controller, you might get an L4 load balancer (e.g. nginx, Traefik), but still that's Ingres Controller doing the routing.

Complexity? You will have to figure out a way to update the Ingress Controller records without a downtime for other users. Also, on Kubernetes, an Ingress Controller can't pass a request from one namespace to another. So, the service needs to run in the same namespace that the Ingress resource has been created (Note, I'm saying Ingress resource, being the rules (like the yaml above); not Ingress Controller). This is a known limitation that Kubernetes team already announced that will never be changed, as it introduces a huge security hole.

You will need to create headless services without selectors in the same namespace that Ingress object, and separately create Endpoint objects pointing to the service in the other namespaces. It might look like cumbersome, but that's quite pro actually.

-- suren
Source: StackOverflow

3/26/2020

To separate external access to the apps you need to deploy an Ingress Controller and create different Ingresses pointing to Services of each application. Every Ingress will hold its unique URL per application.

To prohibit internal cross-namespace communication you need to deploy network policies. Fr this you'll need to deploy an addon. Or you can solve it by deploying any common service mesh: Istio, Linkerd, Consul etc.

-- Anton Matsiuk
Source: StackOverflow