使用python自動生成docker nginx反向代理配置

来源:http://www.cnblogs.com/ccmc/archive/2017/01/02/6243486.html
-Advertisement-
Play Games

由於在測試環境上用docker部署了多個應用,而且他們的埠有的相同,有的又不相同,數量也比較多,在使用jenkins發版本的時候,不好配置,於是想要寫一個腳本,能在docker 容器創建、停止的時候,自動生成nginx反向代理,然後reload nginx 我的原則是儘量簡單,輕量,記憶體占用少 目 ...


由於在測試環境上用docker部署了多個應用,而且他們的埠有的相同,有的又不相同,數量也比較多,在使用jenkins發版本的時候,不好配置,於是想要寫一個腳本,能在docker 容器創建、停止的時候,自動生成nginx反向代理,然後reload nginx

我的原則是儘量簡單,輕量,記憶體占用少

目標很明確,只要能監聽到docker的容器啟動/停止事件,即可

網上查了一下可以用docker events來監聽docker事件,試了一下,發現基本可以滿足,於是用python寫了一段程式,用來監聽docker事件

python

#!/usr/bin/python
# coding: utf8
import os
import json
import re
import subprocess


def override(path, text):
    if not os.path.exists(path) and os.path.exists(path+"_temp"):
        os.rename(path+"_temp",path)
    fw = open(path+"_temp", 'wb')
    fw.write(text)
    fw.close()
    if os.path.exists(path):
        os.remove(path)
    os.rename(path+"_temp", path)


def read(path):
    try:
        fr = open(path, "rb")
    except IOError:
        print "The file don't exist, Please double check!"
        return
    lines = fr.readlines()
    ret = ''
    for line in lines:
        ret += line
    return ret


def read_jsonfile(path):
    return json.loads(read(path))


def cmd(command):
    return os.popen(command).read()


def get_name(container):
    return cmd("docker inspect -f '{{.Name}}' " + container).replace("/", "").replace('\n', '')


def get_ip(container):
    return cmd("docker inspect -f '{{.NetworkSettings.IPAddress}}' " + container).replace('\n', '')


def get_port(container):
    return cmd("docker inspect -f '{{.Config.ExposedPorts}}' " + container).replace('/tcp:{}]', '').replace('map[', '').replace('\n', '')


def get_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}
    return ret


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;
        }
    }
"""


def generate_conf():
    print "generate_conf"
    out = cmd("docker ps | grep -v CONTAINER | awk '{print $1}'")
    containers = out.split("\n")
    servers = ''
    hosts = ''
    for con in containers:
        if con != '':
            name = get_name(con)
            ip = get_ip(con)
            port = get_port(con)
            print ip, port
            if len(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', "<pre>" + hosts + "</pre>")


def reload_nginx():
    print "reload nginx"
    cmd('nginx -s reload')


def auto_reload():
    generate_conf()
    reload_nginx()

print " ==================== docker events ==================== "

# auto_reload()

proc = subprocess.Popen(["docker", "events"],
                        # shell=True,   # windows: true, linux: false
                        stdout=subprocess.PIPE)

while 1:
    out = proc.stdout.readline()
    event = re.sub('\(|\)', "", out).split(" ")
    if out.find('container stop') != -1:
        auto_reload()
        print ' container stop '
    elif out.find('container start') != -1:
        auto_reload()
        print ' start container '
    if out == '':
        print "out "
        break

啟動命令:

nohup ./docker.py > /dev/null 2>&1 &

程式會在後臺運行,斷開ssh也不會結束

主要就是生成一個 conf 文件,這個文件要在nginx.conf裡面引入,然後每次有容器啟動/停止都生成這個文件,然後重啟nginx,我這了還把容器名加上一個功能變數名稱,組合成了一個子功能變數名稱,然後把對應的映射關係生成了一個html文件,通過瀏覽器可以訪問這個文件,然後把對應的代碼 複製到本機的 hosts 文件裡面,可以實現通過功能變數名稱訪問應用,當然只是開發測試的時候會這麼做,但是也足夠了。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • jdbc連接資料庫的四個對象 DriverManager 驅動類 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建議使用 原因有2個: > 導致驅動被註冊2次。 > 強烈依賴資料庫的驅動jar 解決辦法: Class.forNa ...
  • 似乎隔三差五就能看到一些關於架構師應不應該寫代碼的文章。我是屬於寫代碼派,因為我本身就喜歡寫代碼。但是,當工作職責發生變化之後,如何保持寫代碼和其它工作之間的平衡就成了問題。 從個體效率上來看,我自己親自寫代碼,和很多人相比沒有什麼絕對優勢,甚至有些人碼代碼的速度比我還快一些。 但作為架構師,參與寫 ...
  • 一、變數的概念: (1)記憶體中的一個存儲區域 (2)該區域有自己的名稱(變數名)和類型(數據類型) (3)Java中每個變數必須先聲明,後使用 (4)該區域的數據可以在同一類型範圍內不斷變化 使用變數註意: (1)變數的作用域:一對{ }之間有效 (2)初始化值 定義變數的格式:數據類型 變數名 = ...
  • 一、Java 集合框架 集合框架是一個用來代表和操縱集合的統一架構。所有的集合框架都包含如下內容: 介面:是代表集合的抽象數據類型。介面允許集合獨立操縱其代表的細節。在面向對象的語言,介面通常形成一個層次。 實現(類):是集合介面的具體實現。從本質上講,它們是可重覆使用的數據結構。 演算法:是實現集合 ...
  • 20161230問題解析請點擊今日問題下方的“【Java每日一題】20170103”查看(問題解析在公眾號首發,公眾號ID:weknow619) 今日問題: 請問主程式輸出結果是什麼?(點擊以下“【Java每日一題】20170103”查看20161230問題解析) 題目原發佈於公眾號、簡書:【Jav ...
  • 本節介紹記憶體映射文件,利用它,我們實現一個簡單的、持久化的、可跨程式協作的消息隊列,怎麼實現呢? ...
  • 考慮以下場景: #include #include using namespace std; struct Person { string name; int age; }; class Manager{ private: Person person; public: ... ...
  • 未完 for examples: example 1: 運行結果如下: example 2: 運行結果如下: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...