kubernetes-ingress Documentation

NGINX and NGINX Plus Ingress Controllers for Kubernetes

5,057 stars Go Go 1 file ยท ~5,433 tokens #docker#go#golang#ingress#ingress-controller#k8s#kubernetes#nginx
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy kubernetes-ingress on any server, homelab, or cloud container platform.

File: README.md







NGINX Ingress Controller

This repo provides an implementation of an Ingress Controller for NGINX and NGINX Plus from the people behind NGINX.


Join The Next Community Call

We value community input and would love to see you at the next community call. At these calls, we discuss PRs by community members as well as issues, discussions and feature requests.

Zoom: NGINX Ingress Controller - Community Call

Meeting ID: 985 4405 5687

Passcode: 982193

When: 16:00 GMT / Convert to your timezone, every other Monday.

Community Call Dates
2026-07-13
2026-07-27
2026-08-10
2026-08-24
2026-09-07
2026-09-21
2026-10-05
2026-10-19
2026-11-02
2026-11-16
2026-11-30
2026-12-14

You can also join the NGINX Community Forum to chat about the NGINX Ingress Controller.


NGINX Ingress Controller works with both NGINX and NGINX Plus and supports the standard Ingress features - content-based
routing and TLS/SSL termination.

Additionally, several NGINX and NGINX Plus features are available as extensions to the Ingress resource via annotations
and the ConfigMap resource. In addition to HTTP, NGINX Ingress Controller supports load balancing Websocket, gRPC, TCP
and UDP applications. See
ConfigMap and
Annotations
docs to learn more about the supported features and customization options.

As an alternative to the Ingress, NGINX Ingress Controller supports the VirtualServer and VirtualServerRoute resources.
They enable use cases not supported with the Ingress resource, such as traffic splitting and advanced content-based
routing. See VirtualServer and VirtualServerRoute resources
doc
.

TCP, UDP and TLS Passthrough load balancing is also supported. See the TransportServer resource
doc
.

Read this doc to learn more about NGINX Ingress
Controller with NGINX Plus.

Note

This project is different from the NGINX Ingress Controller in
kubernetes/ingress-nginx repo.

Ingress and Ingress Controller

What is the Ingress?

The Ingress is a Kubernetes resource that lets you configure an HTTP load balancer for applications running on
Kubernetes, represented by one or more Services.
Such a load balancer is necessary to deliver those applications to clients outside of the Kubernetes cluster.

The Ingress resource supports the following features:

  • Content-based routing:
    • Host-based routing. For example, routing requests with the host header foo.example.com to one group of services
      and the host header bar.example.com to another group.
    • Path-based routing. For example, routing requests with the URI that starts with /serviceA to service A and
      requests with the URI that starts with /serviceB to service B.
  • TLS/SSL termination for each hostname, such as foo.example.com.

See the Ingress User Guide to learn more about the
Ingress resource.

What is the Ingress Controller?

The Ingress Controller is an application that runs in a cluster and configures an HTTP load balancer according to
Ingress resources. The load balancer can be a software load balancer running in the cluster or a hardware or cloud load
balancer running externally. Different load balancers require different Ingress Controller implementations.

In the case of NGINX, the Ingress Controller is deployed in a pod along with the load balancer.

Getting Started

Note

All documentation should only be used with the latest stable release, indicated on the releases
page
of the GitHub repository.

  1. Install NGINX Ingress Controller using the Helm
    chart
    or the Kubernetes
    manifests.
  2. Configure load balancing for a simple web application:
  3. See additional configuration examples.
  4. Learn more about all available configuration and customization in the
    docs.

NGINX Ingress Controller Releases

We publish NGINX Ingress Controller releases on GitHub. See our releases
page
.

The latest stable release is 5.5.4. For production
use, we recommend that you choose the latest stable release.

The edge version is useful for experimenting with new features that are not yet published in a stable release. To use
it, choose the edge version built from the latest
commit
from the main branch.

To use NGINX Ingress Controller, you need to have access to:

  • An NGINX Ingress Controller image.
  • Installation manifests or a Helm chart.
  • Documentation and examples.

It is important that the versions of those things above match.

The table below summarizes the options regarding the images, Helm chart, manifests, documentation and examples and gives
your links to the correct versions:

Version Description Image for NGINX Image for NGINX Plus Installation Manifests and Helm Chart Documentation and Examples
Latest stable release For production use Use the 5.5.4 images from DockerHub, GitHub Container, Amazon ECR Public Gallery or Quay.io or build your own image. Use the 5.5.4 images from the F5 Container Registry or Build your own image. Manifests. Helm chart. Documentation. Examples.
Edge/Nightly For testing and experimenting Use the edge or nightly images from DockerHub, GitHub Container, Amazon ECR Public Gallery or Quay.io or build your own image. Build your own image. Manifests. Helm chart. Documentation. Examples.

