# nginx/kubernetes-ingress: the NGINX-maintained Ingress Controller for Kubernetes

> NGINX Ingress Controller is the vendor-built controller that runs NGINX or NGINX Plus inside a pod and configures it from Ingress, VirtualServer and TransportServer resources. It is the right tool when you want NGINX semantics and NGINX Plus features in Kubernetes, and the wrong one when you want a controller with no vendor line behind it.

**nginx/kubernetes-ingress** — NGINX and  NGINX Plus Ingress Controllers for Kubernetes

- Repository: https://github.com/nginx/kubernetes-ingress
- Website: https://docs.nginx.com/nginx-ingress-controller
- Stars: 5,079 · Forks: 2,051
- Language: Go
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/nginx-kubernetes-ingress

## What nginx/kubernetes-ingress actually does

A Kubernetes Ingress resource is only a declaration. Something has to watch it and rewrite a real load balancer's configuration. This repository is that something for NGINX. The controller runs inside a pod alongside NGINX, so the load balancer and the process reconfiguring it share a container.

Out of the box it handles what the standard Ingress resource supports: host-based routing, path-based routing and TLS termination per hostname. Beyond that it exposes NGINX and NGINX Plus features through annotations on Ingress resources and through a ConfigMap. The README points at two documentation pages for that surface, one for the ConfigMap resource and one for advanced configuration with annotations.

It also goes past HTTP. The README states that Websocket, gRPC, TCP and UDP applications can be load balanced. The audience is platform teams that already understand NGINX and do not want to relearn routing semantics in a different proxy. If you have never written an nginx.conf and have no intention of starting, the annotation surface will feel like a second configuration language layered on top of Kubernetes.

## VirtualServer, VirtualServerRoute and TransportServer as the escape hatch from Ingress

The Ingress resource has a ceiling. Traffic splitting and advanced content-based routing are not expressible in it, and the README says so directly. The project's answer is two custom resources, VirtualServer and VirtualServerRoute, which the README describes as enabling use cases the Ingress resource does not support.

For non-HTTP traffic there is a third resource, TransportServer, documented for TCP, UDP and TLS passthrough load balancing. That is a meaningful architectural split: three resource types, three configuration paths, one controller process watching all of them. The cost is that a team moving from another controller has to decide per route which resource type to use, and custom resources mean CRDs installed in the cluster before anything referencing them will apply.

The design choice here is defensible but not free. Annotations on Ingress keep you inside a portable Kubernetes API at the price of string-typed configuration. VirtualServer gives you a typed schema at the price of a resource that only this controller understands. Pick per workload, not per cluster.

## Installing NGINX Ingress Controller and routing a first request

The README's Getting Started section gives two installation routes: the Helm chart, or the Kubernetes manifests. Both are documented on docs.nginx.com rather than in the repository itself. The README adds a note that all documentation should be used with the latest stable release indicated on the releases page, which matters because the annotation and ConfigMap surface moves between minor versions.

The repository ships a charts/ directory and a deploy/ directory, consistent with those two paths. The README links the Helm chart at https://docs.nginx.com/nginx-ingress-controller/install/helm/, which is where the install commands and chart values live; the repository does not reproduce them.

After the release settles, the controller pod should be running in the namespace you installed into, and the chart's Service should have an external address on a cluster that can provision one. The next step is a workload to route to. The README points at the Cafe example under examples/ingress-resources/complete-example for the Ingress path and a basic configuration example for the VirtualServer path.

Once an Ingress exists that selects your Service, requests to the host you declared should reach the backend. If they do not, the first thing to check is whether the controller is watching the Ingress class you set. The README does not document the class-matching behaviour inline; that lives in the configuration documentation, so treat the class field as something to confirm rather than assume.

## Where this controller is the wrong choice

The README carries a note that this project is different from the NGINX Ingress Controller in the kubernetes/ingress-nginx repository. That sentence is doing more work than it looks like. Two projects, both called some variant of NGINX Ingress Controller, both under the NGINX organisation's orbit, with different codebases, different annotation sets and different release cadences. Copying an annotation from a blog post written about the other one will silently do nothing here.

The second limitation is the NGINX Plus split. Several features are Plus-only, and the README links to a separate page about NGINX Ingress Controller with NGINX Plus. The Makefile confirms the build is parameterised between NGINX OSS and NGINX Plus, with NGINX_OSS_VERSION and NGINX_PLUS_VERSION as separate variables and separate package repositories. If you read a feature in the docs and cannot find it in your OSS deployment, that is usually why.

