Attach a Virtual Server to a Kubernetes Ingress

Overview

You can use the BIG-IP Controller for Kubernetes as an Ingress Controller in Kubernetes. To do so, add the BIG-IP Controller Ingress annotations to a Kubernetes Ingress Resource. The annotations define the objects you want to create on the BIG-IP system.

If you use helm, you can use the f5-bigip-ingress chart to create and manage the resources below. You may also use the f5-bigip-ctlr chart to create and manage the resources for the BIG-IP Controller itself.

Note

This document provides set-up instructions for using the BIG-IP Controller as a Kubernetes Ingress Controller. For a functionality overview, see Use the BIG-IP Controller as a Kubernetes Ingress Controller.

Task summary
Step Description
Create a BIG-IP Self IP address for the virtual server.
Define Virtual Server Ingress Annotations in an Ingress Resource.
Health Monitors.
Upload the Ingress to the API server.
Verify object creation on the BIG-IP system.

Initial Setup

Skip this step if:

Allocate a Self IP address from the external network on the BIG-IP system. You will assign this IP address to the Ingress resource. If you’re running the BIG-IP Controller in cluster mode, the IP address must be within the subnet assigned to the BIG-IP VXLAN tunnel.

Note

If you intend to create unattached pools (pools that aren’t attached to a virtual server), you will need to set up another way to route traffic to the pools on the BIG-IP system before proceeding with the steps below.

Annotate Ingress Resources using kubectl

Use kubectl annotate to add the supported Ingress annotations to any existing Ingress resource. It’s good practice to include all of your key-value pairs in a single kubectl annotate command, to avoid piecemeal updates to the BIG-IP system.

The example below creates a virtual server on the BIG-IP with the following settings:

  • set the Ingress class to “f5” to avoid conflicts with other Ingress Controllers;
  • use the default IP address assigned in the k8s-bigip-ctlr Deployment;
  • listen on port 443;
  • create the virtual server in the “k8s” partition;
  • use the BIG-IP “round-robin” load balancing algorithm;
  • create a BIG-IP health monitor;
  • redirect HTTP requests to HTTPS; and
  • deny HTTP requests.
kubectl annotate ingress myIngress kubernetes.io/ingress.class="f5" \
                                   myIngress virtual-server.f5.com/ip="controller-default" \
                                   virtual-server.f5.com/http-port="443" \
                                   virtual-server.f5.com/partition="k8s" \
                                   virtual-server.f5.com/balance="round-robin" \
                                   virtual-server.f5.com/health='[{"path": "svc1.example.com/app1", "send": "HTTP GET /health/svc1", "interval": 5, "timeout": 10}]' \
                                   ingress.kubernetes.io/ssl-redirect="true" \
                                   ingress.kubernetes.io/allow-http="false"

Define Virtual Server Ingress Annotations in an Ingress Resource

You can also define the virtual server settings when creating a new Ingress resource. Define the desired Ingress annotations using valid JSON.

Health Monitors

Use the virtual-server.f5.com/health annotation to add (or update) health monitors to the virtual server for a Kubernetes Ingress resource. You can include it in the resource definition, as shown below, or use the command line (shown in the previous example).

Health Monitor Example
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ing1
  namespace: default
  annotations:
    virtual-server.f5.com/ip: "controller-default"
    virtual-server.f5.com/partition: "k8s"
    virtual-server.f5.com/health: |
      [
        {
          "path":     "svc1.example.com/app1",
          "send":     "HTTP GET /health/app1",
          "interval": 5,
          "timeout":  10
        }, {
          "path":     "svc2.example.com/app2",
          "send":     "HTTP GET /health/app2",
          "interval": 5,
          "timeout":  5
        }
      ]
spec:
  rules:
  - host: svc1.example.com
    http:
      paths:
      - backend:
          serviceName: svc1
          servicePort: 8080
        path: /app1
  - host: svc2.example.com
    http:
      paths:
      - backend:
          serviceName: svc2
          servicePort: 9090
        path: /app2

