It’s been almost a year since my original article that discussed the basics of using the Docker API to configure BIG-IP pool members. This article dives into more details of utilizing the F5 Python SDK to dynamically update the BIG-IP using Kubernetes as an example. This is meant as a guide for those that are interested in the internals of how to utilize the BIG-IP iControl REST API.
Those that are interested in an integrated solution with Kubernetes and F5 BIG-IP should take a look at RedHat OpenShift. This provides a platform for hosting containers that integrates with F5 BIG-IP. There are also community efforts lead by F5 customers to integrate their BIG-IP with Kubernetes (using Go instead of Python that is used in the example). If you’re interested in learning more about F5 and containers please contact your local F5 account team.
Kubernetes Service Load Balancer / Ingress Router
For the following example we’re using Kubernetes as the example infrastructure. Kubernetes enables an infrastructure that provides a structure for hosting containers (Docker / rkt). The challenge with using Kubernetes and BIG-IP is that services tend to be ephemeral in Kubernetes making it hard to use traditional means (GUI/TMSH) of configuring pool members and virtual servers. Kubernetes also has the notion of a “service load balancer” and “ingress router” that can be configured from within Kubernetes. The example code takes the approach of fetching data from Kubernetes about its “service load balancer” and “ingress router” and uses it to configure the BIG-IP.
The pseudo code of my example is the following:
# Step 1: Connect to BIG-IP
bigip_client = BigIPManagement();
# Step 2: Connect to Kubernetes
kubernetes_client = KubernetesManagement();
# Step 3: Get everything I want from Kubernetes
everything_i_want = kubernetes_client.get_everything_you_want();
# Step 4: Update BIG-IP with everything you want
There are numerous ways to integrate your infrastructure with BIG-IP. The most basic method is to write directly to the iControl REST API using your preferred programming platform. This works well and is documented up on DevCentral. There also exist language specific bindings/libraries. Here’s a few examples:
Each method has its pros/cons. For the use-case of connecting to Kubernetes I opted for the Python SDK because I know Python and it’s easier for me to program (I did try to do this in Go and I gave up). In general I’d recommend using an automation tool that works best for you. Programmers may prefer the native iControl REST API, System Engineers may prefer CM tools like Puppet, and Network Engineers will utilize infrastructure tools that are made available to them. You can also combine tools as long as you have clear lines of separation (i.e. use partitions or naming convention to keep things sane).
Step 2: Connecting to your external data source
Generally you’re interested in automation because you have data in one place that you would like to synchronize from one source to another. You might have configurations that live in an Excel spread sheet, CSV/TXT/YAML/JSON file, MySQL database, etcd, etc… For my example I utilized two libraries to connect to Kubernetes:
1. Pykube: Python library that connects to Kubernetes admin API
2. Python-etcd: Python library that connects to backend data store that flannel uses for storing network data
Step 3: Get everything I want from Kubernetes
Using these libraries I fetch information from Kubernetes about the “service load balancers” that have been defined (virtual service / pool members), ingress routers (LTM policies / L7 content routing). The second library is used for a more advanced example that allows one to use the BIG-IP SDN capability to connect to the VXLAN network that can be utilized by Kubernetes (look at the code for details…).
Step 4: Update BIG-IP with everything you want
Once you have all the data that you have from Kubernetes you need to make decisions on what you want to update. For the example it creates/updates virtual servers, pool members, wide-ips, and routes. Depending on the use-case you may want to only update a subset of the options. In an existing deployment you may want to only update a designated LTM pool and not modify any other objects. You may also want to opt between different options of how to make the update. For customers that have developed their own iApps they may want to leverage these iApp to help ensure a more consistent deployment.
iWorkFlow: Keeping the peace
Ideally the application, system, security, and network teams will have a trust model that enables an application developer to promote a change in their application that will immediately propagate to production. In cases where RBAC controls are required to limit actions (i.e. app developer can only add/remove pool members from the pool named “app_owner_pool”) iWorkFlow can be utilized as a REST-PROXY to the BIG-IP and apply resource level RBAC. This can allow for separate automation identities “kubernetes_automation_agent_userid” and automation roles “kubernetes_only_allow_pool_update_role”.
Go for automation
Again, this is a Python example, but the same basic flow will exist for many use-cases. For a deep dive into some Python code that also handles the provisioning of “bare metal” (VE/vCMP) hosts take a look at the f5-openstack-agent. This covers some of the steps commonly involved in managing your BIG-IP.
This has been a very imperative (step-by-step) example of managing your BIG-IP, but take a look at Chef, Puppet, Ansible, HEAT, and Cloud Formation templates for better ways to be more declarative.