Ingress

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

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

Terminology

  • 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.
  • 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.
  • Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the Kubernetes networking model.
  • Service: A Kubernetes 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.

What is Ingress?

Ingress, added in Kubernetes v1.1, exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the ingress resource.

  internet
      |
 [ Ingress ]
 --|-----|--
 [ Services ]

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 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.

An ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.

Prerequisites

FEATURE STATE: Kubernetes v1.1 beta

GCE/Google Kubernetes Engine deploys an ingress controller on the master.

In environments other than GCE/Google Kubernetes Engine, you may need to deploy an ingress controller. There are a number of ingress controllers you may choose from.

Ingress controllers

In order for the ingress resource to work, the cluster must have an ingress controller running. This is unlike other types of controllers, which run as part of the kube-controller-manager binary, and are typically started automatically with a cluster. Choose the ingress controller implementation that best fits your cluster.

Kubernetes as a project currently supports and maintains GCE and nginx controllers.

Additional controllers include:

  • Contour is an Envoy based ingress controller provided and supported by Heptio.
  • F5 Networks provides support and maintenance for the F5 BIG-IP Controller for Kubernetes.
  • HAProxy based ingress controller jcmoraisjr/haproxy-ingress which is mentioned on the blog post "HAProxy Ingress Controller for Kubernetes". HAProxy Technologies offers support and maintenance for HAProxy Enterprise and the ingress controller jcmoraisjr/haproxy-ingress.
  • Istio based ingress controller Control Ingress Traffic.
  • Kong offers community or commercial support and maintenance for the Kong Ingress Controllerfor Kubernetes.
  • NGINX, Inc. offers support and maintenance for the NGINX Ingress Controller for Kubernetes.
  • Traefik is a fully featured ingress controller (Let’s Encrypt, secrets, http2, websocket), and it also comes with commercial support by Containous.

You may deploy any number of ingress controllers within a cluster. When you create an ingress, you should annotate each ingress with the appropriate ingress-class to indicate which ingress controller should be used if more than one exists within your cluster. If you do not define a class, your cloud provider may use a default ingress provider.

The Ingress Resource

A minimal ingress resource example:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /testpath
            backend:
              serviceName: test
              servicePort: 80

As with all other Kubernetes resources, an ingress needs apiVersion, kind, and metadata fields.

Ingress frequently uses annotations to configure some options depending on the ingress controller, an example of which is the rewrite-target annotation. Different ingress controller support different annotations. Review the documentation for your choice of ingress controller to learn which annotations are supported.

The ingress spec 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 for directing HTTP traffic.

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 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 and servicePort. Both the host and path must match the content of an incoming request before the loadbalancer will direct traffic to the referenced service.
  • A backend is a combination of service and port names as described in the services doc. HTTP (and HTTPS) requests to the ingress matching the host and path of the rule will be sent to the listed backend.

A default backend is often configured in an ingress controller that will service any requests that do not match a path in the spec.

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 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.

Types of Ingress

Single Service Ingress

You can expose a single Service in multiple ways that don’t directly involve the ingress resource:

  • Use Service.Type=LoadBalancer
  • Use Service.Type=NodePort
  • Use a Port Proxy

You can do this with an ingress by specifying a default backend with no rules.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  backend:
    serviceName: testsvc
    servicePort: 80

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 loadbalancers down to a minimum. For example, a setup like:

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

would require an ingress such as:

apiVersion: extensions/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
EOF

The ingress controller will provision an implementation specific loadbalancer that satisfies the ingress, as long as the services (service1, service2) exist.

Name based virtual hosting

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

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

The following ingress tells the backing loadbalancer to route requests based on the Host header.

apiVersion: extensions/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

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 requested for first.bar.com to service1, second.bar.com to service2, and any traffic to the IP address without a hostname defined in request (that is, without a request header being presented) to service3.

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

TLS

You can secure an ingress by specifying a secret that contains a TLS private key and certificate. Currently the ingress only supports a single TLS port, 443, and assumes TLS termination. If the TLS configuration section in an ingress specifies different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the ingress controller supports SNI). The TLS secret must contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS, e.g.:

apiVersion: v1
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
type: Opaque

Referencing this secret in an ingress will tell the ingress controller to 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.

apiVersion: extensions/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

Loadbalancing

An ingress controller is bootstrapped with some load balancing policy settings that it applies to all ingress, such as the load balancing algorithm, backend weight scheme, and others. More advanced load balancing concepts (e.g. persistent sessions, dynamic weights) are not yet exposed through the ingress. You can still get these features through the service loadbalancer.

It’s also worth noting that even though health checks are not exposed directly through the ingress, there exist parallel concepts in Kubernetes such as readiness probes which allow you to achieve the same end result.

results matching ""

    No results matching ""