一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

利用python自动生成docker nginx反向代理配置的教程

时间:2017-01-07 编辑:简简单单 来源:一聚教程网

由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建、停止的时候,自动生成nginx反向代理,然后reload nginx

我的原则是尽量简单,轻量,内存占用少

目标很明确,只要能监听到docker的容器启动/停止事件,即可

网上查了一下可以用docker events来监听docker事件,试了一下,发现基本可以满足,于是用python写了一段程序,用来监听docker事件

 

 代码如下 复制代码

python

#!/usr/bin/python
# coding: utf8
importos
importjson
importre
importsubprocess
 
 
defoverride(path, text):
  ifnotos.path.exists(path)andos.path.exists(path+"_temp"):
    os.rename(path+"_temp",path)
  fw=open(path+"_temp",'wb')
  fw.write(text)
  fw.close()
  ifos.path.exists(path):
    os.remove(path)
  os.rename(path+"_temp", path)
 
 
defread(path):
  try:
    fr=open(path,"rb")
  exceptIOError:
    print"The file don't exist, Please double check!"
    return
  lines=fr.readlines()
  ret=''
  forlineinlines:
    ret+=line
  returnret
 
 
defread_jsonfile(path):
  returnjson.loads(read(path))
 
 
defcmd(command):
  returnos.popen(command).read()
 
 
defget_name(container):
  returncmd("docker inspect -f '{{.Name}}' "+container).replace("/", "").replace('\n', '')
 
 
defget_ip(container):
  returncmd("docker inspect -f '{{.NetworkSettings.IPAddress}}' "+container).replace('\n', '')
 
 
defget_port(container):
  returncmd("docker inspect -f '{{.Config.ExposedPorts}}' "+container).replace('/tcp:{}]', '').replace('map[', '').replace('\n', '')
 
 
defget_info(container):
  filename="/var/lib/docker/containers/"+container+"/config.v2.json"
  config=read_jsonfile(filename)
 
  name=config['Name'].replace("/", "")
  port=config['Config']['ExposedPorts'].keys()[0].replace('/tcp', '')
  ip=cmd("docker inspect -f '{{.NetworkSettings.IPAddress}}' "+name)
  # ip = config['NetworkSettings']['Networks']['bridge']['IPAddress']
 
  ret={'name': name,'port': port,'ip': ip}
  returnret
 
 
tpl="""
  server {
    listen 80;
    server_name $name.test.com;
    location / {
    proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://$ip:$port;
    }
  }
"""
 
 
defgenerate_conf():
  print"generate_conf"
  out=cmd("docker ps | grep -v CONTAINER | awk '{print $1}'")
  containers=out.split("\n")
  servers=''
  hosts=''
  forconincontainers:
    ifcon !='':
      name=get_name(con)
      ip=get_ip(con)
      port=get_port(con)
      printip, port
      iflen(port) >=2:
        servers+=tpl.replace("$name", name).replace("$ip", ip).replace("$port", port)
        hosts+="11.12.13.14 "+name+".test.com\n"
  override('/usr/local/openresty/nginx/conf/vhost.conf', servers)
  override('/usr/local/openresty/nginx/html/vhost.html',"
"+hosts+"
")
 
 
defreload_nginx():
  print"reload nginx"
  cmd('nginx -s reload')
 
 
defauto_reload():
  generate_conf()
  reload_nginx()
 
print" ==================== docker events ==================== "
 
# auto_reload()
 
proc=subprocess.Popen(["docker","events"],
            # shell=True,  # windows: true, linux: false
            stdout=subprocess.PIPE)
 
while1:
  out=proc.stdout.readline()
  event=re.sub('\(|\)', "", out).split("")
  ifout.find('container stop') !=-1:
    auto_reload()
    print' container stop '
  elifout.find('container start') !=-1:
    auto_reload()
    print' start container '
  ifout=='':
    print"out "
    break
 

启动命令:

nohup ./docker.py >/dev/null2>&1&

程序会在后台运行,断开ssh也不会结束

主要就是生成一个 conf 文件,这个文件要在nginx.conf里面引入,然后每次有容器启动/停止都生成这个文件,然后重启nginx,我这了还把容器名加上一个域名,组合成了一个子域名,然后把对应的映射关系生成了一个html文件,通过浏览器可以访问这个文件,然后把对应的代码 复制到本机的 hosts 文件里面,可以实现通过域名访问应用,当然只是开发测试的时候会这么做,但是也足够了。

热门栏目