Ingress

Make your HTTP (or HTTPS) network service available using a protocol-aware configuration mechanism, that understands web concepts like URIs, hostnames, paths, and more. The Ingress concept lets you map traffic to different backends based on rules you define via the Kubernetes API.

FEATURE STATE:Kubernetes v1.19 [stable]

An API object that manages external access to the services in a cluster, typically HTTP.

Ingress may provide load balancing, SSL termination and name-based virtual hosting.

Note:

The Kubernetes project recommends usingGateway instead ofIngress.The Ingress API has been frozen.

This means that:

  • The Ingress API is generally available, and is subject to thestability guarantees for generally available APIs.The Kubernetes project has no plans to remove Ingress from Kubernetes.
  • The Ingress API is no longer being developed, and will have no further changesor updates made to it.

Terminology

For clarity, this guide defines the following terms:

  • Node: A worker machine in Kubernetes, part of a cluster.
  • Cluster: A set of Nodes that run containerized applications managed by Kubernetes.For this example, and in most common Kubernetes deployments, nodes in the clusterare not part of the public internet.
  • Edge router: A router that enforces the firewall policy for your cluster. Thiscould be a gateway managed by a cloud provider or a physical piece of hardware.
  • Cluster network: A set of links, logical or physical, that facilitate communicationwithin a cluster according to the Kubernetesnetworking model.
  • Service: A KubernetesService that identifiesa set of Pods usinglabel selectors.Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.

What is Ingress?

Ingressexposes HTTP and HTTPS routes from outside the cluster toservices within the cluster.Traffic routing is controlled by rules defined on the Ingress resource.

Here is a simple example where an Ingress sends all its traffic to one Service:

ingress-diagram

Figure. Ingress

An Ingress may be configured to give Services externally-reachable URLs,load balance traffic, terminate SSL / TLS, and offer name-based virtual hosting.AnIngress controlleris responsible for fulfilling the Ingress, usually with a load balancer, thoughit may also configure your edge router or additional frontends to help handle the traffic.

An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typicallyuses a service of typeService.Type=NodePort orService.Type=LoadBalancer.

Prerequisites

You must have anIngress controllerto satisfy an Ingress. Only creating an Ingress resource has no effect.

You can choose from a number ofIngress controllers.

Ideally, all Ingress controllers should fit the reference specification. In reality, the various Ingresscontrollers operate slightly differently.

Note:

Make sure you review your Ingress controller's documentation to understand the caveats of choosing it.

The Ingress resource

A minimal Ingress resource example:

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:minimal-ingressspec:ingressClassName:nginx-examplerules:-http:paths:-path:/testpathpathType:Prefixbackend:service:name:testport:number:80

An Ingress needsapiVersion,kind,metadata andspec fields.The name of an Ingress object must be a validDNS subdomain name.For general information about working with config files, seedeploying applications,configuring containers,managing resources.Ingress controllers frequently useannotations to configure behavior.Review the documentation for your choice of ingress controller to learn which annotations are expected and / or supported.

TheIngress spechas all the information needed to configure a load balancer or proxy server. Most importantly, itcontains a list of rules matched against all incoming requests. Ingress resource only supports rulesfor directing HTTP(S) traffic.

If theingressClassName is omitted, adefault Ingress classshould be defined.

Some ingress controllers work even without the definition of adefault IngressClass. Even if you use an ingress controller that is ableto operate without any IngressClass, the Kubernetes project still recommendsthat you define a default IngressClass.

Ingress rules

Each HTTP rule contains the following information:

  • An optional host. In this example, no host is specified, so the rule applies to all inboundHTTP traffic through the IP address specified. If a host is provided (for example,foo.bar.com), the rules apply to that host.
  • A list of paths (for example,/testpath), each of which has an associatedbackend defined with aservice.name and aservice.port.name orservice.port.number. Both the host and path must match the content of anincoming request before the load balancer directs traffic to the referencedService.
  • A backend is a combination of Service and port names as described in theService doc or acustom resource backendby way of aCRD. HTTP (and HTTPS) requests to theIngress that match the host and path of the rule are sent to the listed backend.