Use a BIG-IP SSL profile or Secret

You can secure an Ingress using BIG-IP SSL profiles or Kubernetes Secrets.

  1. Specify the SSL profile(s) or the Secret containing the cert and key in the spec.tls section of the Ingress resource.
  2. Add the ingress.kubernetes.io/ssl-redirect annotation (OPTIONAL; defaults to "true").
  3. Add the ingress.kubernetes.io/allow-http annotation (OPTIONAL; defaults to "false").

Note

  • You can specify one or more SSL profiles in your Ingress resource.
  • If you specify a spec.tls section without providing the TLS Ingress properties, the BIG-IP device uses its local traffic policies to redirect HTTP requests to HTTPS.

The table below shows how the Controller behaves for different combinations of the ingress.kubernetes.io/ssl-redirect and ingress.kubernetes.io/allow-http settings.

State sslRedirect allowHttp Description
1 F F Just HTTPS, nothing on HTTP
2 T F HTTP redirects to HTTPS
2 T T Honor sslRedirect == true
3 F T Both HTTP and HTTPS
TLS Ingress example using a BIG-IP SSL profile
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingressTLS
  namespace: default
  annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
    virtual-server.f5.com/ip: "1.2.3.4"
    virtual-server.f5.com/partition: "k8s"
    ingress.kubernetes.io/ssl-redirect: "true"
    ingress.kubernetes.io/allow-http: "false"
spec:
  tls:
    # Provide the name of the BIG-IP SSL profile you want to use.
    - secretName: /Common/clientssl
  backend:
    # Provide the name of a single Kubernetes Service you want to expose to external
    # traffic using TLS
    serviceName: myService
    servicePort: 443

f5-k8s-ingress-tls.yaml

TLS Ingress example using a Secret
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingressTLS
  namespace: default
  annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
    virtual-server.f5.com/ip: "1.2.3.4"
    virtual-server.f5.com/partition: "k8s"
    ingress.kubernetes.io/ssl-redirect: "true"
    ingress.kubernetes.io/allow-http: "false"
spec:
  tls:
    # Provide the name of the Secret you want to use.
    - secretName: myTLSSecret
  backend:
    # Provide the name of a single Kubernetes Service you want to expose to external
    # traffic using TLS
    serviceName: myService
    servicePort: 443


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: no-rules-map
spec:
  tls:
  - secretName: testsecret
  backend:
    serviceName: s1
    servicePort: 80

f5-k8s-ingress-tls-secret.yaml

See also

Refer to the Kubernetes TLS Ingress documentation for details regarding supported port(s) and termination.

Rewrite URLs

The BIG-IP Controller can rewrite URLs for Routes. See Rewrite URLs for more information.

Upload the Ingress to the API server

Use the kubectl apply command to upload your new or edited Ingress resource to the Kubernetes API server.

Tip

When uploading resources that don’t reside in the default namespace, specify the correct namespace using the --namespace (or -n) flag.

kubectl
kubectl apply -f <filename.yaml> [--namespace=<resource-namespace>]

Verify object creation on the BIG-IP system

You can use the BIG-IP configuration utility or a TMOS shell to verify creation/modification/deletion of BIG-IP objects.

Configuration Utility

  • Go to Local Traffic ‣ Virtual Servers.
  • Select the correct partition from the Partition drop-down menu.

TMOS Management Console

admin@(bigip)(cfg-sync Standalone)(Active)(/Common) cd my-partition
admin@(bigip)(cfg-sync Standalone)(Active)(/my-partition) tmsh
admin@(bigip)(cfg-sync Standalone)(Active)(/my-partition)(tmos)$ show ltm virtual
------------------------------------------------------------------
Ltm::Virtual Server: default_myApp.vs_173.16.2.2_80
------------------------------------------------------------------
Status
  Availability     : available
  State            : enabled
  Reason           : The virtual server is available
  CMP              : enabled
  CMP Mode         : all-cpus
  Destination      : 173.16.2.2:80
