consul/website/source/docs/guides/consul-f5.md

11 KiB
Raw Blame History

In this guide you will use Consul to configure F5 BIG-IP nodes and server pools. You will set up a basic F5 BIG-IP AS3 declaration that generates the load balancer backend-server-pool configuration based on the available service instances registered in Consul service discovery.

Prerequisites

To complete this guide, you will need previous experience with F5 BIG-IP and Consul. You can either manually deploy the necessary infrastructure, or use the terraform demo code.

Watch the Video - Optional

Consul's intetgration with F5 was demonstrated in a webinar. If you would prefer to lear about the integration but aren't ready to try it out, you can watch the webinar recording instead.

Manually deploy your infrastructure

You should configure the following infrastructure.

  • A single Consul datacenter with server and client nodes, and the configuration directory for Consul agents at /etc/consul.d/.

  • A running instance of the F5 BIG-IP platform. If you dont already have one you can use a hosted AWS instance for this guide.

  • The AS3 package version 3.7.0 installed on your F5 BIG-IP platform.

  • Standard web server running on a node, listening on HTTP port 80. We will use NGINX in this guide.

Deploy a demo using Terraform - Optional

You can set up the prerequisites on your own, or use the terraform configuration in this repository to set up a testing environment.

Once your environment is set up, you'll be able to visit the F5 GUI at <F5_IP>:8443/tmui/login.jsp where <F5_IP> is the address provided in your Terraform output. Login with the username admin and the password from your Terraform output.

Verify your environment

Check your environment to ensure you have a healthy Consul datacenter by checking your datacenter members. You can do this by running the consul members command on the machine where Consul is running, or by accessing the Consul web UI at the IP address of your consul instances, on port 8500.

$ consul memberss
Node           Address          Status  Type    Build  Protocol  DC   Segment
consul         10.0.0.100:8301  alive   server  1.5.3  2         dc1  <all>
nginx          10.0.0.109:8301  alive   client  1.5.3  2         dc1  <default>

In this sample environment we have one Consul server node, and one web server node with a Consul client.

Register a Web Service

To register the web service on one of your client nodes with Consul, create a service definition in Consul's config directory /etc/consul.d/ named nginx-service.json. Paste in the following configuration, which includes a tcp check for the web server so that Consul can monitor its health.

{
  "service": {
    "name": "nginx",
    "port": 80,
    "checks": [
      {
        "id": "nginx",
        "name": "nginx TCP Check",
        "tcp": "localhost:80",
        "interval": "5s",
        "timeout": "1s"
      }
    ]
  }
}

Reload the client to read the new service definition.

$ consul reload

In a broswer window, visit the services page of the Consul web UI at <your-consul-ip>:8500/ui/dc1/services/nginx.

Consul UI with NGINX registered

You should notice your instance of the nginx service listed and healthy.

Apply an AS3 Declaration

Next you will configure BIG-IP to use Consul Service discovery with an AS3 declaration. You will use cURL to apply the declaration to the BIG-IP Instance.

First construct an authorization header to authenticate our API call with BIG-IP. You will need to use a username and password for your instance. Below is an example for username “admin”, and password “password”.

$ echo -n 'admin:password' | base64
YWRtaW46YWRtaW4=

Now use cURL to send the authorized declaration to the BIG-IP Instance. Use the value you created above for your BIG-IP instance in the authorization header. Remember t o replace <your-BIG-IP-mgmt-ip> with the real IP address.

$ curl -X POST \
  https://<your-BIG-IP-mgmt-ip>/mgmt/shared/appsvcs/declare \
  -H 'authorization: Basic <your-authorization-header>' \
  -d '{
    "class": "ADC",
    "schemaVersion": "3.7.0",
    "id": "Consul_SD",
        "controls": {
        "class": "Controls",
        "trace": true,
        "logLevel": "debug"
    },
    "Consul_SD": {
      "class": "Tenant",
      "Nginx": {
        "class": "Application",
        "template": "http",
        "serviceMain": {
          "class": "Service_HTTP",
          "virtualPort": 8080,
          "virtualAddresses": [
            "<your-BIG-IP-virtual-ip>"
          ],
          "pool": "web_pool"
        },
        "web_pool": {
          "class": "Pool",
          "monitors": [
            "http"
          ],
          "members": [
            {
              "servicePort": 80,
              "addressDiscovery": "consul",
              "updateInterval": 5,
              "uri": "http://<your-consul-ip>:8500/v1/catalog/service/nginx"
            }
          ]
        }
      }
    }
}
'

