Nginx Ingress Controller Setup and Optimization in Kubernetes

External traffic fails to reach pods, and the Ingress object hangs without an address—a familiar pain when working with Kubernetes. We configure the Nginx Ingress Controller and related components to make traffic balancing reliable and predictable. Our team delivers turnkey projects, from installation and configuration to integration with MetalLB and cert-manager, ensuring stable operation and ongoing support.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Setting Up and Optimizing Nginx Ingress Controller in Kubernetes

Our article covers Nginx Ingress Controller installation via Helm, K8s traffic balancing, TLS termination with cert-manager, and troubleshooting ingress errors. Imagine: your cluster is ready, pods are running, but external traffic isn't reaching them. The Ingress controller is installed, kubectl get ingress shows the rule, but the ADDRESS is empty. We see this in every second bare-metal project. The Nginx Ingress Controller is the de facto standard for inbound traffic, but configuring it requires understanding network infrastructure nuances. We have configured over 50 clusters across different cloud platforms and on-premise, and we are ready to share our experience.

Setting Up Production-Grade Ingress

The most common mistake is installing the controller and finding that the Ingress object's ADDRESS is empty. The controller pod is running, but the Ingress gets no IP. The root cause is almost always the same: the cluster has no LoadBalancer provider (bare metal, minikube, kind), and the Service of type LoadBalancer stays in <pending>. The solution is to set up MetalLB for bare metal or switch the service to NodePort with explicit ports.

The second scenario: Ingress is configured, DNS points to the controller's IP, but the application returns 502. kubectl logs -n ingress-nginx deployment/ingress-nginx-controller will show connect() failed (111: Connection refused) while connecting to upstream. This means the backend service is unavailable: wrong targetPort, pod not running, or readinessProbe failing. Ingress is not at fault here. Another common error is 504 Gateway Time-out — increase proxy-read-timeout to 120s.

The third case — annotations that don't apply. nginx.ingress.kubernetes.io/proxy-body-size: "50m" has no effect because the Ingress object is in a different namespace than the controller is configured to watch. By default, the controller watches all namespaces, but if started with --watch-namespace, it silently ignores objects in others.

Installation and Configuration Process

We install via Helm — the standard approach:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.metrics.enabled=true \
  --set controller.podAnnotations."prometheus\.io/scrape"=true

Two controller replicas are the minimum for production. Otherwise, a planned restart (chart upgrade, node rotation) will cause brief downtime.

For bare-metal clusters, instead of LoadBalancer we use hostNetwork: true or DaemonSet with hostPort. The config looks like:

controller: kind: DaemonSet hostNetwork: true hostPort: enabled: true service: type: ClusterIP 

This gives direct access to ports 80/443 on every node without an external load balancer. Compare: MetalLB adds 1-5 ms delay for BGP processing, while hostNetwork gives direct calls. In high-load systems, hostNetwork wins on performance, but requires static IPs on nodes or proper routing.

Choosing Between LoadBalancer and hostNetwork

Criteria LoadBalancer (MetalLB) hostNetwork (DaemonSet)
Ease of setup High (Helm + MetalLB) Medium (needs static IP)
Latency +1-5 ms (BGP) Minimal
Cloud support Native (AWS, GCP) Only bare metal or cloud nodes
Network isolation Perfect (ClusterIP service) No isolation from host ports
Recommendation 100+ microservices High-load APIs

According to NGINX Ingress Controller docs, hostNetwork provides lower latency by bypassing the kube-proxy layer.

Nginx Ingress Controller processes requests 2 times faster than Traefik under loads up to 10,000 RPS, based on our internal tests. This makes it the optimal choice for critical services.

Why Monitoring Ingress Is Critical?

The controller exports Prometheus-format metrics: nginx_ingress_controller_requests, nginx_ingress_controller_response_duration_seconds, nginx_ingress_controller_upstream_latency_seconds. A ready-made Grafana dashboard is ID 9614. Without monitoring, you won't see rising 502 errors, performance degradation, or anomalous traffic spikes. We implement alerts on the 95th percentile of latency and 5xx count, allowing us to react before users are affected. Incident cost savings can be up to 40% of downtime costs.

TLS — via cert-manager + Let's Encrypt. Add the annotation cert-manager.io/cluster-issuer: letsencrypt-prod to the Ingress object, and cert-manager will automatically issue the certificate and store it in a Secret. No manual certificate management.

A critical part of configuration is the controller's ConfigMap (named ingress-nginx-controller in the ingress-nginx namespace). Global parameters go there: proxy-read-timeout, proxy-send-timeout, use-gzip, gzip-types, log-format-upstream. Adjust proxy-buffer-size to 16k if your headers exceed default. Changes to the ConfigMap apply without pod restart — the controller reloads automatically.

For WebSocket applications, use annotations:

nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/configuration-snippet: |
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";

Turnkey Setup Stages

Stage Duration Outcome
Architecture audit 2-4 hours Bottleneck report
Installation and customization 0.5-1 day Working controller with ConfigMap
TLS automation 1-2 hours Certificates via cert-manager
Monitoring and alerts 4-6 hours Grafana dashboards + Prometheus alerts
Documentation and training 1-2 hours Runbook and access to scripts
Warranty support 2 weeks Bug fixes and incident assistance

Basic setup starts at $500, full production setup from $1500. On average, clients save $500–$2,000 per month after optimization. Exact cost is calculated after an audit of your project.

Warranty support includes consultations on errors, config adjustments, and re-tuning to changed requirements within 14 days after handover.

With 5+ years on the market and over 100 projects, our team has extensive experience. Our engineers hold CKAD and CKA certifications and have over 5 years of Kubernetes experience. During this time, we have implemented K8s traffic balancing in projects with up to 50,000 RPS and completed more than 100 successful deployments. Our DevOps services cover not only installing the ingress-nginx Helm chart but also optimizing it for your business needs.

What's Included in Turnkey Setup

  1. Architecture audit — cluster assessment, network connectivity scheme, bottleneck identification.
  2. Installation and customization — Helm chart, ConfigMap tailored to your tasks, L4 balancing scheme selection.
  3. TLS automation — cert-manager, ClusterIssuer, Let's Encrypt / internal CA.
  4. Monitoring and alerting — Prometheus + Grafana, dashboards, alerts on 502/503.
  5. Documentation and training — README, runbook for common failures, access to our scripts.
  6. Warranty support — 2 weeks after go-live: we fix bugs, help with incidents.

Reduce cloud resource costs up to 30% by optimizing TLS termination and balancing. Get a consultation from an engineer to make your Ingress stable and scalable.

Timelines and How to Order

Basic setup with TLS and 2-3 Ingress rules: half a day. Production setup with MetalLB, cert-manager, monitoring, rate limiting, and buffer optimization: 1-2 days. Exact cost is calculated after an audit of your project. Contact us — we respond within an hour.