Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating Ingress docs for 1.19 #21590

Merged
merged 4 commits into from Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
258 changes: 112 additions & 146 deletions content/en/docs/concepts/services-networking/ingress.md
Expand Up @@ -7,7 +7,7 @@ weight: 40
---

<!-- overview -->
{{< feature-state for_k8s_version="v1.1" state="beta" >}}
{{< feature-state for_k8s_version="v1.19" state="stable" >}}
robscott marked this conversation as resolved.
Show resolved Hide resolved
{{< glossary_definition term_id="ingress" length="all" >}}


Expand All @@ -25,7 +25,7 @@ For clarity, this guide defines the following terms:

## What is Ingress?

[Ingress](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ingress-v1beta1-networking-k8s-io) exposes HTTP and HTTPS routes from outside the cluster to
[Ingress](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ingress-v1-networking-k8s-io) exposes HTTP and HTTPS routes from outside the cluster to
{{< link text="services" url="/docs/concepts/services-networking/service/" >}} within the cluster.
Traffic routing is controlled by rules defined on the Ingress resource.

Expand Down Expand Up @@ -61,23 +61,7 @@ Make sure you review your Ingress controller's documentation to understand the c

A minimal Ingress resource example:

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
serviceName: test
servicePort: 80
```
{{< codenew file="service/networking/minimal-ingress.yaml" >}}

As with all other Kubernetes resources, an Ingress needs `apiVersion`, `kind`, and `metadata` fields.
The name of an Ingress object must be a valid
Expand All @@ -100,70 +84,129 @@ Each HTTP rule contains the following information:
* An optional host. In this example, no host is specified, so the rule applies to all inbound
HTTP 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 associated backend defined with a `serviceName`
and `servicePort`. Both the host and path must match the content of an incoming request before the
load balancer directs traffic to the referenced Service.
* A list of paths (for example, `/testpath`), each of which has an associated
backend defined with a `service.name` and a `service.port.name` or
`service.port.number`. Both the host and path must match the content of an
incoming request before the load balancer directs traffic to the referenced
Service.
* A backend is a combination of Service and port names as described in the
[Service doc](/docs/concepts/services-networking/service/). HTTP (and HTTPS) requests to the
[Service doc](/docs/concepts/services-networking/service/) or a [custom resource backend](#resource-backend) by way of a CRD. HTTP (and HTTPS) requests to the
Ingress that matches the host and path of the rule are sent to the listed backend.

A default backend is often configured in an Ingress controller to service any requests that do not
A `defaultBackend` is often configured in an Ingress controller to service any requests that do not
robscott marked this conversation as resolved.
Show resolved Hide resolved
match a path in the spec.

### Default Backend
### DefaultBackend {#default-backend}

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.
An Ingress with no rules sends all traffic to a single default backend. The `defaultBackend` is conventionally a configuration option
of the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) and is not specified in your Ingress resources.

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

### Resource Backends {#resource-backend}

A `Resource` backend is an ObjectRef to another Kubernetes resource within the
same namespace of the Ingress object. A `Resource` is a mutually exclusive
setting with Service, and will fail validation if both are specified. A common
usage for a `Resource` backend is to ingress data to an object storage backend
with static assets.

{{< codenew file="service/networking/ingress-resource-backend.yaml" >}}

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

```
kubectl describe ingress ingress-resource-backend
```

```
Name: ingress-resource-backend
Namespace: default
Address:
Default backend: APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
Rules:
Host Path Backends
---- ---- --------
*
/icons APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
Annotations: <none>
Events: <none>
```

### Path Types

Each path in an Ingress has a corresponding path type. There are three supported
path types:
Each path in an Ingress is required to have a corresponding path type. Paths
that do not include an explicit `pathType` will fail validation. There are three
supported path types:

* _`ImplementationSpecific`_ (default): With this path type, matching is up to
the IngressClass. Implementations can treat this as a separate `pathType` or
treat it identically to `Prefix` or `Exact` path types.
* `ImplementationSpecific`: With this path type, matching is up to the
IngressClass. Implementations can treat this as a separate `pathType` or treat
it identically to `Prefix` or `Exact` path types.

* _`Exact`_: Matches the URL path exactly and with case sensitivity.
* `Exact`: Matches the URL path exactly and with case sensitivity.

* _`Prefix`_: Matches based on a URL path prefix split by `/`. Matching is case
* `Prefix`: Matches based on a URL path prefix split by `/`. Matching is case
sensitive and done on a path element by element basis. A path element refers
to the list of labels in the path split by the `/` separator. A request is a
match for path _p_ if every _p_ is an element-wise prefix of _p_ of the
request path.

{{< note >}}
If the last element of the path is a substring of the last element in request path, it is not a match (for example: `/foo/bar` matches`/foo/bar/baz`, but does not match `/foo/barbaz`).
{{< /note >}}

{{< note >}} If the last element of the path is a substring of the last
element in request path, it is not a match (for example: `/foo/bar`
matches`/foo/bar/baz`, but does not match `/foo/barbaz`). {{< /note >}}

### Examples

| Kind | Path(s) | Request path(s) | Matches? |
|--------|---------------------------------|-------------------------------|------------------------------------|
| Prefix | `/` | (all paths) | Yes |
| Exact | `/foo` | `/foo` | Yes |
| Exact | `/foo` | `/bar` | No |
| Exact | `/foo` | `/foo/` | No |
| Exact | `/foo/` | `/foo` | No |
| Prefix | `/foo` | `/foo`, `/foo/` | Yes |
| Prefix | `/foo/` | `/foo`, `/foo/` | Yes |
| Prefix | `/aaa/bb` | `/aaa/bbb` | No |
| Prefix | `/aaa/bbb` | `/aaa/bbb` | Yes |
| Prefix | `/aaa/bbb/` | `/aaa/bbb` | Yes, ignores trailing slash |
| Prefix | `/aaa/bbb` | `/aaa/bbb/` | Yes, matches trailing slash |
| Prefix | `/aaa/bbb` | `/aaa/bbb/ccc` | Yes, matches subpath |
| Prefix | `/aaa/bbb` | `/aaa/bbbxyz` | No, does not match string prefix |
| Prefix | `/`, `/aaa` | `/aaa/ccc` | Yes, matches `/aaa` prefix |
| Prefix | `/`, `/aaa`, `/aaa/bbb` | `/aaa/bbb` | Yes, matches `/aaa/bbb` prefix |
| Prefix | `/`, `/aaa`, `/aaa/bbb` | `/ccc` | Yes, matches `/` prefix |
| Prefix | `/aaa` | `/ccc` | No, uses default backend |
| Mixed | `/foo` (Prefix), `/foo` (Exact) | `/foo` | Yes, prefers Exact |
robscott marked this conversation as resolved.
Show resolved Hide resolved

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

## Hostname Wildcards
Hosts can be precise matches (for example “`foo.bar.com`”) or a wildcard (for
example “`*.foo.com`”). Precise matches require that the HTTP `host` header
matches the `host` field. Wildcard matches require the HTTP `host` header is
equal to the suffix of the wildcard rule.

| Host | Host header | Match? |
robscott marked this conversation as resolved.
Show resolved Hide resolved
| ----------- |-------------------| --------------------------------------------------|
| `*.foo.com` | `bar.foo.com` | Matches based on shared suffix |
| `*.foo.com` | `baz.bar.foo.com` | No match, wildcard only covers a single DNS label |
| `*.foo.com` | `foo.com` | No match, wildcard only covers a single DNS label |
robscott marked this conversation as resolved.
Show resolved Hide resolved

{{< codenew file="service/networking/ingress-wildcard-host.yaml" >}}

## Ingress Class

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

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com/v1alpha
kind: IngressParameters
name: external-lb
```
{{< codenew file="service/networking/external-lb.yaml" >}}