...
Ltm::Virtual Server: default_myApp.vs_173.16.2.2_443
------------------------------------------------------------------
Status
  Availability     : available
  State            : enabled
  Reason           : The virtual server is available
  CMP              : enabled
  CMP Mode         : all-cpus
  Destination      : 173.16.2.2:443
...

Delete the virtual server

If you want to remove the virtual server associated with an Ingress from the BIG-IP system, but keep the Ingress:

  1. Remove the BIG-IP Controller Annotations from the Ingress definition.

  2. Update the Kubernetes API server.

    Tip

    When uploading resources that don’t reside in the default namespace, specify the correct namespace using the --namespace (or -n) flag.

    kubectl
    kubectl apply -f <filename.yaml> [--namespace=<resource-namespace>]
    

See also

See Manage Your BIG-IP Virtual Servers for more information.

Example Ingress Resources

Single Service

A Single Service Ingress creates a BIG-IP virtual server and server pool for a single Kubernetes Service.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: singleIngress1
  namespace: default
  annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
    virtual-server.f5.com/ip: "1.2.3.4"
    virtual-server.f5.com/partition: "k8s"
spec:
  backend:
    # The name of the Service you want to expose to external traffic
    serviceName: myService
    servicePort: 80

f5-k8s-single-ingress.yaml

Simple Fanout

A Simple Fanout Ingress creates a BIG-IP virtual server and pools for a group of Kubernetes Services (one pool per Service).

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ing-fanout
  namespace: default
  annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
    virtual-server.f5.com/ip: "1.2.3.4"
    virtual-server.f5.com/partition: "k8s"
    virtual-server.f5.com/balance: "least-connections-node"
spec:
  rules:
  - host: mysite.example.com
    http:
      paths:
      - path: /app1
        backend:
          serviceName: myService1
          servicePort: 80
      - path: /app2
        backend:
          serviceName: myService2
          servicePort: 80

f5-k8s-ingress-fanout.yaml

Name-based virtual hosting

A Name-based virtual hosting ingress creates the following BIG-IP objects:

  • One virtual server
  • One pool per Service
  • Local traffic policies to route requests to specific pools based on host name and path.

Tip

If you don’t specify any hosts or paths for the Service named in the backend section of the Ingress resource, the BIG-IP device will proxy traffic for all hosts/paths.

Specific hosts
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: ing-virtual-hosting
 namespace: default
 annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
  virtual-server.f5.com/ip: "1.2.3.4"
  virtual-server.f5.com/partition: "k8s"
  virtual-server.f5.com/balance: "least-connections-node"
  virtual-server.f5.com/http-port: "80"
spec:
 rules:
 # URL
 - host: site1.example.com
   http:
     # path to Service from URL
     paths:
       - path: /app1
         backend:
           serviceName: myService1
           servicePort: 80
 # URL
 - host: site2.example.com
   http:
     # path to Service from URL
     paths:
       - path: /app2
         backend:
           serviceName: myService2
           servicePort: 80

f5-k8s-ingress-virtual-hosting.yaml

All hosts
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: ing-virtual-hosting
 namespace: default
 annotations:
  # See the k8s-bigip-ctlr documentation for information about
  # all Ingress Annotations
  # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/#supported-ingress-annotations
  virtual-server.f5.com/ip: "1.2.3.4"
  virtual-server.f5.com/partition: "k8s"
  virtual-server.f5.com/balance: "least-connections-node"
  virtual-server.f5.com/http-port: "80"
spec:
 rules:
 # Omit the host name (URL) to match all hosts
 - http:
     # Provide the path to each Service you want to proxy
     paths:
     - path: /app1
       backend:
         serviceName: myService1
         servicePort: 80
     - path: /app2
       backend:
         serviceName: myService2
         servicePort: 80

f5-k8s-ingress-virtual-hosting_all.yaml