on 14-Nov-2019 13:22
How do you prevent double monitoring when a Load Balancer load balances a Load Balancer? Using the NGINX Plus API we can leverage a BIG-IP to monitor the state of your applications and avoid monitoring your applications twice!
You decide on an architecture of having a BIG-IP load balance your NGINX Plus load balancer.
In this topology how does the BIG-IP know whether an application that is running behind NGINX Plus is “healthy”?
One solution is to configure both NGINX Plus and BIG-IP to monitor the health of the application. This leads into log entries on your backend server that look like the following:
… …17:13:46 …] "GET / HTTP/1.0" 200 139 "-" "nginx/1.17.3 (health check)" … …17:13:47 …] "GET / HTTP/1.0" 200 139 "-" "Custom BIG-IP Monitor”
In this example you can see the application is being polled twice, once by the BIG-IP and once by NGINX Plus.
NGINX Plus has an API that can return the status of its upstreams (equivalent to a BIG-IP pool). An example of the output
Using this API we can configure the BIG-IP to monitor the NGINX Plus API instead of the backend application (and avoid double monitoring).
The configuration for the BIG-IP is straightforward, create a monitor that queries the NGINX API.
In this Local Traffic Manager (LTM) example we are querying the “app001” upstream and looking for the string “state”:”up” that indicates at least one server is available.
This can also apply to DNS as well.
This is an example of how to use BIG-IP and NGINX Plus together.
Additional considerations that you should think about is how to secure access to the NGINX Plus API (IP restriction, Basic Auth, etc…).
Ideally you should automate/template the configuration of both devices to avoid double configuration; a topic for another article.
an example
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
import urllib2
import json
def get_nginxapi(url):
ct_headers = {'Content-type':'application/json'}
request = urllib2.Request(url,headers=ct_headers)
response = urllib2.urlopen(request)
html = response.read()
return html
api = sys.argv[3]
try:
data = get_nginxapi(api)
data = json.loads(data)
except:
data = ''
m = 0
lowwater = int(sys.argv[4])
try:
for peer in data['peers']:
state = peer['state']
if state == 'up':
m = m + 1
except:
m = 0
#print data['peers'][]['state']
#print m
if m >= lowwater:
print 'UP'
very nice! I have another blog post coming up that is similar in idea. The basic idea is to collect the number of available upstreams and use that as information to update the BIG-IP. The article uses NGINX JavaScript (NJS) to do the lookup on NGINX (vs. externally via Python). Once the article is posted; I'll post the link here.
here's the article that I mentioned earlier: https://www.nginx.com/blog/just-one-post-declarative-dns-with-f5-and-nginx-javascript/