AdefaultBackend is often configured in an Ingress controller to service any requests that do notmatch a path in the spec.

DefaultBackend

An Ingress with no rules sends all traffic to a single default backend and.spec.defaultBackendis the backend that should handle requests in that case.ThedefaultBackend is conventionally a configuration option of theIngress controller andis not specified in your Ingress resources.If no.spec.rules are specified,.spec.defaultBackend must be specified.IfdefaultBackend is not set, the handling of requests that do not match any of the rules will be up to theingress controller (consult the documentation for your ingress controller to find out how it handles this case).

If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic isrouted to your default backend.

Resource backends

AResource backend is an ObjectRef to another Kubernetes resource within thesame namespace as the Ingress object. AResource is a mutually exclusivesetting with Service, and will fail validation if both are specified. A commonusage for aResource backend is to ingress data to an object storage backendwith static assets.

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-resource-backendspec:defaultBackend:resource:apiGroup:k8s.example.comkind:StorageBucketname:static-assetsrules:-http:paths:-path:/iconspathType:ImplementationSpecificbackend:resource:apiGroup:k8s.example.comkind:StorageBucketname:icon-assets

After creating the Ingress above, you can view it with the following command:

kubectl describe ingress ingress-resource-backend
Name:             ingress-resource-backendNamespace:        defaultAddress:Default backend:  APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assetsRules:  Host        Path  Backends  ----        ----  --------  *              /icons   APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assetsAnnotations:  <none>Events:       <none>

Path types

Each path in an Ingress is required to have a corresponding path type. Pathsthat do not include an explicitpathType will fail validation. There are threesupported path types:

  • ImplementationSpecific: With this path type, matching is up to theIngressClass. Implementations can treat this as a separatepathType or treatit identically toPrefix orExact path types.

  • Exact: Matches the URL path exactly and with case sensitivity.

  • Prefix: Matches based on a URL path prefix split by/. Matching is casesensitive and done on a path element by element basis. A path element refersto the list of labels in the path split by the/ separator. A request is amatch for pathp if everyp is an element-wise prefix ofp of therequest path.

    Note:

    If the last element of the path is a substring of the lastelement in request path, it is not a match (for example:/foo/barmatches/foo/bar/baz, but does not match/foo/barbaz).

Examples

KindPath(s)Request path(s)Matches?
Prefix/(all paths)Yes
Exact/foo/fooYes
Exact/foo/barNo
Exact/foo/foo/No
Exact/foo//fooNo
Prefix/foo/foo,/foo/Yes
Prefix/foo//foo,/foo/Yes
Prefix/aaa/bb/aaa/bbbNo
Prefix/aaa/bbb/aaa/bbbYes
Prefix/aaa/bbb//aaa/bbbYes, ignores trailing slash
Prefix/aaa/bbb/aaa/bbb/Yes, matches trailing slash
Prefix/aaa/bbb/aaa/bbb/cccYes, matches subpath
Prefix/aaa/bbb/aaa/bbbxyzNo, does not match string prefix
Prefix/,/aaa/aaa/cccYes, matches/aaa prefix
Prefix/,/aaa,/aaa/bbb/aaa/bbbYes, matches/aaa/bbb prefix
Prefix/,/aaa,/aaa/bbb/cccYes, matches/ prefix
Prefix/aaa/cccNo, uses default backend
Mixed/foo (Prefix),/foo (Exact)/fooYes, prefers Exact

Multiple matches

In some cases, multiple paths within an Ingress will match a request. In thosecases precedence will be given first to the longest matching path. If two pathsare still equally matched, precedence will be given to paths with an exact pathtype over prefix path type.

Hostname wildcards

Hosts can be precise matches (for example “foo.bar.com”) or a wildcard (forexample “*.foo.com”). Precise matches require that the HTTPhost headermatches thehost field. Wildcard matches require the HTTPhost header isequal to the suffix of the wildcard rule.