You should get a similar output to the following after youve applied your declaration.

{
  "results": [
    {
      "message": "success",
      "lineCount": 26,
      "code": 200,
      "host": "localhost",
      "tenant": "Consul_SD",
      "runTime": 3939
    }
  ],
  "declaration": {
    "class": "ADC",
    "schemaVersion": "3.7.0",
    "id": "Consul_SD",
    "controls": {
      "class": "Controls",
      "trace": true,
      "logLevel": "debug",
      "archiveTimestamp": "2019-09-06T03:12:06.641Z"
    },
    "Consul_SD": {
      "class": "Tenant",
      "Nginx": {
        "class": "Application",
        "template": "http",
        "serviceMain": {
          "class": "Service_HTTP",
          "virtualPort": 8080,
          "virtualAddresses": [
            "10.0.0.200"
          ],
          "pool": "web_pool"
        },
        "web_pool": {
          "class": "Pool",
          "monitors": [
            "http"
          ],
          "members": [
            {
              "servicePort": 80,
              "addressDiscovery": "consul",
              "updateInterval": 5,
              "uri": "http://10.0.0.100:8500/v1/catalog/service/nginx"
            }
          ]
        }
      }
    },
    "updateMode": "selective"
  }
}

The above declaration does the following:

  • Creates a partition (tenant) named Consul_SD.

  • Defines a virtual server named serviceMain in Consul_SD partition with:

    • A pool named web_pool monitored by the http health monitor.

    • NGINX Pool members autodiscovered via Consul's catalog HTTP API endpoint. For the virtualAddresses make sure to substitute your BIG-IP Virtual Server.

    • A URI specific to your Consul environment for the scheme, host, and port of your consul address discovery. This could be a single server, load balanced endpoint, or co-located agent, depending on your requirements. Make sure to replace the uri in your configuration with the IP of your Consul client.

You can find more information on Consul SD declarations in F5s Consul service discovery documentation

You can read more about composing AS3 declarations in the F5 documentation. The Terraform provider for BIG-IP also supports AS3 resources.

Verify BIG-IP Consul Communication

Use the consul monitor command on the consul agent specified in the AS3 URI to verify that you are receiving catalog requests from the BIG-IP instance.

$ consul monitor -log-level=debug
2019/09/06 03:16:50 [DEBUG] http: Request GET /v1/catalog/service/nginx (103.796µs) from=10.0.0.200:29487
2019/09/06 03:16:55 [DEBUG] http: Request GET /v1/catalog/service/nginx (104.95µs) from=10.0.0.200:42079
2019/09/06 03:17:00 [DEBUG] http: Request GET /v1/catalog/service/nginx (98.652µs) from=10.0.0.200:45536
2019/09/06 03:17:05 [DEBUG] http: Request GET /v1/catalog/service/nginx (101.242µs) from=10.0.0.200:45940

Check that the interval matches the value you supplied in your AS3 declaration.

Verify the BIG-IP Dynamic Pool

Check the network map of the BIG-IP instance to make sure that the NGINX instances registered in Consul are also in your BIG-IP dynamic pool.

To check the network map, open a browser window and navigate to https://<your-big-IP-mgmt-ip>/tmui/tmui/locallb/network_map/app/?xui=false#!/?p=Consul_SD. Remember to replace the IP address.

NGINX instances in BIG-IP

You can read more about the network map in the F5 documentation.

Test the BIG-IP Virtual Server

Now that you have a healthy virtual service, you can use it to access your web server.

$ curl <your-BIG-IP-virtual-ip>:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Summary

The F5 BIG-IP AS3 service discovery integration with Consul queries Consul's catalog on a regular, configurable basis to get updates about changes for a given service, and adjusts the node pools dynamically without operator intervention.

In this guide you configured an F5 BIG-IP instance to natively integrate with Consul for service discovery. You were able to monitor dynamic node registration for a web server pool member, and test it with a virtual server.

As a follow up, you can add or reemove web server nodes reegistered with Consul and validate that the network map on the F5 BIG-IP updates automatically.