Can Ingress Controllers use Selector based rules?

3/3/2021

I have deployed a statefulset in AKS - My goal is to load balance traffic to my statefulset.

From my understanding I can define a LoadBalancer Service that can route traffic based on Selectors, something like this.

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: web
  selector:
    app: nginx

However I don't want to necessarily go down the LoadBalance route and I would prefer Ingress doing this work for me, My question is can any of the ingress controller support routing rules which can do Path based routing to endpoints based on selectors? Instead of routing to another service.

Update To elaborate more on the scenario - Each pod in my statefulset is a stateless node doing data processing of a HTTP feed. I want my ingress service to be able to load balance traffic across these statefulset pods ( honoring keep-alives etc), however given the nature of statefulsets in k8s they are currently exposed through a headless service. I am not sure if a headless service can load balance traffic to my statefulsets?

Update 2 Quick search reveals headless service does not loadbalance

Sometimes you don't need load-balancing and a single Service IP. In this case, you can create what are termed "headless" Services, by explicitly specifying "None" for the cluster IP (.spec.clusterIP).

-- Riddle
azure-aks
kubernetes

3 Answers

3/5/2021

I am not sure if a headless service can load balance traffic to my statefulsets?

The first answer is "no". Why?

k8s Service is implemented by the kube-proxy. Kube-proxy itself can work in two modes:

  1. iptables (also known as netfilter)
  2. ipvs (also known as LVS/Linux Virtual Server)

load balancing in case of iptables mode is a NAT iptables rule: from ClusterIP address to the list of Endpoints

load balancing in case of ipvs mode is a VIP (LVS Virtual IP) with the Endpoints as upstreams

So, when you create k8s Service with clusterIP set to None you are exactly saying:

"I need this service WITHOUT load balancing"

Setting up the clusterIP to None causes kube-proxy NOT TO CREATE NAT rule in iptables mode, VIP in ipvs mode. There will be nothing for traffic load balancing across the pods selected by this particular Service selector

The second answer is "it could be". Why?

You are free to create headless Service with desired pods selector. DNS query to this Service will return the list of DNS A records for selected pods. Then you can use this data to implement load balancing YOUR way

-- Konstantin Vustin
Source: StackOverflow

3/4/2021

As much i know it's not possible to do the selector-based routing with ingress.

selector based routing is mostly used during a Blue-green deployment or canary deployment you can only achieve this by using the service mesh. You can use any of the service mesh like istio or APP mesh and you can do the selector base routing.

I have deployed a statefulset in AKS - My goal is to load balance traffic to my statefulset.

if your goal is to just load balance traffic you can use the ingress controller maybe still not sure about scenrio you are trying to explain.

By default kubernetes service also Load balance the traffic across the PODs.

Flow will be something like DNS > ingress > ingress controller > Kubernetes service (Load balancing here) > any of statefulset

-- Harsh Manvar
Source: StackOverflow

3/4/2021

+1 to Harsh Manvar's answer but let me add also my 3 cents.

My question is can any of the ingress controller support routing rules which can do Path based routing to endpoints based on selectors? Instead of routing to another service.

To the best of my knowledge, the answer to your question is no, it can't as it doesn't even depend on a particular ingress controller implementation. Note that various ingress controllers, no matter how different they may be when it comes to implementation, must conform to the general specification of the ingress resource, described in the official kubernetes documentation. You don't have different kinds of ingresses, depending on what controller is used.

Ingress and Service work on a different layer of abstraction. While Service exposes a set of pods using a selector e.g.:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp 👈

path-based routing performed by Ingress is always done between Services:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test 👈
            port:
              number: 80
-- mario
Source: StackOverflow