HostHost headerMatch?
*.foo.combar.foo.comMatches based on shared suffix
*.foo.combaz.bar.foo.comNo match, wildcard only covers a single DNS label
*.foo.comfoo.comNo match, wildcard only covers a single DNS label
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-wildcard-hostspec:rules:-host:"foo.bar.com"http:paths:-pathType:Prefixpath:"/bar"backend:service:name:service1port:number:80-host:"*.foo.com"http:paths:-pathType:Prefixpath:"/foo"backend:service:name:service2port:number:80

Ingress class

Ingresses can be implemented by different controllers, often with differentconfiguration. Each Ingress should specify a class, a reference to anIngressClass resource that contains additional configuration including the nameof the controller that should implement the class.

apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lbspec:controller:example.com/ingress-controllerparameters:apiGroup:k8s.example.comkind:IngressParametersname:external-lb

The.spec.parameters field of an IngressClass lets you reference anotherresource that provides configuration related to that IngressClass.

The specific type of parameters to use depends on the ingress controllerthat you specify in the.spec.controller field of the IngressClass.

IngressClass scope

Depending on your ingress controller, you may be able to use parametersthat you set cluster-wide, or just for one namespace.

The default scope for IngressClass parameters is cluster-wide.

If you set the.spec.parameters field and don't set.spec.parameters.scope, or if you set.spec.parameters.scope toCluster, then the IngressClass refers to a cluster-scoped resource.Thekind (in combination theapiGroup) of the parametersrefers to a cluster-scoped API (possibly a custom resource), andthename of the parameters identifies a specific cluster scopedresource for that API.

For example:

---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-1spec:controller:example.com/ingress-controllerparameters:# The parameters for this IngressClass are specified in a# ClusterIngressParameter (API group k8s.example.net) named# "external-config-1". This definition tells Kubernetes to# look for a cluster-scoped parameter resource.scope:ClusterapiGroup:k8s.example.netkind:ClusterIngressParametername:external-config-1

FEATURE STATE:Kubernetes v1.23 [stable]

If you set the.spec.parameters field and set.spec.parameters.scope toNamespace, then the IngressClass refersto a namespaced-scoped resource. You must also set thenamespacefield within.spec.parameters to the namespace that containsthe parameters you want to use.

Thekind (in combination theapiGroup) of the parametersrefers to a namespaced API (for example: ConfigMap), andthename of the parameters identifies a specific resourcein the namespace you specified innamespace.

Namespace-scoped parameters help the cluster operator delegate control over theconfiguration (for example: load balancer settings, API gateway definition)that is used for a workload. If you used a cluster-scoped parameter then either:

  • the cluster operator team needs to approve a different team's changes everytime there's a new configuration change being applied.
  • the cluster operator must define specific access controls, such asRBAC roles and bindings, that letthe application team make changes to the cluster-scoped parameters resource.

The IngressClass API itself is always cluster-scoped.

Here is an example of an IngressClass that refers to parameters that arenamespaced:

---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-2spec:controller:example.com/ingress-controllerparameters:# The parameters for this IngressClass are specified in an# IngressParameter (API group k8s.example.com) named "external-config",# that's in the "external-configuration" namespace.scope:NamespaceapiGroup:k8s.example.comkind:IngressParameternamespace:external-configurationname:external-config

Deprecated annotation

Before the IngressClass resource andingressClassName field were added inKubernetes 1.18, Ingress classes were specified with akubernetes.io/ingress.class annotation on the Ingress. This annotation wasnever formally defined, but was widely supported by Ingress controllers.

The neweringressClassName field on Ingresses is a replacement for thatannotation, but is not a direct equivalent. While the annotation was generallyused to reference the name of the Ingress controller that should implement theIngress, the field is a reference to an IngressClass resource that containsadditional Ingress configuration, including the name of the Ingress controller.

Default IngressClass

You can mark a particular IngressClass as default for your cluster. Setting theingressclass.kubernetes.io/is-default-class annotation totrue on anIngressClass resource will ensure that new Ingresses without aningressClassName field specified will be assigned this default IngressClass.

Caution:

If you have more than one IngressClass marked as the default for your cluster,the admission controller prevents creating new Ingress objects that don't haveaningressClassName specified. You can resolve this by ensuring that at most 1IngressClass is marked as default in your cluster.

Start by defining adefault IngressClass. It is recommended though, to specify the defaultIngressClass:

apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:labels:app.kubernetes.io/component:controllername:nginx-exampleannotations:ingressclass.kubernetes.io/is-default-class:"true"spec:controller:k8s.io/ingress-nginx

Types of Ingress

Ingress backed by a single Service

There are existing Kubernetes concepts that allow you to expose a single Service(seealternatives). You can also do this with an Ingress by specifying adefault backend with no rules.

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:test-ingressspec:defaultBackend:service:name:testport:number:80

If you create it usingkubectl apply -f you should be able to view the stateof the Ingress you added:

kubectl get ingress test-ingress
NAME           CLASS         HOSTS   ADDRESS         PORTS   AGEtest-ingress   external-lb   *       203.0.113.123   80      59s

Where203.0.113.123 is the IP allocated by the Ingress controller to satisfythis Ingress.

Note:

Ingress controllers and load balancers may take a minute or two to allocate an IP address.Until that time, you often see the address listed as<pending>.

Simple fanout

A fanout configuration routes traffic from a single IP address to more than one Service,based on the HTTP URI being requested. An Ingress allows you to keep the number of load balancersdown to a minimum. For example, a setup like:

ingress-fanout-diagram

Figure. Ingress Fan Out

It would require an Ingress such as:

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:simple-fanout-examplespec:rules:-host:foo.bar.comhttp:paths:-path:/foopathType:Prefixbackend:service:name:service1port:number:4200-path:/barpathType:Prefixbackend:service:name:service2port:number:8080

When you create the Ingress withkubectl apply -f:

kubectl describe ingress simple-fanout-example
Name:             simple-fanout-exampleNamespace:        defaultAddress:          178.91.123.132Default backend:  default-http-backend:80 (10.8.2.3:8080)Rules:  Host         Path  Backends  ----         ----  --------  foo.bar.com               /foo   service1:4200 (10.8.0.90:4200)               /bar   service2:8080 (10.8.0.91:8080)Events:  Type     Reason  Age                From                     Message  ----     ------  ----               ----                     -------  Normal   ADD     22s                loadbalancer-controller  default/test

The Ingress controller provisions an implementation-specific load balancerthat satisfies the Ingress, as long as the Services (service1,service2) exist.When it has done so, you can see the address of the load balancer at theAddress field.

Note:

Depending on theIngress controlleryou are using, you may need to create a default-http-backendService.

Name based virtual hosting

Name-based virtual hosts support routing HTTP traffic to multiple host names at the same IP address.

ingress-namebase-diagram

Figure. Ingress Name Based Virtual hosting

The following Ingress tells the backing load balancer to route requests based ontheHost header.

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:name-virtual-host-ingressspec:rules:-host:foo.bar.comhttp:paths:-pathType:Prefixpath:"/"backend:service:name:service1port:number:80-host:bar.foo.comhttp:paths:-pathType:Prefixpath:"/"backend:service:name:service2port:number:80

If you create an Ingress resource without any hosts defined in the rules, then anyweb traffic to the IP address of your Ingress controller can be matched without a name basedvirtual host being required.

For example, the following Ingress routes trafficrequested forfirst.bar.com toservice1,second.bar.com toservice2,and any traffic whose request host header doesn't matchfirst.bar.comandsecond.bar.com toservice3.

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:name-virtual-host-ingress-no-third-hostspec:rules:-host:first.bar.comhttp:paths:-pathType:Prefixpath:"/"backend:service:name:service1port:number:80-host:second.bar.comhttp:paths:-pathType:Prefixpath:"/"backend:service:name:service2port:number:80-http:paths:-pathType:Prefixpath:"/"backend:service:name:service3port:number:80

TLS