The third is operational weight. You are running NGINX, not a purpose-built Go proxy. That is the point, but it means your debugging surface includes nginx.conf as generated by the controller, and the controller's own logs. Teams that want a single log stream and no proxy config to reason about will find this heavier than they want.

## How it differs from the Kubernetes community ingress-nginx controller

The obvious alternative is kubernetes/ingress-nginx, the community controller the README explicitly distinguishes this project from. The difference is not feature parity, it is governance and configuration model.

The community controller is a Kubernetes project. This one is built and released by the people behind NGINX, ships an LTS release line (2026-lts-r8 sits alongside v5.6.3 in the recent releases), and offers commercial support, which the README signals with a support badge. That LTS line is the concrete difference for an operations team: a version you can pin for a long window rather than tracking minor releases.

The configuration model differs too. This project adds VirtualServer, VirtualServerRoute and TransportServer as first-class resources. A controller that only speaks Ingress cannot express traffic splitting without annotation gymnastics or a service mesh. If your routing needs stop at host and path, the extra resource types are unused surface area; if they do not, they are the reason to pick this one.

## Maintenance, licensing and what an upgrade actually costs

The repository is not archived and the last push was on 2026-09-22, one day before this writing. Releases are frequent: v5.6.3 and 2026-lts-r8 both landed on 2026-09-16, with v5.6.2 the day before. The README's own status badge describes the project as having reached a stable, usable state and being actively developed.

The licence is Apache-2.0, which covers the controller code in this repository. It does not cover NGINX Plus, which is a commercial product sold separately, nor the NGINX App Protect modules referenced in the Makefile variables. Running the OSS build is an Apache-2.0 exercise; running the Plus build brings a subscription into the picture. That is a distinction worth confirming with whoever holds the budget, not something to infer from the repository licence file.

Upgrade cost is dominated by the annotation and ConfigMap surface, which is versioned alongside the controller rather than being a stable Kubernetes API. The repository's test markers in pyproject.toml list a long tail of feature areas (appprotect, policies, oidc, rewrite, upgrade among them), which tells you how much behaviour is covered by the project's own test suite and, by extension, how much can shift between releases. The 2026-lts-r8 line exists precisely so you do not have to absorb that drift continuously.

## Conclusion

Adopt it if you already run NGINX or NGINX Plus, need TCP, UDP or TLS passthrough load balancing, or want VirtualServer traffic splitting that plain Ingress cannot express. Do not adopt it if you have standardised on Gateway API or want a controller with no vendor support contract behind it. Before you commit, verify which release line you are pinning (v5.6.3 or 2026-lts-r8), confirm your cluster's Kubernetes version against the release you pick, and read the Helm chart values rather than assuming defaults.

## FAQ

### What is the difference between nginx/kubernetes-ingress and the kubernetes/ingress-nginx controller?

They are separate projects with separate codebases. The README carries an explicit note that this project is different from the NGINX Ingress Controller in the kubernetes/ingress-nginx repository, so annotations and configuration written for one do not carry over to the other.

### How do I install and set up nginx/kubernetes-ingress?

The README's Getting Started section gives two routes: the Helm chart or the Kubernetes manifests, both documented on docs.nginx.com. It also notes that the documentation should be used with the latest stable release shown on the releases page.

### What is Kubernetes Ingress used for in this project?

It configures an HTTP load balancer for applications running on Kubernetes, represented by one or more Services. This controller supports content-based routing (host and path) plus TLS/SSL termination per hostname for the Ingress resource.

### What is a Kubernetes Ingress resource in nginx/kubernetes-ingress?

It is a Kubernetes resource that lets you configure an HTTP load balancer for applications running on Kubernetes. This controller implements it for NGINX and NGINX Plus, adding annotations and a ConfigMap for extra features.

### Should I use Ingress or Gateway API with nginx/kubernetes-ingress?

The README does not document Gateway API support. It documents the Ingress resource plus the VirtualServer, VirtualServerRoute and TransportServer custom resources as the way to reach use cases Ingress cannot express, such as traffic splitting.

## Sources

- [License: Apache-2.0](https://github.com/nginx/kubernetes-ingress/blob/main/LICENSE)
- [nginx/kubernetes-ingress on GitHub](https://github.com/nginx/kubernetes-ingress)
- [Project website](https://docs.nginx.com/nginx-ingress-controller)
- [README](https://github.com/nginx/kubernetes-ingress/blob/main/README.md)
- [Releases](https://github.com/nginx/kubernetes-ingress/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nginx-kubernetes-ingress
