Connecting Docker to BIG-IP

The following is an example of using BIG-IP to automate the routing of HTTP and DNS requests for containers across a Docker cluster. The process for connecting Docker to BIG-IP will involve exporting the list of containers that are running on a Docker host and enabling a process to route HTTP and DNS requests to the appropriate Docker container.

How it works

A Python script is used as the orchestration agent in this example, but other languages and/or tools could be used as an alternative.  Here's an overview of the flow using the different actors:

Python Script: Hello Docker, please tell me all the names of containers and ip:port services that they are offering.
Docker API: Sure, here’s a list of the information that you requested.
Python Script: I’ve compiled a list of the pool and members for you BIG-IP, please update your services.
BIG-IP API: Thank you. I’ve updated my configuration.
Client: I’d like to access www.example.com.
BIG-IP Virtual Server: Sure, let me find that container…. Here you go.

The details of how it works are below and the code can be found on DevCentral codeshare.

Routing

To enable the BIG-IP to be able to connect directly to individual Docker containers and to allow Docker containers to communicate between hosts we create separate private network ranges on each Docker host and create static routes to each host. By using the BIG-IP as the default gateway or setting static routes from the Docker host we can then enable containers to communicate across different hosts.

Python Script

The python script interacts with the Docker and BIG-IP APIs to:

1. Grab a list of Docker containers that will be in BIG-IP pools

2. Create/Update/Delete BIG-IP LTM pools that are related to a Docker cluster

3. Update data groups to be used by LTM for service/container discovery

GTM Wide-IP

When a client requests a DNS name the GTM Wide-IP answers the request and sends it to the appropriate virtual server.

HTTP iRule

The HTTP iRule uses the information to map requests to Docker containers. A naming convention is used to map names. For example requests for “www.example.com” would be load balanced to containers named “www-1”, “www-2”, etc…. It will also alternately route requests for www-1.example.com to the individual container as well.

DNS iRule

By default Docker will update the /etc/hosts file of a container to route DNS requests to the correct container. When dealing with a cluster of Docker hosts the Python script will export the DNS information to the BIG-IP and allow DNS queries that span multiple hosts. The DNS iRule maps container names to container IP addresses.  This assumes that there’s routing in place to allow containers to communicate to each other and that the BIG-IP is either the primary or delegated DNS source.

Results

Using the previous steps results in an environment where changes to the Docker hosts can be rapidly deployed to the BIG-IP and the BIG-IP can adjust to loss/changes of individual containers or hosts. Utilizing a second data center the example could be expanded to include failover between separate data center and/or cloud environments.  This example focused on HTTP and DNS, but it could be expanded to other protocols/services by modifying the script/configurations. 

Connecting to the pool name “www” and the container name “www-3”. Performing DNS lookups on service and container names.

Connecting from container on host “docker1” to container on host “docker2” via BIG-IP.

Published Sep 02, 2015
Version 1.0

Was this article helpful?

4 Comments

  • Has anybody experimented defining a Software-based Load Balancer such as using HAProxy in Docker? That way, the load balancing of the Docker instances would be independent of container list? This looks so promising!
  • Using a software load balancer (SLB) would be an option. A lot will depend on the requirements. The attached example is meant to be independent of the service type and could be as varied as a node.js HTTP/HTTPS micro service, UDP syslog collector, or any technology that receives an IP packet. I'll follow-up with your other comments in the codeshare.