基于Docker + Consul + Nginx + Consul-Template + Registrator的服务自动负载均衡实现

基于Docker + Consul + Nginx + Consul-Template + Registrator的服务自动负载均衡实现

本文搭建的consul为单节点版本 , 集群版 参考文章1

参考文章:

  1. 基于Docker + Consul + Nginx + Consul-Template的服务负载均衡实现
  2. 用 consul + consul-template + registrator + nginx 打造真正可动态扩展的服务架构
  3. 8分钟学会Consul集群搭建及微服务概念

docker-composer相关知识点

  • 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 相关知识点

  • Client模式 就是客户端模式。是 Consul 节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到 Server,本身是不持久化这些信息。
  • Server模式 表明这个 Consul 是个 Server ,这种模式下,功能和 Client 都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。同时可以同步多个consul客户端的数据

    Server 节点之间的数据一致性保证协议使用的是 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 表示节点个数为2个
 # -node=consul-server-1 表示节点名称为consul-server-1
 # -client=0.0.0.0 表示允许连接的客户端 IP
 # -bind=10.211.55.2 表示服务端 IP为10.211.55.2
 # -datacenter=dc1 数据中心名称
 # -join=10.211.55.4 表示加入10.211.55.4节点的集群
 
  • 服务发现协议 Consul 采用 http 和 DNS 协议,etcd 只支持 http
    服务注册:Consul 支持两种方式实现服务注册,一种是通过 Consul 的服务注册 Http API,由服务自己调用 API 实现注册,另一种方式是通过 json 格式的配置文件实现注册,将需要注册的服务以 json 格式的配置文件给出。Consul 官方建议使用第二种方式。
  • 服务定义参数
环境变量Key 环境变量Value 说明
SERVICE_ID web-001 可以为GUID或者可读性更强变量,保证不重复
SERVICE_NAME web 如果ID没有设置,Consul会将name作为id,则有可能注册失败
SERVICE_TAGS nodejs,web 服务的标签,用逗号分隔,开发者可以根据标签来查询一些信息
SERVICE_IGNORE Boolean 是否忽略本Container,可以为一些不需要注册的Container添加此属性

实现原理

  • 通过 Nginx 自身实现负载均衡和请求转发
  • 通过 Consul-template 的 config 功能实时监控 Consul 集群节点的服务和数据的变化;
    实时的用 Consul 节点的信息替换 Nginx 配置文件的模板,并重新加载配置文件

Consul-template 和 nginx 必须安装在同一台机器上,因为 Consul-template 需要动态修改 nginx 的配置文件 nginx.conf,然后执行 nginx -s reload 命令进行路由更新,达到动态负载均衡的目的

  • registrator,它可以通过跟本地的 docker 引擎通信,来获取本地启动的容器信息,并且注册到指定的服务发现管理端。

数据流向: docker 容器数据-> registrator -> consul ->consul-template -> nginx

镜像构建

  • 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 模板所在目录,执行
$ 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变化

总结测试

最先我未去指定容器的启动顺序(deponds_on) 导致docker-compose up 后访问http://localhost 报错 nginx 502
原因是因为 registrator容器先于web容器启动,导致未将web容器注册到consul 所以生成的nginx配置文件中,没用web参与负载

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容