You can secure an Ingress by specifying aSecretthat contains a TLS private key and certificate. The Ingress resource onlysupports a single TLS port, 443, and assumes TLS termination at the ingress point(traffic to the Service and its Pods is in plaintext).If the TLS configuration section in an Ingress specifies different hosts, they aremultiplexed on the same port according to the hostname specified through theSNI TLS extension (provided the Ingress controller supports SNI). The TLS secretmust contain keys namedtls.crt andtls.key that contain the certificateand private key to use for TLS. For example:

apiVersion:v1kind:Secretmetadata:name:testsecret-tlsnamespace:defaultdata:tls.crt:base64 encoded certtls.key:base64 encoded keytype:kubernetes.io/tls

Referencing this secret in an Ingress tells the Ingress controller tosecure the channel from the client to the load balancer using TLS. You need to makesure the TLS secret you created came from a certificate that contains a CommonName (CN), also known as a Fully Qualified Domain Name (FQDN) forhttps-example.foo.com.

Note:

Keep in mind that TLS will not work on the default rule because thecertificates would have to be issued for all the possible sub-domains. Therefore,hosts in thetls section need to explicitly match thehost in therulessection.
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:tls-example-ingressspec:tls:-hosts:- https-example.foo.comsecretName:testsecret-tlsrules:-host:https-example.foo.comhttp:paths:-path:/pathType:Prefixbackend:service:name:service1port:number:80

Note:

There is a gap between TLS features supported by various ingress controllers.You should refer to the documentation for the ingress controller(s) you've chosen tounderstand how TLS works in your environment.

Load balancing

An Ingress controller is bootstrapped with some load balancing policy settingsthat it applies to all Ingress, such as the load balancing algorithm, backendweight scheme, and others. More advanced load balancing concepts(e.g. persistent sessions, dynamic weights) are not yet exposed through theIngress. You can instead get these features through the load balancer used fora Service.

It's also worth noting that even though health checks are not exposed directlythrough the Ingress, there exist parallel concepts in Kubernetes such asreadiness probesthat allow you to achieve the same end result. Please review the controllerspecific documentation to see how they handle health checks.

Updating an Ingress

To update an existing Ingress to add a new Host, you can update it by editing the resource:

kubectl describe ingresstest
Name:             testNamespace:        defaultAddress:          178.91.123.132Default backend:  default-http-backend:80 (10.8.2.3:8080)Rules:  Host         Path  Backends  ----         ----  --------  foo.bar.com               /foo   service1:80 (10.8.0.90:80)Events:  Type     Reason  Age                From                     Message  ----     ------  ----               ----                     -------  Normal   ADD     35s                loadbalancer-controller  default/test
kubectl edit ingresstest

This pops up an editor with the existing configuration in YAML format.Modify it to include the new Host:

spec:rules:-host:foo.bar.comhttp:paths:-backend:service:name:service1port:number:80path:/foopathType:Prefix-host:bar.baz.comhttp:paths:-backend:service:name:service2port:number:80path:/foopathType:Prefix..

After you save your changes, kubectl updates the resource in the API server, which tells theIngress controller to reconfigure the load balancer.

Verify this:

kubectl describe ingresstest
Name:             testNamespace:        defaultAddress:          178.91.123.132Default backend:  default-http-backend:80 (10.8.2.3:8080)Rules:  Host         Path  Backends  ----         ----  --------  foo.bar.com               /foo   service1:80 (10.8.0.90:80)  bar.baz.com               /foo   service2:80 (10.8.0.91:80)Events:  Type     Reason  Age                From                     Message  ----     ------  ----               ----                     -------  Normal   ADD     45s                loadbalancer-controller  default/test

You can achieve the same outcome by invokingkubectl replace -f on a modified Ingress YAML file.

Failing across availability zones

Techniques for spreading traffic across failure domains differ between cloud providers.Please check the documentation of the relevantIngress controller for details.

Alternatives

You can expose a Service in multiple ways that don't directly involve the Ingress resource:

What's next

Last modified November 24, 2025 at 7:03 PM PST:Apply maintainer feedback (5e041a86f7)