Reverse proxy to Kubernetes cluster NodePort through nginx
#!/usr/bin/env python | |
import os | |
import subprocess | |
import argparse | |
import json | |
from oauth2client.client import GoogleCredentials | |
from googleapiclient import discovery | |
nginx_conf = """ | |
upstream %(name)s { | |
%(servers)s | |
} | |
server { | |
listen %(listen_ip)s:%(listen_port)s; | |
location / { | |
proxy_pass http://%(name)s; | |
} | |
} | |
""" | |
nginx_conf_dir = "/etc/nginx/sites-enabled" | |
def main(): | |
parser = argparse.ArgumentParser("Watch GKE node IPs for changes") | |
parser.add_argument("-p", "--project", required=True, help="Project to list instances for") | |
parser.add_argument("-z", "--zones", required=True, action="append", help="Zones to list instances for") | |
parser.add_argument("name", help="Meaningful name of your forwarding rule") | |
parser.add_argument("gke_prefix", metavar="gke-prefix", help="GKE node prefix to monitor and forward to") | |
parser.add_argument("listen_ip", metavar="listen-ip", help="IP listen on") | |
parser.add_argument("listen_port", metavar="listen-port", type=int, help="Port to listen on") | |
parser.add_argument("target_port", metavar="target-port", type=int, help="IP listen on") | |
args = parser.parse_args() | |
credentials = GoogleCredentials.get_application_default() | |
compute = discovery.build('compute', 'v1', credentials=credentials) | |
instances = [] | |
for zone in args.zones: | |
instances.extend(compute.instances().list(project=args.project, zone=zone).execute()["items"]) | |
ips = [] | |
for ins in instances: | |
if not ins["name"].startswith(args.gke_prefix): | |
continue | |
ips.extend( (nic["networkIP"] for nic in ins["networkInterfaces"]) ) | |
ips = sorted(ips) | |
args.servers = "\n".join((" server %s:%s;" % (ip, args.target_port) for ip in ips)) | |
new_conf = nginx_conf % args.__dict__ | |
conf_fn = os.path.join(nginx_conf_dir, args.name) | |
try: | |
old_conf = open(conf_fn).read() | |
except IOError: | |
old_conf = "" | |
if old_conf != new_conf: | |
with open(conf_fn, "wt") as f: | |
f.write(new_conf) | |
subprocess.check_call("service nginx reload", shell=True) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment