基于Docker + Consul + Nginx + Consul-Template + Registrator的服務(wù)自動負載均衡實現(xiàn)

基于Docker + Consul + Nginx + Consul-Template + Registrator的服務(wù)自動負載均衡實現(xiàn)

本文搭建的consul為單節(jié)點版本 , 集群版 參考文章1

參考文章:

  1. 基于Docker + Consul + Nginx + Consul-Template的服務(wù)負載均衡實現(xiàn)
  2. 用 consul + consul-template + registrator + nginx 打造真正可動態(tài)擴展的服務(wù)架構(gòu)
  3. 8分鐘學會Consul集群搭建及微服務(wù)概念

docker-composer相關(guān)知識點

  • ports 暴露容器端口到主機的任意端口或指定端口, 用法如下
ports:
 
    - "80:80" # 綁定容器的80端口到主機的80端口
     
    - "9000:8080" # 綁定容器的8080端口到主機的9000端口
     
    - "443" # 綁定容器的443端口到主機的任意端口,容器啟動時隨機分配綁定的主機端口

  • links 使得docker容器間通過指定的名字來和目標容器通信

如果使用links則容器間通信 只能通過該使用容器的ip地址來通信或者通過宿主機的ip加上容器暴露出的端口號來通信 (這兩種都有弊端)

links:
    -  consul_server_master:consul # 當前容器中使用consul 即可獲取容器consul_server_master的ip地址,便于通信
  • depends_on 決定容器的依賴, 也就是指定當前容器的啟動順序,必須依賴啟動后才會啟動
depends_on:
    - lb
    - registrator

consul 相關(guān)知識點

  • Client模式 就是客戶端模式。是 Consul 節(jié)點的一種模式,這種模式下,所有注冊到當前節(jié)點的服務(wù)會被轉(zhuǎn)發(fā)到 Server,本身是不持久化這些信息。
  • Server模式 表明這個 Consul 是個 Server ,這種模式下,功能和 Client 都一樣,唯一不同的是,它會把所有的信息持久化的本地,這樣遇到故障,信息是可以被保留的。同時可以同步多個consul客戶端的數(shù)據(jù)

    Server 節(jié)點之間的數(shù)據(jù)一致性保證協(xié)議使用的是 raft,而 zookeeper 用的 paxos,etcd采用的也是raft

 command: consul agent -server -bootstrap-expect 1 -advertise 192.168.1.181 -node consul_server_master -data-dir /tmp/data-dir -client 0.0.0.0 -ui
 # -bootstrap-expect=2 表示節(jié)點個數(shù)為2個
 # -node=consul-server-1 表示節(jié)點名稱為consul-server-1
 # -client=0.0.0.0 表示允許連接的客戶端 IP
 # -bind=10.211.55.2 表示服務(wù)端 IP為10.211.55.2
 # -datacenter=dc1 數(shù)據(jù)中心名稱
 # -join=10.211.55.4 表示加入10.211.55.4節(jié)點的集群
 
  • 服務(wù)發(fā)現(xiàn)協(xié)議 Consul 采用 http 和 DNS 協(xié)議,etcd 只支持 http
    服務(wù)注冊:Consul 支持兩種方式實現(xiàn)服務(wù)注冊,一種是通過 Consul 的服務(wù)注冊 Http API,由服務(wù)自己調(diào)用 API 實現(xiàn)注冊,另一種方式是通過 json 格式的配置文件實現(xiàn)注冊,將需要注冊的服務(wù)以 json 格式的配置文件給出。Consul 官方建議使用第二種方式。
  • 服務(wù)定義參數(shù)
環(huán)境變量Key 環(huán)境變量Value 說明
SERVICE_ID web-001 可以為GUID或者可讀性更強變量,保證不重復
SERVICE_NAME web 如果ID沒有設(shè)置,Consul會將name作為id,則有可能注冊失敗
SERVICE_TAGS nodejs,web 服務(wù)的標簽,用逗號分隔,開發(fā)者可以根據(jù)標簽來查詢一些信息
SERVICE_IGNORE Boolean 是否忽略本Container,可以為一些不需要注冊的Container添加此屬性

實現(xiàn)原理

  • 通過 Nginx 自身實現(xiàn)負載均衡和請求轉(zhuǎn)發(fā)
  • 通過 Consul-template 的 config 功能實時監(jiān)控 Consul 集群節(jié)點的服務(wù)和數(shù)據(jù)的變化;
    實時的用 Consul 節(jié)點的信息替換 Nginx 配置文件的模板,并重新加載配置文件

Consul-template 和 nginx 必須安裝在同一臺機器上,因為 Consul-template 需要動態(tài)修改 nginx 的配置文件 nginx.conf,然后執(zhí)行 nginx -s reload 命令進行路由更新,達到動態(tài)負載均衡的目的

  • registrator,它可以通過跟本地的 docker 引擎通信,來獲取本地啟動的容器信息,并且注冊到指定的服務(wù)發(fā)現(xiàn)管理端。

數(shù)據(jù)流向: docker 容器數(shù)據(jù)-> registrator -> consul ->consul-template -> nginx

鏡像構(gòu)建

  • Consul:consul:latest
  • Registrator:gliderlabs/registrator:latest
  • Nginx和Consul-template:liberalman/nginx-consul-template:latest
  • Web: yeasy/simple-web:latest

docker-compose.yml

version: '3'
#backend web application, scale this with docker-compose scale web=3
services:
    web:
      image: yeasy/simple-web:latest
      environment:
        - SERVICE_80_NAME=my-web-server
      ports:
      - "80"
      depends_on:
          - lb
          - registrator  

    #load balancer will automatically update the config using consul-template
    lb:
      image: liberalman/nginx-consul-template:latest
      hostname: lb
      environment:
          - SERVICE_IGNORE=true
      links:
      -  consul_server_master:consul
      ports:
      - "80:80"
      depends_on:
          - consul_server_master
          
    consul_server_master:
      image:  consul:latest
      hostname: consul_server_master
      environment:
          - SERVICE_IGNORE=true
      ports:
      - "8500:8500"
      command: consul agent -server -bootstrap-expect 1 -node consul_server_master -data-dir /tmp/consul -client 0.0.0.0 -ui

    # listen on local docker sock to register the container with public ports to the consul service
    registrator:
      image: gliderlabs/registrator:master
      hostname: registrator
      environment:
          - SERVICE_IGNORE=true
      links:
      - consul_server_master:consul
      depends_on:
          - consul_server_master
      volumes:
      - "/var/run/docker.sock:/tmp/docker.sock"
      command: -internal consul://consul:8500

測試步驟

  1. docker-compose 模板所在目錄,執(zhí)行
$ sudo docker-compose up
  1. 訪問 http://localhost 可以看到一個 web 頁面,提示實際訪問的目標地址。
#2019-12-20 04:12:30: 19 requests from <LOCAL: 172.17.0.6> to WebServer <172.17.0.4>
  1. 增加web 測試負載
$ sudo docker-compose scale web=3
  1. 重復刷新http://localhost 觀察ip變化

總結(jié)測試

最先我未去指定容器的啟動順序(deponds_on) 導致docker-compose up 后訪問http://localhost 報錯 nginx 502
原因是因為 registrator容器先于web容器啟動,導致未將web容器注冊到consul 所以生成的nginx配置文件中,沒用web參與負載

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容