Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Kubernetes Consulting

Choosing and Deploying an Ingress Controller: NGINX, ALB or Application Gateway

An ingress controller routes external traffic into your cluster by host and path, and terminates TLS. We help you choose between NGINX, the AWS Load Balancer Controller and Azure Application Gateway, then deploy it with certificates, health checks, scaling and security headers configured and tested.

Key takeaways

  • The choice is between in-cluster proxy (NGINX) and cloud-native load balancer integration (ALB, Application Gateway).
  • Cloud load balancers offer managed scaling and WAF integration, while NGINX offers portability and rich annotations.
  • TLS certificates should be automated with cert-manager or the cloud's certificate service, never renewed by hand.
  • Ingress needs the same care as any production service: replicas, disruption budgets, resources and monitoring.
  • Gateway API is the successor to Ingress, so new designs should consider it.

Why ingress is a decision, not a default

Every cluster that serves users needs a way in. Many teams install whatever the first tutorial used, and then live with it: surprise load balancer bills, TLS certificates that expire on a Sunday, or a single proxy deployment that becomes the bottleneck for everything.

Choosing and configuring an ingress controller is a small piece of work with an outsized effect on reliability and security. It is part of our Kubernetes consulting service, usually done alongside cluster architecture so networking and edge design agree with each other.

Two families of controller

In-cluster proxies such as NGINX run as pods. A cloud load balancer (usually layer 4) forwards traffic to them, and they route by host and path. You operate scaling, upgrades and tuning, in return for portability and rich behaviour.

Cloud-integrated controllers such as the AWS Load Balancer Controller and Azure’s Application Gateway options translate Kubernetes objects into managed load balancer configuration. The cloud operates the data plane, and you get native WAF and certificate integration, in return for tighter cloud coupling and fewer exotic features.

ConcernNGINXAWS ALB controllerAzure Application Gateway
Who runs the data planeYou (pods)AWS (ALB)Azure
Portability across cloudsHighAWS onlyAzure only
WAF integrationAdd-on (ModSecurity)AWS WAFBuilt in (WAF tier)
Advanced rewrites and annotationsExtensiveLimitedModerate
Typical cost shapeCompute plus one load balancerPer ALB plus capacity unitsGateway plus capacity units
Direct to pod routingVia proxyIP target modeYes

One caution before choosing NGINX: the community ingress-nginx project has been announced for retirement in 2026. Check the current state, and consider alternatives or Gateway API implementations for new work.

How we decide

We ask a short list of questions:

  1. Are you single cloud and likely to stay? If yes, native integration reduces what you operate.
  2. Do you need WAF, DDoS protection or private link style connectivity? Cloud controllers make these easier.
  3. Do you rely on rewrites, rate limiting, auth subrequests or canary routing that annotations make easy?
  4. How many load balancers will you create? Per-ingress ALBs add up, so grouping ingresses onto a shared ALB is an important setting.
  5. Does your team already know one of these?

The answer is often “ALB on EKS, Application Gateway on AKS, and NGINX where portability or behaviour matters”. We record the reasoning, so a later engineer understands why.

What a sound setup contains

  • High availability. At least two replicas across zones, a pod disruption budget and sensible requests, because ingress pods restarting is customer visible downtime.
  • Automated TLS. cert-manager issuing from an ACME provider, or the cloud’s certificate service.
  • DNS automation. external-dns creates records from Ingress objects so hostnames do not depend on a ticket.
  • Timeouts and body limits matching real application behaviour, since defaults surprise teams with file uploads and long polling.
  • Security headers and TLS policy set deliberately, with old protocol versions disabled.
  • Observability. Request rate, error rate, latency and certificate expiry exported to Prometheus.

A concrete example

An AWS Load Balancer Controller ingress sharing one ALB across services, with TLS from ACM:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: public
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:REGION:ACCOUNT_ID:certificate/CERT_ID
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80

The group.name annotation lets multiple ingresses share one load balancer, which keeps cost down. The ARN is shown with obvious placeholders, as it would be filled from Terraform outputs in your repository.

On NGINX, the equivalent adds cert-manager through an annotation such as cert-manager.io/cluster-issuer and a tls block in the spec.

Worked example: planning a migration between controllers

Replacing an ingress controller on a live cluster is common, especially if you are moving off a controller that is being retired. The safe pattern is to run both side by side. Install the new controller with its own ingress class and its own load balancer, then recreate a low-risk route against it using a test hostname. Compare responses, headers, timeouts and TLS behaviour with the old path.