SBOM (Software Bill of Materials)

We generate SBOMs for the binaries and the Docker images.

Binaries

The SBOMs for the binaries are available in the releases page. The SBOMs are generated using
syft and are available in SPDX format.

Docker Images

The SBOMs for the Docker images are available in the DockerHub, GitHub
Container
, Amazon ECR Public
Gallery
or Quay.io
repositories. The SBOMs are generated using syft and stored as an attestation in the
image manifest.

For example to retrieve the SBOM for linux/amd64 from Docker Hub and analyze it using
grype you can run the following command:

console
docker buildx imagetools inspect nginx/nginx-ingress:edge --format '{{ json (index .SBOM "linux/amd64").SPDX }}' | grype

Contacts

Weโ€™d like to hear your feedback! If you have any suggestions or experience issues with our Ingress Controller, please
create an issue or send a pull request on GitHub.

Contributing

If you'd like to contribute to the project, please read our Contributing guide.

Support

For NGINX Plus customers NGINX Ingress Controller (when used with NGINX Plus) is covered by the support contract.


File: charts/nginx-ingress/README.md

Helm Documentation

Please refer to the Installation with Helm guide in the NGINX Ingress Controller documentation site.


File: deployments/README.md

Installation

This folder includes Kubernetes manifests for installing NGINX or NGINX Plus Ingress Controller. Read the installation
instructions
.


File: examples/shared-examples/wildcard-tls-certificate/README.md

Wildcard TLS Certificate

The wildcard TLS certificate simplifies the configuration of TLS termination if you need to use the same TLS certificate
in multiple Ingress and VirtualServer resources from various namespaces. Typically, such a certificate is for a
subdomain (for example, *.example.com), while the hosts in the Ingress and VirtualServer resources include that
subdomain (for example, foo.example.com, bar.example.com).

Example

Prerequisites

Start the Ingress Controller with the -wildcard-tls-secret command-line
argument

set to a TLS secret with a wildcard cert/key. For example:

yaml
-wildcard-tls-secret=nginx-ingress/wildcard-tls-secret

Note: the Ingress Controller supports only one wildcard TLS secret.

Configuring TLS Termination

In the example below we configure TLS termination for an Ingress for the host foo.example.com and a VirtualServer for
the host bar.example.com:

foo Ingress from the namespace foo:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: foo
 namespace: foo
spec:
 ingressClassName: nginx
 tls:
 - hosts:
   - foo.example.com
 rules:
 - host: foo.example.com
   http:
     paths:
     - path: /
       pathType: Prefix
       backend:
         service:
           name: foo-service
           port:
             number: 80

bar VirtualServer from the namespace bar:

yaml
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: bar
  namespace: bar
spec:
  host: bar.example.com
  tls:
    secret: ""
  upstreams:
  - name: bar
    service: bar-service
    port: 80
  routes:
  - path: /
    action:
      pass: bar

Because we don't reference any TLS secret in the resources above -- there is no secret field in the tls section of
the Ingress resource and the secret field is empty in the VirtualServer -- NGINX will use the wildcard secret
specified in the -wildcard-tls-secret command-line argument.


File: examples/shared-examples/rbac/README.md

RBAC

It is possible to run the Ingress Controller in a cluster with
RBAC enabled.
Read the installation instructions.


File: examples/shared-examples/proxy-protocol/README.md

PROXY Protocol

Proxies and load balancers, such as HAProxy or ELB, can pass the client's information (the IP address and the port) to
the next proxy or load balancer via the PROXY Protocol. To enable NGINX Ingress Controller to receive that information,
use the proxy-protocol ConfigMaps configuration key as well as the real-ip-header and the set-real-ip-from keys.
Once you enable the PROXY Protocol, it is enabled for every Ingress and VirtualServer resource. NOTE TransportServer
resource supports PROXY Protocol only when TLS Passthrough is enabled for the Ingress Controller.

Syntax

The proxy-protocol key syntax is as follows:

yaml
proxy-protocol: "True | False"

Additionally, you must configure the following keys:

  • real-ip-header: Set its value to proxy_protocol.
  • set-real-ip-from: Set its value to the IP address or the subnet of the proxy or the load balancer. See
    set-real-ip-from

Example

In the example below we configure the PROXY Protocol via a ConfigMaps resource. set-real-ip-from is set to
192.168.0.0/16. This is the CIDR range of the proxy that sits in front of the Ingress Controller in this example. You
can set this to 0.0.0.0/0 to trust all IPs. After we create the ConfigMaps resource, the client's IP address is
available via the $remote_addr variable in the NGINX configuration. By default, NGINX Ingress Controller logs the
value of this variable and also passes the value to the backend service in the X-Real-IP header.

The default log format for NGINX is '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'

yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  proxy-protocol: "True"
  real-ip-header: "proxy_protocol"
  set-real-ip-from: "192.168.0.0/16"

File: examples/shared-examples/otel/README.md

Enable OpenTelemetry

This is the example code used in the Enable OpenTelemetry documentation.


File: examples/shared-examples/nginx-plus-secret/README.md

NGINX Plus Secret

Refer to the Create License Secret docs to download and create a License Secret


File: examples/shared-examples/custom-templates/README.md

Custom Templates

The Ingress Controller allows you to customize your templates through a
ConfigMap
via the following keys:

  • main-template - Sets the main NGINX configuration template.
  • ingress-template - Sets the Ingress NGINX configuration template for an Ingress resource.
  • virtualserver-template - Sets the NGINX configuration template for an VirtualServer resource.
  • transportserver-template - Sets the NGINX configuration template for a TransportServer resource.

Example

yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  main-template: |
    worker_processes  {{.WorkerProcesses}};
    ...
        include /etc/nginx/conf.d/*.conf;
    }
  ingress-template: |
    {{range $upstream := .Upstreams}}
    upstream {{$upstream.Name}} {
      {{if $upstream.LBMethod }}{{$upstream.LBMethod}};{{end}}
    ...
    }{{end}}
  virtualserver-template: |
    {{ range $u := .Upstreams }}
    upstream {{ $u.Name }} {
      {{ if ne $u.UpstreamZoneSize "0" }}zone {{ $u.Name }} {{ $u.UpstreamZoneSize }};{{ end }}
    ...
    }
    {{ end }}
  transportserver-template: |
    {{- range $u := .Upstreams }}
    upstream {{ $u.Name }} {
        zone {{ $u.Name }} 256k;
    ...
    }

Notes:

  • The templates are truncated for the clarity of the example.
  • The templates for NGINX (the main nginx.tmpl and the Ingress nginx.ingress.tmpl) and NGINX Plus (the main
    nginx-plus.tmpl and the Ingress nginx-plus.ingress.tmpl) are located at
    internal/configs/version1. The VirtualServer templates for NGINX
    (nginx.virtualserver.tmpl) and NGINX Plus (nginx-plus.virtualserver.tmpl) are located at
    internal/configs/version2.

Troubleshooting

  • If a custom template contained within the ConfigMap is invalid on startup, the Ingress Controller will fail to start,
    the error will be reported in the Ingress Controller logs.

    An example of an error from the logs:

    text
    Error updating NGINX main template: template: nginxTemplate:98: unexpected EOF
  • If a custom template contained within the ConfigMap is invalid on update, the Ingress Controller will not update the
    NGINX configuration, the error will be reported in the Ingress Controller logs and an event with the error will be
    associated with the ConfigMap.

    An example of an error from the logs:

    text
    Error when updating config from ConfigMap: Invalid nginx configuration detected, not reloading

    An example of an event with an error (you can view events associated with the ConfigMap by running kubectl describe -n nginx-ingress configmap nginx-config):

    text
    Events:
      Type     Reason            Age                From                      Message
      ----     ------            ----               ----                      -------
      Normal   Updated           12s (x2 over 25s)  nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated
      Warning  UpdatedWithError  10s                nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated, but not applied: Error when parsing the main template: template: nginxTemplate:98: unexpected EOF
      Warning  UpdatedWithError  8s                 nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated, but not applied: Error when writing main Config
  • If custom templates from before version 5.5 are used without updating to match the upstream versions, the Ingress
    Controller may fail to start. The error will be reported in the Ingress Controller logs.

    An example of an error from the logs:

    text
    Error generating NGINX main config: template: nginxTemplate:142:18: executing "nginxTemplate" at <.DefaultHTTPListenerPort>: can't evaluate field DefaultHTTPListenerPort in type *version1.MainConfig

File: examples/shared-examples/custom-log-format/README.md

Custom NGINX log format

This example lets you set the log-format for NGINX using the configmap resource

yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  log-format:  '$remote_addr - $remote_user [$time_local] "$request" $status $grpc_status $body_bytes_sent "$http_referer"  "$http_user_agent" "$http_x_forwarded_for" "$resource_name" "$resource_type" "$resource_namespace" "$service"'

In addition to the built-in NGINX variables, you can also use the variables
that the Ingress Controller configures:

  • $resource_type - The type of kubernetes resource that handled the client request.
  • $resource_name - The name of the resource
  • $resource_namespace - The namespace the resource exists in.
  • $service - The name of the service the client request was sent to.
  • $grpc_status - the gRPC status code, which is constructed either from the HTTP/2 trailer (grpc_status) returned from
    the backend for normal conditions, or from the HTTP/2 header (grpc_status) set either by the backend or by NGINX
    itself for some error conditions.

note These variables are only available for Ingress, VirtualServer and VirtualServerRoute resources.