Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 111 lines (92 sloc) 3.36 KB
#!/usr/bin/python
# Kubernetes to HA Proxy config updater script
# Copyright (C) 2017 Glen Pitt-Pladdy
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# See: https://www.pitt-pladdy.com/blog/_20170328-130720_0100_Kubernetes_to_learn_Part_4/
#
import json
import subprocess
import time
import sys
import os
template = '/etc/haproxy/haproxy.cfg.TEMPLATE'
outputcfg = '/etc/haproxy/haproxy.cfg'
polldelay = 5
def getnodes():
p = subprocess.Popen ( ['kubectl','get','nodes','-o','json'], stdout=subprocess.PIPE, stderr=subprocess.PIPE )
stdout,stderr = p.communicate()
return json.loads ( stdout )
def getservices():
p = subprocess.Popen ( ['kubectl','get','services','-o','json'], stdout=subprocess.PIPE, stderr=subprocess.PIPE )
stdout,stderr = p.communicate()
return json.loads ( stdout )
def reloadhaproxy():
p = subprocess.Popen ( ['systemctl','reload','haproxy'], stdout=None, stderr=None )
lastconfig = ''
while True:
# get all our nodes
nodes = []
for node in getnodes()['items']:
for state in node['status']['conditions']:
if state['type'] == 'Ready' and state['status'] == 'True':
# good node - add this
for address in node['status']['addresses']:
if address['type'] == 'InternalIP':
nodes.append ( address['address'] )
break
break
# ingest all our services
services = {}
for service in getservices()['items']:
if service['spec']['type'] == 'NodePort':
app = service['spec']['selector']['app']
if app not in services: services[app] = {}
tier = service['spec']['selector']['tier']
if 'tier' not in services: services[app][tier] = {}
for portspec in service['spec']['ports']:
if portspec['protocol'] != 'TCP': continue # we can't do this
services[app][tier][portspec['port']] = portspec['nodePort']
# generate HA Proxy config snipped
config = "\n# automatically generated by %s\n\n" % sys.argv[0]
portused = {}
for app in services:
for tier in services[app]:
for port in services[app][tier]:
# frontend
config += "frontend %s_%s\n" % (app,tier)
listenport = int(port)
while listenport in portused: listenport += 1
portused[listenport] = True
config += "\tbind *:%d\n" % listenport
config += "\tdefault_backend %s_%s\n" % (app,tier)
# backend
config += "backend %s_%s\n" % (app,tier)
config += "\tbalance roundrobin\n"
for node in nodes:
config += "\tserver %s %s:%s check\n" % (node.replace('.','_'),node,services[app][tier][port])
if config != lastconfig:
print
print "Configuration Changed!"
print config
with open ( template, 'rt' ) as fi:
with open ( outputcfg+'.TMP', 'wt' ) as fo:
fo.write ( fi.read() )
fo.write ( config )
os.rename ( outputcfg+'.TMP', outputcfg )
reloadhaproxy ()
lastconfig = config
time.sleep ( polldelay )