2017-03-31 20:25:41 +00:00
---
2018-02-27 18:51:46 +00:00
reviewers:
2017-03-31 20:25:41 +00:00
- bprashanth
2017-10-25 18:21:46 +00:00
title: Ingress
2018-05-05 16:00:51 +00:00
content_template: templates/concept
2018-06-06 23:51:26 +00:00
weight: 40
2017-03-31 20:25:41 +00:00
---
2018-05-05 16:00:51 +00:00
{{% capture overview %}}
{{< glossary_definition term_id = "ingress" length = "all" > }}
{{% /capture %}}
2017-03-31 20:25:41 +00:00
2018-05-05 16:00:51 +00:00
{{% capture body %}}
2018-06-11 19:38:26 +00:00
## Terminology
2017-03-31 20:25:41 +00:00
2018-11-16 20:37:21 +00:00
For the sake of clarity, this guide defines the following terms:
2017-03-31 20:25:41 +00:00
* Node: A single virtual or physical machine in a Kubernetes cluster.
* Cluster: A group of nodes firewalled from the internet, that are the primary compute resources managed by Kubernetes.
2017-05-12 01:29:58 +00:00
* Edge router: A router that enforces the firewall policy for your cluster. This could be a gateway managed by a cloud provider or a physical piece of hardware.
2018-11-16 20:37:21 +00:00
* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the [Kubernetes networking model ](/docs/concepts/cluster-administration/networking/ ).
2017-04-19 17:56:47 +00:00
* Service: A Kubernetes [Service ](/docs/concepts/services-networking/service/ ) that identifies a set of pods using label selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.
2017-03-31 20:25:41 +00:00
## What is Ingress?
2018-11-16 20:37:21 +00:00
Ingress, added in Kubernetes v1.1, exposes HTTP and HTTPS routes from outside the cluster to
{{< link text = "services" url = "/docs/concepts/services-networking/service/" > }} within the cluster.
2019-02-18 02:36:33 +00:00
Traffic routing is controlled by rules defined on the Ingress resource.
2017-03-31 20:25:41 +00:00
2018-06-11 19:38:26 +00:00
```none
2017-03-31 20:25:41 +00:00
internet
|
[ Ingress ]
--|-----|--
[ Services ]
```
2019-02-18 02:36:33 +00:00
An Ingress can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, and offer name based virtual hosting. An [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) is responsible for fulfilling the Ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic.
2018-11-16 20:37:21 +00:00
2019-02-18 02:36:33 +00:00
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically
2018-11-16 20:37:21 +00:00
uses a service of type [Service.Type=NodePort ](/docs/concepts/services-networking/service/#nodeport ) or
[Service.Type=LoadBalancer ](/docs/concepts/services-networking/service/#loadbalancer ).
2017-03-31 20:25:41 +00:00
## Prerequisites
2018-11-16 20:37:21 +00:00
{{< feature-state for_k8s_version = "v1.1" state = "beta" > }}
2019-02-18 02:36:33 +00:00
Before you start using an Ingress, there are a few things you should understand. The Ingress is a beta resource.
2018-11-16 20:37:21 +00:00
2019-02-18 02:36:33 +00:00
{{< note > }}
You must have an [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) to satisfy an Ingress. Only creating an Ingress resource has no effect.
{{< / note > }}
GCE/Google Kubernetes Engine deploys an Ingress controller on the master. Review the
2018-11-16 20:37:21 +00:00
[beta limitations ](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations )
of this controller if you are using GCE/GKE.
In environments other than GCE/Google Kubernetes Engine, you may need to
[deploy an ingress controller ](https://kubernetes.github.io/ingress-nginx/deploy/ ). There are a number of
2019-02-27 23:15:30 +00:00
[ingress controllers ](/docs/concepts/services-networking/ingress-controllers ) you may choose from.
2017-03-31 20:25:41 +00:00
2018-11-25 07:28:46 +00:00
### Before you begin
Ideally, all ingress controllers should fulfill this specification, but the various ingress
controllers operate slightly differently.
{{< note > }}
Make sure you review your ingress controller's documentation to understand the caveats of choosing it.
{{< / note > }}
2017-03-31 20:25:41 +00:00
## The Ingress Resource
2018-11-25 07:28:46 +00:00
A minimal ingress resource example:
2017-03-31 20:25:41 +00:00
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
2017-06-12 05:58:12 +00:00
annotations:
2018-03-12 23:04:10 +00:00
nginx.ingress.kubernetes.io/rewrite-target: /
2017-03-31 20:25:41 +00:00
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
```
2019-02-18 02:36:33 +00:00
As with all other Kubernetes resources, an Ingress needs `apiVersion` , `kind` , and `metadata` fields.
2018-11-16 20:37:21 +00:00
For general information about working with config files, see [deploying applications ](/docs/tasks/run-application/run-stateless-application-deployment/ ), [configuring containers ](/docs/tasks/configure-pod-container/configure-pod-configmap/ ), [managing resources ](/docs/concepts/cluster-administration/manage-deployment/ ).
2019-02-18 02:36:33 +00:00
Ingress frequently uses annotations to configure some options depending on the Ingress controller, an example of which
2018-11-16 20:37:21 +00:00
is the [rewrite-target annotation ](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md ).
2019-03-05 14:46:39 +00:00
Different [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) support different annotations. Review the documentation for
2019-02-18 02:36:33 +00:00
your choice of Ingress controller to learn which annotations are supported.
2017-03-31 20:25:41 +00:00
2019-02-18 02:36:33 +00:00
The Ingress [spec ](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status )
2018-11-16 20:37:21 +00:00
has all the information needed to configure a loadbalancer or proxy server. Most importantly, it
contains a list of rules matched against all incoming requests. Ingress resource only supports rules
2018-11-25 07:28:46 +00:00
for directing HTTP traffic.
### Ingress rules
2017-03-31 20:25:41 +00:00
2018-11-25 07:28:46 +00:00
Each http rule contains the following information:
2017-03-31 20:25:41 +00:00
2018-11-28 15:46:01 +00:00
* An optional host. In this example, no host is specified, so the rule applies to all inbound
HTTP traffic through the IP address is 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 associated backend defined with a `serviceName`
2018-11-16 20:37:21 +00:00
and `servicePort` . Both the host and path must match the content of an incoming request before the
2018-11-25 07:28:46 +00:00
loadbalancer will direct traffic to the referenced service.
* A backend is a combination of service and port names as described in the
[services doc ](/docs/concepts/services-networking/service/ ). HTTP (and HTTPS) requests to the
2019-02-18 02:36:33 +00:00
Ingress matching the host and path of the rule will be sent to the listed backend.
2017-03-31 20:25:41 +00:00
2019-02-18 02:36:33 +00:00
A default backend is often configured in an Ingress controller that will service any requests that do not
2018-11-25 07:28:46 +00:00
match a path in the spec.
2017-03-31 20:25:41 +00:00
2018-11-25 07:28:46 +00:00
### Default Backend
2017-03-31 20:25:41 +00:00
2019-02-18 02:36:33 +00:00
An Ingress with no rules sends all traffic to a single default backend. The default
backend is typically a configuration option of the [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) and is not specified in your Ingress resources.
2017-03-31 20:25:41 +00:00
2019-02-18 02:36:33 +00:00
If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is
2018-11-25 07:28:46 +00:00
routed to your default backend.
2017-03-31 20:25:41 +00:00
## Types of Ingress
### Single Service Ingress
2018-07-10 15:56:25 +00:00
There are existing Kubernetes concepts that allow you to expose a single Service
2019-02-18 02:36:33 +00:00
(see [alternatives ](#alternatives )). You can also do this with an Ingress by specifying a
2018-11-16 20:37:21 +00:00
*default backend* with no rules.
2017-03-31 20:25:41 +00:00
2018-07-10 15:56:25 +00:00
{{< codenew file = "service/networking/ingress.yaml" > }}
2017-03-31 20:25:41 +00:00
If you create it using `kubectl create -f` you should see:
```shell
2018-08-29 07:09:41 +00:00
kubectl get ingress test-ingress
```
```shell
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 107.178.254.228 80 59s
2017-03-31 20:25:41 +00:00
```
2019-02-18 02:36:33 +00:00
Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy
this Ingress.
2018-11-16 20:37:21 +00:00
{{< note > }}
2018-11-25 07:28:46 +00:00
Ingress controllers and load balancers may take a minute or two to allocate an IP address.
Until that time you will often see the address listed as `<pending>` .
2018-11-16 20:37:21 +00:00
{{< / note > }}
2017-03-31 20:25:41 +00:00
### Simple fanout
2018-11-25 07:28:46 +00:00
A fanout configuration routes traffic from a single IP address to more than one service,
2019-02-18 02:36:33 +00:00
based on the HTTP URI being requested. An Ingress allows you to keep the number of loadbalancers
2018-11-25 07:28:46 +00:00
down to a minimum. For example, a setup like:
2017-03-31 20:25:41 +00:00
```shell
2018-11-16 20:37:21 +00:00
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
2017-03-31 20:25:41 +00:00
```
2019-02-18 02:36:33 +00:00
would require an Ingress such as:
2017-03-31 20:25:41 +00:00
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
2018-11-16 20:37:21 +00:00
name: simple-fanout-example
2017-06-12 05:58:12 +00:00
annotations:
2018-04-12 22:11:59 +00:00
nginx.ingress.kubernetes.io/rewrite-target: /
2017-03-31 20:25:41 +00:00
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
2018-11-16 20:37:21 +00:00
serviceName: service1
servicePort: 4200
2017-03-31 20:25:41 +00:00
- path: /bar
backend:
2018-11-16 20:37:21 +00:00
serviceName: service2
servicePort: 8080
2017-03-31 20:25:41 +00:00
```
2019-02-18 02:36:33 +00:00
When you create the Ingress with `kubectl create -f` :
2017-03-31 20:25:41 +00:00
```shell
2018-11-16 20:37:21 +00:00
kubectl describe ingress simple-fanout-example
2018-08-29 07:09:41 +00:00
```
```shell
2018-11-16 20:37:21 +00:00
Name: simple-fanout-example
2018-08-29 07:09:41 +00:00
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
2018-11-16 20:37:21 +00:00
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
2018-08-29 07:09:41 +00:00
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
2017-03-31 20:25:41 +00:00
```
2018-08-29 07:09:41 +00:00
2019-02-18 02:36:33 +00:00
The Ingress controller provisions an implementation specific loadbalancer
that satisfies the Ingress, as long as the services (`s1`, `s2` ) exist.
When it has done so, you can see the address of the loadbalancer at the
2018-08-29 07:09:41 +00:00
Address field.
{{< note > }}
2019-02-18 02:36:33 +00:00
Depending on the [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) you are using, you may need to
2018-11-16 20:37:21 +00:00
create a default-http-backend [Service ](/docs/concepts/services-networking/service/ ).
2018-08-29 07:09:41 +00:00
{{< / note > }}
2017-03-31 20:25:41 +00:00
### Name based virtual hosting
2018-11-16 20:37:21 +00:00
Name-based virtual hosts support routing HTTP traffic to multiple host names at the same IP address.
2017-03-31 20:25:41 +00:00
2018-06-11 19:38:26 +00:00
```none
2017-03-31 20:25:41 +00:00
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
```
2019-02-18 02:36:33 +00:00
The following Ingress tells the backing loadbalancer to route requests based on
2018-07-10 15:56:25 +00:00
the [Host header ](https://tools.ietf.org/html/rfc7230#section-5.4 ).
2017-03-31 20:25:41 +00:00
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
2018-11-16 20:37:21 +00:00
name: name-virtual-host-ingress
2017-03-31 20:25:41 +00:00
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
2018-11-16 20:37:21 +00:00
serviceName: service1
2017-03-31 20:25:41 +00:00
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
2018-11-16 20:37:21 +00:00
serviceName: service2
2017-03-31 20:25:41 +00:00
servicePort: 80
```
2019-02-18 02:36:33 +00:00
If you create an Ingress resource without any hosts defined in the rules, then any
web traffic to the IP address of your Ingress controller can be matched without a name based
virtual host being required. For example, the following Ingress resource will route traffic
2019-01-08 12:10:02 +00:00
requested for `first.bar.com` to `service1` , `second.foo.com` to `service2` , and any traffic
2018-11-25 07:28:46 +00:00
to the IP address without a hostname defined in request (that is, without a request header being
presented) to `service3` .
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: first.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: second.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
- http:
paths:
- backend:
serviceName: service3
servicePort: 80
```
2017-03-31 20:25:41 +00:00
### TLS
2019-02-18 02:36:33 +00:00
You can secure an Ingress by specifying a [secret ](/docs/concepts/configuration/secret )
that contains a TLS private key and certificate. Currently the Ingress only
2018-07-10 15:56:25 +00:00
supports a single TLS port, 443, and assumes TLS termination. If the TLS
2019-02-18 02:36:33 +00:00
configuration section in an Ingress specifies different hosts, they will be
2018-07-10 15:56:25 +00:00
multiplexed on the same port according to the hostname specified through the
2019-02-18 02:36:33 +00:00
SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret
2018-07-10 15:56:25 +00:00
must contain keys named `tls.crt` and `tls.key` that contain the certificate
and private key to use for TLS, e.g.:
2017-03-31 20:25:41 +00:00
```yaml
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
2018-11-16 20:37:21 +00:00
name: testsecret-tls
2017-03-31 20:25:41 +00:00
namespace: default
2019-02-13 07:36:11 +00:00
type: kubernetes.io/tls
2017-03-31 20:25:41 +00:00
```
2019-02-18 02:36:33 +00:00
Referencing this secret in an Ingress will tell the Ingress controller to
2018-11-16 20:37:21 +00:00
secure the channel from the client to the loadbalancer using TLS. You need to make
sure the TLS secret you created came from a certificate that contains a CN
for `sslexample.foo.com` .
2017-03-31 20:25:41 +00:00
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
2018-11-16 20:37:21 +00:00
name: tls-example-ingress
2017-03-31 20:25:41 +00:00
spec:
tls:
2018-11-19 18:23:49 +00:00
- hosts:
- sslexample.foo.com
2018-11-16 20:37:21 +00:00
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
2017-03-31 20:25:41 +00:00
```
2018-11-16 20:37:21 +00:00
{{< note > }}
2019-02-18 02:36:33 +00:00
There is a gap between TLS features supported by various Ingress
2018-07-10 15:56:25 +00:00
controllers. Please refer to documentation on
[nginx ](https://git.k8s.io/ingress-nginx/README.md#https ),
[GCE ](https://git.k8s.io/ingress-gce/README.md#frontend-https ), or any other
2019-02-18 02:36:33 +00:00
platform specific Ingress controller to understand how TLS works in your environment.
2018-11-16 20:37:21 +00:00
{{< / note > }}
2017-03-31 20:25:41 +00:00
### Loadbalancing
2019-02-18 02:36:33 +00:00
An Ingress controller is bootstrapped with some load balancing policy settings
that it applies to all Ingress, such as the load balancing algorithm, backend
2018-07-10 15:56:25 +00:00
weight scheme, and others. More advanced load balancing concepts
(e.g. persistent sessions, dynamic weights) are not yet exposed through the
2019-02-18 02:36:33 +00:00
Ingress. You can still get these features through the
2018-08-17 17:00:10 +00:00
[service loadbalancer ](https://github.com/kubernetes/ingress-nginx ).
2018-07-10 15:56:25 +00:00
It's also worth noting that even though health checks are not exposed directly
2019-02-18 02:36:33 +00:00
through the Ingress, there exist parallel concepts in Kubernetes such as
2018-07-10 15:56:25 +00:00
[readiness probes ](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ )
which allow you to achieve the same end result. Please review the controller
specific docs to see how they handle health checks (
[nginx ](https://git.k8s.io/ingress-nginx/README.md ),
[GCE ](https://git.k8s.io/ingress-gce/README.md#health-checks )).
2017-03-31 20:25:41 +00:00
## Updating an Ingress
2019-02-18 02:36:33 +00:00
To update an existing Ingress to add a new Host, you can update it by editing the resource:
2017-03-31 20:25:41 +00:00
```shell
2018-08-29 07:09:41 +00:00
kubectl describe ingress test
```
```shell
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo s1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
```
```shell
kubectl edit ingress test
2017-03-31 20:25:41 +00:00
```
2017-09-21 14:00:02 +00:00
This should pop up an editor with the existing yaml, modify it to include the new Host:
2017-03-31 20:25:41 +00:00
```yaml
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: s1
servicePort: 80
path: /foo
- host: bar.baz.com
http:
paths:
- backend:
serviceName: s2
servicePort: 80
path: /foo
..
```
2018-11-16 20:37:21 +00:00
Saving the yaml will update the resource in the API server, which should tell the
2019-02-18 02:36:33 +00:00
Ingress controller to reconfigure the loadbalancer.
2017-03-31 20:25:41 +00:00
```shell
2018-08-29 07:09:41 +00:00
kubectl describe ingress test
```
```shell
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo s1:80 (10.8.0.90:80)
bar.baz.com
/foo s2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
2017-03-31 20:25:41 +00:00
```
2019-02-18 02:36:33 +00:00
You can achieve the same by invoking `kubectl replace -f` on a modified Ingress yaml file.
2017-03-31 20:25:41 +00:00
## Failing across availability zones
2018-11-16 20:37:21 +00:00
Techniques for spreading traffic across failure domains differs between cloud providers.
2019-02-18 02:36:33 +00:00
Please check the documentation of the relevant [Ingress controller ](/docs/concepts/services-networking/ingress-controllers ) for details. You can also refer to the [federation documentation ](/docs/concepts/cluster-administration/federation/ )
for details on deploying Ingress in a federated cluster.
2017-03-31 20:25:41 +00:00
## Future Work
2018-11-16 20:37:21 +00:00
Track [SIG Network ](https://github.com/kubernetes/community/tree/master/sig-network )
for more details on the evolution of the ingress and related resources. You may also track the
2019-02-18 02:36:33 +00:00
[Ingress repository ](https://github.com/kubernetes/ingress/tree/master ) for more details on the
evolution of various Ingress controllers.
2017-03-31 20:25:41 +00:00
## Alternatives
2019-02-18 02:36:33 +00:00
You can expose a Service in multiple ways that don't directly involve the Ingress resource:
2017-03-31 20:25:41 +00:00
2018-08-17 17:00:10 +00:00
* Use [Service.Type=LoadBalancer ](/docs/concepts/services-networking/service/#loadbalancer )
* Use [Service.Type=NodePort ](/docs/concepts/services-networking/service/#nodeport )
2017-06-26 22:40:13 +00:00
* Use a [Port Proxy ](https://git.k8s.io/contrib/for-demos/proxy-to-service )
2018-11-16 20:37:21 +00:00
2018-05-05 16:00:51 +00:00
{{% /capture %}}
2018-06-11 19:38:26 +00:00
{{% capture whatsnext %}}
2019-02-27 23:15:30 +00:00
* [Set up Ingress on Minikube with the NGINX Controller ](/docs/tasks/access-application-cluster/ingress-minikube )
2018-06-11 19:38:26 +00:00
{{% /capture %}}