Ingress

What is Ingress?

Kubernetes supports a high-level abstraction called Ingress, which allows simple host or URL-based HTTP routing. An Ingress is a core concept of Kubernetes, but it is always implemented by a third party proxy. These implementations are known as Ingress controllers. An Ingress controller is responsible for reading the Ingress resource information and processing that data accordingly. Different Ingress controllers have extended the specification in different ways to support additional use cases.

In Kubernetes, an Ingress is an object that allows access to your Kubernetes services from outside the Kubernetes cluster. You configure access by creating a collection of rules that define which inbound connections reach which services.

../_images/ingress-diagram.png

Ingress is tightly integrated into Kubernetes, meaning that your existing workflows around kubectl will likely extend to managing Ingress. Note that an Ingress controller typically does not eliminate the need for an external load balancer. The Ingress controller simply adds an additional layer of routing and control behind the load balancer.

For example, you might want to send requests to example.com/api/v1/ to an api-v1 service, and requests to example.com/api/v2/ to the api-v2 service. With an Ingress, you can easily set this up without creating several LoadBalancers or exposing each service on the Node.

Why use Ingress?

You can use Ingress to make internal services reachable from outside the cluster. It saves static IPs, as you will not need to declare multiple LoadBalancer services.

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

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

The Ingress spec has all the information needed to configure a load balancer 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 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 backend is a combination of Service and port names. HTTP (and HTTPS) requests to the Ingress that match the host and path of the rule are sent to the listed backend.

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.

Path types:

Each path in an Ingress has a corresponding path type. There are three supported path types:

  • 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.
  • Exact: Matches the URL path exactly and with case sensitivity.
  • 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.

Types of Ingress

  • Single Service Ingress: You can expose a single service by specifying default backend with no rules. For example:

    Single Service Ingress
          apiVersion: networking.k8s.io/v1beta1
          kind: Ingress
          metadata:
            name: test-f5-ingress
          spec:
            backend:
              serviceName: test-service
              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.

    Simple Fanout
          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
    

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

    Name base virtual hosting
          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
    

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

    The TLS secret must contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS. For example:

    Secret
          apiVersion: v1
          kind: Secret
          metadata:
            name: example-secret-tls
            namespace: default
          data:
            tls.crt: base64 encoded cert
            tls.key: base64 encoded key
          type: kubernetes.io/tls
    

    Referencing this secret in an Ingress tells the Ingress controller to secure the channel from the client to the load balancer using TLS. You need to make 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 example.com

    TLS
          apiVersion: networking.k8s.io/v1beta1
          kind: Ingress
          metadata:
            name: tls-example-ingress
          spec:
            tls:
            - hosts:
              - sslexample.foo.com
              secretName: example-secret-tls
            rules:
              - host: sslexample.com
                http:
                  paths:
                  - path: /
                    backend:
                      serviceName: service1
                      servicePort: 80
    
  • Load balancing: 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 instead get these features through the load balancer used for a Service.


How to deploy Ingress

Prerequisites

In order to deploy Ingress, you must have:

  • an Ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect.
  • You may need to deploy an Ingress controller such as F5 Networks provides F5 BIG-IP Controller for Kubernetes. You can choose from a number of Ingress controllers. For example, Nginx-ingress, HAProxy Ingress, etc.

Quickstart

  1. Create an Ingress resource. In this example, we create two services to demonstrate how the Ingress routes our request. We run two web applications that output a slightly different response.

    kind: Pod
    apiVersion: v1
    metadata:
      name: foo-app
      labels:
        app: foo
    spec:
      containers:
        - name: foo-app
          image: f5/img
          args:
            - "-text=foo"
    
    ---
    
    kind: Service
    apiVersion: v1
    metadata:
      name: foo-service
    spec:
      selector:
        app: foo
      ports:
        - port: 5678 # Default port for image
    
    kind: Pod
    apiVersion: v1
    metadata:
      name: bar-app
      labels:
        app: bar
    spec:
      containers:
        - name: bar-app
          image: f5/img
          args:
            - "-text=bar"
    
    ---
    
    kind: Service
    apiVersion: v1
    metadata:
      name: bar-service
    spec:
      selector:
        app: bar
      ports:
        - port: 5678 # Default port for image
    
  2. Create the resources:

    $ kubectl apply f  foo-app.yaml
    $ kubectl apply f bar app.yaml
    
  3. Declare an Ingress to route requests to /foo to the first service, and requests to /bar to the second service:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: example-ingress
    annotations:
        ingress.kubernetes.io/rewrite-target: /
    spec:
    rules:
    - http:
        paths:
            - path: /foo
            backend:
                serviceName: foo-service
                servicePort: 5678
            - path: /bar
            backend:
                serviceName: bar-service
                servicePort: 5678
    

    Note

    Inside your Ingress configuration you can only redirect to services in the same namespace.

  4. Create the Ingress in the cluster:

    kubectl create -f ingress.yaml
    
  5. Verify that it is working:

    $ curl -kL http://localhost/foo
    foo
    
    $ curl -kL http://localhost/bar
    bar
    
    $ curl -kL http://localhost/notfound
    default backend - 404
    

Repository

See the repository on GitHub for more examples.


Note

To provide feedback on Container Ingress Services or this documentation, you can file a GitHub Issue.