Cutover happens in DNS, not in the cluster: lower the record TTL ahead of time, move one hostname at a time, and keep the old route in place until traffic has drained. Rolling back is then a DNS change rather than an emergency redeploy. Annotations rarely translate one to one between controllers, so we list every annotation in use and decide for each whether the new setup supports it, replaces it or no longer needs it.

Trade-offs and failure modes

  • One ALB per ingress. The default creates many load balancers. Grouping fixes it.
  • Health check mismatch. The load balancer checks a path that returns an error until the app warms up, so new pods never receive traffic. Align readiness probes and load balancer health checks.
  • Draining on deploy. Without a graceful shutdown delay, users see dropped connections during rollouts. A short preStop sleep plus deregistration delay solves most cases.
  • Single controller as a shared fate. One bad annotation can break every team’s routing. Admission validation helps.
  • Wide open backends. Ingress exposes services, network policy limits what else can reach them.
  • Overbuilding. A single small app does not need a service mesh gateway and a WAF.

Delivery and handover

You get the controller installed as code, certificate and DNS automation, dashboards and alerts, a load test of the edge path, and a runbook for failures such as expired certificates and 502 or 504 errors. It is working when a new service gets a hostname and valid TLS from a pull request, rolling deployments cause no 5xx spikes, and certificate expiry is something dashboards track rather than people. See monitoring for the supporting metrics, or contact us to compare options for your stack.

References

How we deliver it

  1. 01

    Gather traffic requirements

    We capture protocols, hostnames, expected traffic shape, WAF and compliance needs, and where TLS must terminate.

  2. 02

    Select the controller

    We compare NGINX, ALB and Application Gateway against your cloud, team and features, and document the decision.

  3. 03

    Deploy with infrastructure as code

    The controller, its cloud permissions and load balancer settings are installed through Terraform and Helm.

  4. 04

    Automate certificates and DNS

    cert-manager or cloud certificate services issue and renew TLS, and DNS records follow ingress objects.

  5. 05

    Harden and scale

    Replicas, disruption budgets, timeouts, rate limits and security headers are tuned and load tested.

  6. 06

    Monitor and document

    Dashboards and alerts cover error rate, latency and certificate expiry, with a runbook for common failures.

Tools and technologies

ingress-nginxAWS Load Balancer ControllerAzure Application Gateway for ContainersAGICcert-managerexternal-dnsAWS WAFGateway APIHelmTerraformPrometheus

Frequently asked questions

NGINX ingress or AWS Load Balancer Controller?
The AWS Load Balancer Controller provisions managed ALBs, which scale without you operating proxy pods and integrate with WAF, ACM and Shield. NGINX runs in the cluster, is portable across clouds and offers extensive annotations and rewrites. Pick ALB for AWS-native simplicity, NGINX for portability or advanced routing.
Is ingress-nginx still the right choice?
Check its current status before committing. The Kubernetes project has announced retirement of the community ingress-nginx project, with maintenance ending in 2026, so new builds should weigh alternatives such as other NGINX distributions, cloud controllers or Gateway API implementations. Verify the latest announcement when you decide.
What is the difference between Ingress and Gateway API?
Ingress is the original, simple HTTP routing resource, with controller-specific behaviour hidden in annotations. Gateway API is its more expressive successor, separating infrastructure roles from application routes and supporting more protocols. Many controllers now support it, and we recommend considering it for new clusters.
How do we automate TLS certificates?
Use cert-manager with an ACME issuer such as Let's Encrypt, or use the cloud's certificate service, for example ACM on AWS or Key Vault on Azure. Either way, renewal is automatic, and you alert on expiry anyway as a safety net. Manually uploaded certificates are a common cause of outages.
Do we need a WAF in front of the cluster?
If the application is internet facing and handles sensitive data or faces automated abuse, a WAF is a worthwhile layer. AWS WAF attaches to ALBs, and Azure Application Gateway includes a WAF tier. A WAF complements secure code, not replaces it, and needs tuning to avoid blocking real users.
Can one ingress controller serve many teams?
Yes, with an ingress class per tenant or a shared controller and policy on which hosts each namespace may claim. A shared controller is cheaper but a bad config from one team can affect all. For stricter isolation, run separate controllers or load balancers per environment or tenant.

Talk to an engineer about kubernetes ingress controller setup

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.