Skip to content

Ingress Controllers

First PublishedByAtif Alam

Ingress is only an API object. An Ingress Controller is the component that watches those objects and programs real data-plane behavior (load balancer rules, proxy config, TLS settings).

Use this guide when you need to choose a controller, wire TLS/mTLS, and troubleshoot ingress behavior in production.

ControllerBest fitNotes
NGINX Ingress ControllerGeneral-purpose Kubernetes ingressMature ecosystem, rich annotations, common in self-managed clusters.
TraefikSimpler dynamic config and CRD-first workflowsGood developer ergonomics; common in platform teams that prefer Traefik CRDs.
AWS Load Balancer ControllerEKS with native ALB/NLB integrationCreates AWS resources from Kubernetes objects; strong fit for AWS-native edge integration.

Client TLS terminates at the ingress edge (ALB, NLB+TLS, NGINX, Traefik), then traffic continues to backends over HTTP or re-encrypted HTTPS.

Use when:

  • You want centralized cert handling and simpler app configs.
  • You need host/path routing and policy at the edge.

TLS stays encrypted through the ingress layer and is terminated by the backend service.

Use when:

  • The application must own certificates directly.
  • You need end-to-end TLS visibility at the workload tier.

Trade-off: less L7 visibility and fewer routing features at ingress.

The client presents a certificate; ingress validates it against a trusted CA bundle.

Typical use:

  • B2B APIs
  • Admin endpoints
  • Internal service entrypoints with strict client identity

Ingress presents a client cert to upstream services, and upstream verifies it.

Typical use:

  • Zero-trust internal boundaries
  • Compliance-driven encryption and identity between tiers

cert-manager automates certificate issuance and renewal in-cluster.

Core resources:

  • Issuer / ClusterIssuer: where certs come from (ACME, Vault, private PKI).
  • Certificate: desired cert config; resulting keypair lands in a Secret.
  • Secret: consumed by ingress for TLS/mTLS.

High-level flow:

  1. Install cert-manager and create Issuer or ClusterIssuer.
  2. Create Certificate resources for ingress hostnames.
  3. Reference the generated TLS Secret in Ingress.
  4. Verify renewal before expiry and alert on failures.

See:

  1. Controller running? Check deployment/pods and controller logs.
  2. Ingress class correct? ingressClassName matches the installed controller.
  3. TLS secret present? Secret name and namespace are correct.
  4. Certificate valid? SAN/CN match host; chain is complete; cert not expired.
  5. Client trust aligned? mTLS CA bundle on ingress matches client cert issuer.
  6. DNS and SNI correct? Host resolves to ingress edge and requested SNI matches cert.
  7. Backend protocol consistent? Avoid accidental double TLS or protocol mismatch.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
ingressClassName: nginx
tls:
- hosts: ["app.example.com"]
secretName: app-example-com-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app
port:
number: 80
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-example-com
spec:
secretName: app-example-com-tls
dnsNames:
- app.example.com
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod