diff --git a/content/en/docs/concepts/services-networking/ingress.md b/content/en/docs/concepts/services-networking/ingress.md index 430ee3c72d..ca0c0333d1 100644 --- a/content/en/docs/concepts/services-networking/ingress.md +++ b/content/en/docs/concepts/services-networking/ingress.md @@ -7,7 +7,7 @@ weight: 40 --- -{{< feature-state for_k8s_version="v1.1" state="beta" >}} +{{< feature-state for_k8s_version="v1.19" state="stable" >}} {{< glossary_definition term_id="ingress" length="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. @@ -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 @@ -100,32 +84,33 @@ 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 +* 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]() 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 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. ### 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. @@ -134,10 +119,33 @@ path types: 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 | #### Multiple Matches In some cases, multiple paths within an Ingress will match a request. In those @@ -152,18 +160,7 @@ 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. @@ -203,18 +200,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 @@ -231,34 +228,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`: @@ -277,8 +254,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 ---- ------ ---- ---- ------- @@ -309,26 +284,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 @@ -339,31 +295,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 @@ -393,25 +325,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 @@ -478,16 +392,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 .. ``` diff --git a/content/en/examples/service/networking/external-lb.yaml b/content/en/examples/service/networking/external-lb.yaml new file mode 100644 index 0000000000..adcf7a2fd0 --- /dev/null +++ b/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 diff --git a/content/en/examples/service/networking/ingress.yaml b/content/en/examples/service/networking/ingress.yaml deleted file mode 100644 index 56a0d5138f..0000000000 --- a/content/en/examples/service/networking/ingress.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: networking.k8s.io/v1beta1 -kind: Ingress -metadata: - name: test-ingress -spec: - backend: - serviceName: testsvc - servicePort: 80 - diff --git a/content/en/examples/service/networking/minimal-ingress.yaml b/content/en/examples/service/networking/minimal-ingress.yaml new file mode 100644 index 0000000000..76640b9447 --- /dev/null +++ b/content/en/examples/service/networking/minimal-ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: minimal-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - http: + paths: + - path: /testpath + pathType: Prefix + backend: + service: + name: test + port: + number: 80 diff --git a/content/en/examples/service/networking/name-virtual-host-ingress-no-third-host.yaml b/content/en/examples/service/networking/name-virtual-host-ingress-no-third-host.yaml new file mode 100644 index 0000000000..16a560b1ff --- /dev/null +++ b/content/en/examples/service/networking/name-virtual-host-ingress-no-third-host.yaml @@ -0,0 +1,35 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: name-virtual-host-ingress-no-third-host +spec: + rules: + - host: first.bar.com + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: service1 + port: + number: 80 + - host: second.bar.com + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: service2 + port: + number: 80 + - http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: service3 + port: + number: 80 diff --git a/content/en/examples/service/networking/name-virtual-host-ingress.yaml b/content/en/examples/service/networking/name-virtual-host-ingress.yaml new file mode 100644 index 0000000000..213a73d261 --- /dev/null +++ b/content/en/examples/service/networking/name-virtual-host-ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: name-virtual-host-ingress +spec: + rules: + - host: foo.bar.com + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: service1 + port: + number: 80 + - host: bar.foo.com + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: service2 + port: + number: 80 diff --git a/content/en/examples/service/networking/simple-fanout-example.yaml b/content/en/examples/service/networking/simple-fanout-example.yaml new file mode 100644 index 0000000000..19fef9455b --- /dev/null +++ b/content/en/examples/service/networking/simple-fanout-example.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: simple-fanout-example +spec: + rules: + - host: foo.bar.com + http: + paths: + - path: /foo + pathType: Prefix + backend: + service: + name: service1 + port: + number: 4200 + - path: /bar + pathType: Prefix + backend: + service: + name: service2 + port: + number: 8080 diff --git a/content/en/examples/service/networking/test-ingress.yaml b/content/en/examples/service/networking/test-ingress.yaml new file mode 100644 index 0000000000..acd384ab56 --- /dev/null +++ b/content/en/examples/service/networking/test-ingress.yaml @@ -0,0 +1,10 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-ingress +spec: + defaultBackend: + service: + name: test + port: + number: 80 diff --git a/content/en/examples/service/networking/tls-example-ingress.yaml b/content/en/examples/service/networking/tls-example-ingress.yaml new file mode 100644 index 0000000000..fe5d52a0cb --- /dev/null +++ b/content/en/examples/service/networking/tls-example-ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tls-example-ingress +spec: + tls: + - hosts: + - https-example.foo.com + secretName: testsecret-tls + rules: + - host: https-example.foo.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: service1 + port: + number: 80