Ingress Controllers
A K8s component that allows external traffic into our cluster.
Definition
An Ingress controller is a specialized load-balancer that manages external access to Services within a K8s cluster, typically providing HTTP and HTTPS routing. Simply put, it is a set of rules (a configuration file). It is the actual software (the "engine") that reads these rules and carries out the traffic routing. It can be both a load-balancer and a reverse-proxy simultaneously.
On the other hand, a K8s Service (like NodePort or LoadBalancer) handles basic traffic routing inside our clusters between pods.
How Ingress Controller work
| # | Step | Activity | Resides |
|---|---|---|---|
1 |
Service of type |
The K8s Service that fronts the Ingress Controller pod(s) requests a cloud-provider load-balancer. The provider creates a public IP/DNS name. |
Cloud-provider LB → Ingress Controller Pod |
2 |
Ingress Controller pod (NGINX, HAProxy, Envoy, Traefik, …) |
The controller runs a revers-proxy server. It watches all |
reverse-proxy logic inside the pod |
3 |
Proxy→Service |
The reverse-proxy forwards the request (HTTP/HTTPS, gRPC, etc.) to the target K8s Service (ClusterIP) that selects the backend Pods. |
Proxy → ClusterIP Service → Pods |
So the external LoadBalancer distributes inbound connections across the actual Ingress Controller Pods, while the reverse-proxy inside each pod does the actual HTTP routing to our workloads.
| Name | Primary proxy engine | Notable features | Typical use cases | Typical LoadBalancer integration |
Why |
|---|---|---|---|---|---|
NGINX (commercial-features) |
Rich annotations, extensive community support, robust TLS & JWT handling |
General purpose, works on most clouds and on-perms |
Deploys a |
It has a
|
|
HAProxy |
Native TCP/UDP support, advanced rate-limiting, connection-pooling, easy to enable HAProxy Enterprise features |
High-performance, latency-sensitive workloads |
Same patterns - a LoadBalancer Service in front of HAProxy load-balancer. |
|
|
Traefik |
Built-in Let’s Encrypt, dynamic configuration via CRDs, middleware pipeline, good for microservice meshes |
Cloud-native stacks, easy TLS automation |
It can expose itself with a |
|
|
NGINX-based |
Plugin ecosystem (authentication, rate-limiting, logging), Kong Enterprise integration |
API-first platforms, need plugin extensibility |
|||
https://[Istio Gateway] |
Envoy (via Istio) |
Full service-mesh capabilities, advanced traffic management, mTLS, fault injection |
Environment already using Istio or needing mesh-wide policies |
The Gateway runs as a Deployment behind a |
|
AWS ALB/NLB |
Directly provisions AWS Application Load Balancers from Ingress resources, supports target-group health checks |
Clusters running on AWS, want native ALB/NLB features |
|||
GCE L7 load balancer |
Managed by Google Cloud, automatic SSL cert provisioning via Google Managed Certificates |
Google cloud-only deployments |
Good for
All the above, table-1, are battle-tested in large-scale production environments.
- Runtime performance
-
HAProxy & Nginx are classic high-throughput choices.
- Feature set
-
Traefik and Kong excel in middleware and plugins; Istio provides
- Cloud integration
-
Cloud-specific controllers
Protocol support
| Protocol/use-case | Can a typical Ingress controller route it? | How it’s usually done? | |
|---|---|---|---|
HTTP/HTTPS(REST, graphQL, gRPC-HTTP/2) |
✅Yes, most Ingress controllers (NGINX, HAProxy, Kong, Traefik, Istio Gateway) understand HTTP/2 and can terminate TLS, then forward the stream to the backend service. gRPC works because it is just HTTP/2 with a different content-type ( |
Use an |
✅ |
Pure gRPC (non-HTTP/2-aware proxies) |
❌Not directly - the Ingress resource is defined for Layer 7 (HTTP) traffic. If the underlying proxy can terminate HTTP/2 and forward the gRPC payload, it works; otherwise you need a Gateway (e.g., Istio Gateway or a dedicated gRPC-proxy such as Envoy). |
Deploy an Envoy or Istio gateway that advertises the gRPC ports, and expose it via a Service of type |
❌ |
GraphQL over HTTP |
✅Yes, GraphQL is just an HTTP POST (or WebSocket) request, so any HTTP-aware Ingress works. |
No special configuration beyond normal HTTP rules; you may want to enable WebSocket support ( |
✅ |
UDP(e.g., DNS, SIP, FTP data channel) |
❌Not with the standard Ingress API, because Ingress is defined only for L7 HTTP(S) traffic. Some controllers (HAProxy, NGINX Plus) expose additional CRDs (e.g., |
For UDP we typically: 1. Create a |
❌ |
FTP (control + data channels) |
❌Not via standard Ingress. FTP uses both TCP control (port 21) and a dynamic data channel (active/passive ports). You need a LoadBalancer Service for the control port and configure the data-port range via a Service or a dedicated FTP-proxy pod. |
Use a StatefulSet with a |
❌ |
Step |
Action |
Commands |
|
Deploy the controller |
Installation is possible using |
|---|---|
|
|
Confirm Pods are running |
Check the health of controller pods |
|
|
Check the Service |
Verify the external IP (LoadBalancer) or node ports |
|
|
Create a test Ingress object |
Creating a simple rule pointing to a Service |
|
|
Client-side testing |
Observe routing using |
|
|
TLS verification |
Checking for TLS; CRTs |
|
|
Logs & metrics |
Check Pods' logs; or metrics in Prometheous |
|
|
Debug config |
Read the generated proxy config (e.g., NGINX config) to ensure rules are applied |
|
|
FAQ
-
Is
Envoyan Ingress controller?-
It can act as one, but it is not the default
K8s Ingressimplementation. -
When an
Envoyruns behind a K8sServiceof type LoadBalancer and configure it viaIstio Gateway CRD,Kong-mesh, or theNGINX-likeIngressCRD offered by Envoy-Ingress-Controller project, Envoy becomes the data plane that fulfills theIngresssemantics. -
In the
Istioecosystem, the Istio Gateway (which runsEnvoyinternally) is the production-grade replacement for a generic Ingress Controller and can handle HTTP, gRPC, TCP, and UDP traffic.
-
-
Layer-7 vs. Layer-4
-
Ths standard K8s Ingress Controller contracts just require Layer-7 support (meaning that HTTP and HTTPS)
-
A couple of Ingress Controllers (e.g., HAProxy or NGINX Plus) extend the model via supporting
TCPIngress,UDPIngressto expose Layer 4 TCP and UDP. -
For a pure Layer 4 (raw TCP/UDP, FTP, DNS, etc.), the usual pattern is exposing via a K8s
Serviceof typeLoadBalancerorNodePortand let the cloud provider’s handle the traffic, or running a specialized controller that supports those CRDs.
-
-
A K8s
Servicedefines a stable Virtual IP (CLusterIP) and DNS name that load-balances traffic inside the cluster to the set of Pods selected by its selector. The traffic never leaves the cluster network unless theServicetype isNodePortorLoadBalancer. -
Pods in different namespaces can reach each other if they know the appropriate DNS name or IP. A
Servicecreated in one namespace is reachable from another namespace by using the fully-qualified name:=== <service-name>.<namespace>.svc.cluster.local ===-
Thus a Service can serve Pods from a namespace to another Services/Pods inside another namespace via
ExternalNameor by selecting the same label set. -
Network Policies may restrict the communication, but from a pure networking standpoint is allowed.
-
-
An Ingress Controller watches
Ingressresources and configures a load-balancer or reverse-proxy that accepts incoming traffic from outside the cluster and routes it to the appropriateServiceinside the cluster. It is entry point for external clients. -
An Ingress Controller can be both a load-balancer and a reverse-proxy simultaneously.