kuberneteskubernetes-ingressazure-aksazure-load-balancerkubernetes-service

Why is Azure Load Balancer created by AKS set up to direct traffic to port 80 and 443 on nodes rather than nodeports opened by a service?


I have an AKS cluster with an nginx ingress controller. Controller has created a service with a type LoadBalancer and Ports section looks like this (from kubectl get service):

80:31141/TCP

If I understand things correctly port 80 is a ClusterIp port that is not reachable from the outside but port 31141 is a port that is a NodePort and is reachable from outside. So I would assume that an Azure Load Balancer is sending traffic to this 31141 port.

I was surprised to find that Azure Load Balancer is set up with a rule:

frontendPort: 80
backendPort: 80
probe (healthCheck): 31141

So it actually does use the nodeport but only as a healthcheck and all traffic is sent to port 80 which presumably functions the same way as 31141.

A curious note is that if I try to reach the node IP at port 80 from a pod I only get "connection refused", but I suppose it does work if traffic comes from a load balancer.

I was not able to find any information about this on internet, so the question is how this really works and why is ALB doing it this way?

P.S. I don't have troubles with connectivity, it works. I am just trying to understand how and why it does behind the scenes.


Solution

  • I think I have figured out how that works (disclaimer: my understanding might not be correct, please correct me if it's wrong).

    What happens is that load balanced traffic does not reach the node itself on port 80 nor does it reach it on an opened node port (31141 in my case). Instead the traffic that is sent to the node is not "handled" by the node itself but rather routed further with the help of iptables. So if some traffic hits the node with the destination IP of the LB frontendIP and port 80 it goes to the service and further to the pod.

    As for health check I suppose it does not use the same port 80 because the request would not have a destination equal to the external IP (LB frontend IP) and rather the node itself directly, then it uses the service nodePort for that reason.