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"=trueTwo 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
- Architecture audit — cluster assessment, network connectivity scheme, bottleneck identification.
- Installation and customization — Helm chart, ConfigMap tailored to your tasks, L4 balancing scheme selection.
- TLS automation — cert-manager, ClusterIssuer, Let's Encrypt / internal CA.
- Monitoring and alerting — Prometheus + Grafana, dashboards, alerts on 502/503.
- Documentation and training — README, runbook for common failures, access to our scripts.
- 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.