IngressClass resources contain an optional parameters field. This can be used to
reference additional configuration for this class.
Expand Down Expand Up @@ -203,18 +246,18 @@ There are existing Kubernetes concepts that allow you to expose a single Service
(see [alternatives](#alternatives)). You can also do this with an Ingress by specifying a
*default backend* with no rules.

{{< codenew file="service/networking/ingress.yaml" >}}
{{< codenew file="service/networking/test-ingress.yaml" >}}

If you create it using `kubectl apply -f` you should be able to view the state
of the Ingress you just added:

```shell
```
kubectl get ingress test-ingress
```

```
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 203.0.113.123 80 59s
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress external-lb * 203.0.113.123 80 59s
```

Where `203.0.113.123` is the IP allocated by the Ingress controller to satisfy
Expand All @@ -231,34 +274,14 @@ A fanout configuration routes traffic from a single IP address to more than one
based on the HTTP URI being requested. An Ingress allows you to keep the number of load balancers
down to a minimum. For example, a setup like:

```none
```
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
```

would require an Ingress such as:

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
```
{{< codenew file="service/networking/simple-fanout-example.yaml" >}}

When you create the Ingress with `kubectl apply -f`:

Expand All @@ -277,8 +300,6 @@ Rules:
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Expand Down Expand Up @@ -309,26 +330,7 @@ bar.foo.com --| |-> bar.foo.com service2:80
The following Ingress tells the backing load balancer to route requests based on
the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
```
{{< codenew file="service/networking/name-virtual-host-ingress.yaml" >}}

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
Expand All @@ -339,31 +341,7 @@ requested for `first.bar.com` to `service1`, `second.foo.com` to `service2`, and
to the IP address without a hostname defined in request (that is, without a request header being
presented) to `service3`.

```yaml
apiVersion: networking.k8s.io/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
```
{{< codenew file="service/networking/name-virtual-host-ingress-no-third-host.yaml" >}}

### TLS

Expand Down Expand Up @@ -393,25 +371,7 @@ secure the channel from the client to the load balancer using TLS. You need to m
sure the TLS secret you created came from a certificate that contains a Common
Name (CN), also known as a Fully Qualified Domain Name (FQDN) for `sslexample.foo.com`.

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
```
{{< codenew file="service/networking/tls-example-ingress.yaml" >}}

{{< note >}}
There is a gap between TLS features supported by various Ingress
Expand Down Expand Up @@ -478,16 +438,22 @@ spec:
http:
paths:
- backend:
serviceName: service1
servicePort: 80
service:
name: service1
port:
number: 80
path: /foo
pathType: Prefix
- host: bar.baz.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
service:
name: service2
port:
number: 80
path: /foo
pathType: Prefix
..
```

Expand Down
10 changes: 10 additions & 0 deletions content/en/examples/service/networking/external-lb.yaml
@@ -0,0 +1,10 @@
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com
kind: IngressParameters
name: external-lb