nginxでダイナミックにリバースプロキシするやつ
SD12月号のdocker特集にあったやつ。
ngixnxをリバースプロキシとして目的のdockerのコンテナにプロキシする。
dockerのコンテナの管理とかはfig使った。
meu@u01:~/docker/dproxy$ find . -type f ./linkd/Dockerfile ./linkd/linkd ./fig.yml ./redis/Dockerfile ./redis/redis.conf ./nginx/Dockerfile ./nginx/nginx.conf
meu@u01:~/docker/dproxy$ cat fig.yml nginx: build: nginx command: /usr/sbin/nginx ports: - "80:80" links: - redis redis: build: redis command: /usr/bin/redis-server /etc/redis/redis.conf expose: - "6379" linkd: build: linkd command: /usr/bin/linkd links: - redis environment: DOCKER_HOST: 192.168.56.102:2375
meu@u01:~/docker/dproxy$ cat nginx/Dockerfile FROM ubuntu:trusty RUN apt-get update -y && apt-get dist-upgrade -fy RUN apt-get install -fy lua-nginx-redis nginx-extras ADD nginx.conf /etc/nginx/nginx.conf
meu@u01:~/docker/dproxy$ cat nginx/nginx.conf user www-data; daemon off; env REDIS_PORT_6379_TCP_ADDR; env REDIS_PORT_6379_TCP_PORT; events { worker_connections 768; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; server { listen 80 default_server; root /usr/share/nginx/html; index index.html index.htm; location / { set $forward ""; rewrite_by_lua ' local redis = require "nginx.redis" local client = redis:new() local redishost = os.getenv("REDIS_PORT_6379_TCP_ADDR") local redisport = os.getenv("REDIS_PORT_6379_TCP_PORT") local ok, _ = client:connect(redishost, redisport) if not ok then ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE) end local sub, _ = string.gsub(ngx.var.host, "([^%.]+)%..*", "%1") local res, err = client:get(sub) if err then ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE) end if res == ngx.null then ngx.exit(ngx.HTTP_NOT_FOUND) end ngx.var.forward = res '; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://$forward; } } }
meu@u01:~/docker/dproxy$ cat redis/Dockerfile FROM ubuntu:trusty RUN apt-get update -y && apt-get dist-upgrade -fy RUN apt-get install -fy redis-server ADD redis.conf /etc/redis/redis.conf
meu@u01:~/docker/dproxy$ cat linkd/Dockerfile FROM ubuntu:trusty RUN apt-get update -y && apt-get dist-upgrade -fy RUN apt-get install -fy python3 python3-pip RUN pip3 install docker-py redis ADD linkd /usr/bin/linkd RUN chmod +x /usr/bin/linkd
#!/usr/bin/python3 import datetime import docker import json import os import redis import sys import urllib.request DOCKER_HOST = os.getenv('DOCKER_HOST') DOCKER_API_BASE_URL = 'tcp://' + DOCKER_HOST DOCKER_EVENT_API_URL = 'http://' + DOCKER_HOST + '/events' REDIS_ADDR = os.getenv('REDIS_PORT_6379_TCP_ADDR') REDIS_PORT = os.getenv('REDIS_PORT_6379_TCP_PORT') CLIENT = docker.Client(base_url=DOCKER_API_BASE_URL) EVENT = urllib.request.urlopen(DOCKER_EVENT_API_URL) REDIS = redis.Redis(host=REDIS_ADDR, port=REDIS_PORT) def getforwardinfo(container): inspect = CLIENT.inspect_container(container.get('Id')) env = inspect.get('Config').get('Env') name = next(filter(lambda x: 'DPROXY_FORWARD_NAME' in x, env), None) if name is None: return None name = name.split('=').pop() ipaddr = inspect.get('NetworkSettings').get('IPAddress') port = str(container.get('Ports').pop().get('PrivatePort')) forward = ipaddr + ':' + port return (name, forward) def updateredis(): info = [] for c in CLIENT.containers(): tmp = getforwardinfo(c) if tmp is None: continue info.append(tmp) REDIS.flushall() for name, forward in info: REDIS.set(name, forward) def dumpredis(): print(datetime.datetime.now().ctime()) for k in REDIS.scan_iter(): s = "%10s:\t%s" % (k.decode('utf-8'), REDIS.get(k).decode('utf-8')) print(s) def readevent(): x = [] while True: c = EVENT.read(1) x.append(c) if c == b'}': break return b''.join(x).decode('utf-8') def main(): updateredis() dumpredis() while True: ev = readevent() status = json.loads(ev).get('status') if status in ('start', 'stop'): updateredis() dumpredis() if __name__ == '__main__': main() exit(0)