Docker+Consul+Registrator+Nginx实现容器服务自动发现的集群框架

1. 使用到的框架或者组件

  • Consul:分布式的、高可用的、 可横向扩展的,用于实现分布式系统的服务发现与配置。
  • Registrator:可以用来做服务发现。
  • Consul Template:搭配Consul使用,支持多种接入层,如Nginx、Haproxy。可以动态添加和移除服务,不需要重写任何服务。
  • Docker:利用容器化,简化部署,节省资源。
  • Supervisor: 是基于Python 的进程管理工具,可以帮助我们更简单的启动、重启和停止服务器上的后台进程,是Linux 服务器管理的效率工具。

2. 架构设计

de11c5f722122d7f4f64b27c0d56a7a3.png

3. 环境说明

我们需要部署nginx、consul、consul-template、registrator、webservice1(nginx)/webservice2(nginx)等服务。

需要注意的是:consul-template必须和nginx部署在一台机器上(因为consul-template动态更新nginx的配置后,需要通过自动触发的方式,来reload nginx的配置信息,否则是没法自动生效。这个reload就需要保证consul-template和nginx处于同一机器才行)

我们测试机器有限,而且有Docker这么方便的容器化工具,所以我们打算把所有服务都通过docker容器来运行。这样的话,我们只要一台安装了docker的机器就行,这里使用一台安装了docker的centos机器

但是我们刚才讲到了consul-template和nginx必须要在一台机器上,这个时候我们不得不要违背一个Docker容器运行一个服务的建议了。我们考虑使用Supervisor来让一个Docker容器同时运行consul-template和nginx服务。

服务器IP 容器名 容器IP 角色
192.168.1.92 consultemplate 172.10.0.2 通过Supervisor运行consul-template,nginx服务
192.168.1.92 consulserver 172.10.0.3 运行consul服务
192.168.1.92 registrator -- 运行registrator服务
192.168.1.92 nginx_81 -- 运行webservice1(nginx,使用端口81)服务
192.168.1.92 nginx_82 -- 运行webservice2(nginx,使用端口82)服务

4. 制作服务镜像

4.1 制作Nginx和Consul-template镜像

4.1.1 创建目录nginx-consultemplate

    mkdir -p nginx-consultemplate
    cd nginx-consultemplate

4.1.2 创建nginx.ctmpl模板文件

upstream http_backend {
        {{range service "nginx"}}
        server {{ .Address }}:{{ .Port }};
        {{ end }}
}

server {
        listen 8000;
        server_name localhost;
        location / {
                proxy_pass http://http_backend;
        }
}

第一段是定义了nginx upsteam的一个简单模板,第二段则是定义了一个server,监听8000端口,反向代理到upstream。

4.1.3 创建nginx.conf文件

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    #添加这一行
    include /etc/nginx/consul/*.conf;
}

我们后面运行consul-template的时候,会使用nginx.ctmpl模板,解析之后生成.conf文件到/etc/nginx/consul目录下,所以nginx.conf文件的最后一条内容是include /etc/nginx/consul/*.conf;

4.1.4 创建supervisord.conf配置文件

[supervisord]
nodaemon=true

[program:consul-template]
command=consul-template -consul-addr 172.12.0.3:8500 -template "/etc/nginx/consul/nginx.ctmpl:/etc/nginx/consul/vhost.conf:nginx -s reload" -log-level=info

[program:nginx]
command=nginx

运行consul-template的时候,通过-consul-addr参数来指定consul服务的IP和端口号,-template参数来指定模板的解析,规则是:冒号第一段是模板文件路径,第二段是生成的配置文件路径,第三段是额外指令(这里特别重要:如果我们没有nginx -s reload这个,配置更新之后,无法自动生效。这个代表每次配置改变之后,都会自动执行此指令,用来reload nginx的配置,以便自动生效

4.1.5 创建Dockerfile文件

# 基于nginx基础镜像创建
FROM nginx:1.12.1
# 设置作者信息
MAINTAINER zwffff "zwffff@gmail.com"

# 设置环境变量,用于更新时,更改此信息来忽略缓存
ENV REFRESHED_AT 2019-05-26

# 安装net-tools(用于调试的时候,打印网络信息),supervisor(进程管理工具),wget,unzip
RUN apt-get update -yqq && apt-get install -yqq net-tools supervisor wget unzip

# 下载安装consul-template
RUN wget https://releases.hashicorp.com/consul-template/0.19.3/consul-template_0.19.3_linux_amd64.zip
RUN unzip consul-template_0.19.3_linux_amd64.zip
RUN mv consul-template /usr/bin/

RUN mkdir -p /etc/nginx/consul/
# 将模板文件nginx.ctmpl拷贝到/etc/nginx/consul目录下
ADD nginx.ctmpl /etc/nginx/consul/
# 将nginx.conf配置文件拷贝到/etc/nginx配置下进行覆盖
ADD nginx.conf /etc/nginx/

# 将supervisord.conf配置文件拷贝到/etc/supervisor/目录
ADD supervisord.conf /etc/supervisor/supervisord.conf

# 运行supervisord时,指定上一条语句的配置文件
ENTRYPOINT [ "/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf" ]

4.1.6 编辑好Dockerfile文件之后,我们可以通过以下命令来生成nginx-consultemplate镜像文件

docker build -t zwffff/nginx-consultemplate .

4.2 制作Consul镜像

4.2.1 创建目录consul

mkdir -p consul
cd consul

4.2.2 创建Dockerfile文件

FROM centos:7.4.1708
MAINTAINER zwffff "zwffff@gmail.com"

#配置consul版本
ENV CONSUL_VERSION=1.0.6
ENV HASHICORP_RELEASES=https://releases.hashicorp.com

#创建用户
RUN groupadd consul && useradd -g consul consul

RUN yum upgrade -y
RUN yum install -y net-tools
#RUN yum install -y firewall firewalld-config
RUN yum install -y wget unzip
RUN  wget ${HASHICORP_RELEASES}/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip && \
        unzip consul_${CONSUL_VERSION}_linux_amd64.zip && \
        rm -rf consul_${CONSUL_VERSION}_linux_amd64.zip && \
        mv consul /usr/local/bin

#创建consul数据目录和配置目录
RUN mkdir -p /consul/data && \
        mkdir -p /consul/config && \
        chown -R consul:consul /consul

#设置匿名卷
VOLUME /consul/data

#开放端口
EXPOSE 8300
EXPOSE 8301 8301/udp 8302 8302/udp
EXPOSE 8500 8600 8600/udp
EXPOSE 80

4.2.3 生成镜像

docker build -t zwffff/consul .

我们只需要用到以上两个自定义镜像,至此镜像就都制作完成了。下面我们考虑把所有镜像通过docker-compose
进行编排到一起执行。

5. 利用Docker-Compose进行容器编排

docker-compose怎么使用,这里不做具体的介绍,它主要使用YAML文件进行配置。有version、services和networks三部分组成。特别留意的是:version版本为2和3的时候,有一些配置是有区分的,不一样的。 services就是我们需要定义的容器集合,networks则是我们需要定义的网络集合。

我们需要启动以下容器:

  • web:使用zwffff/nginx-consultemplate镜像启动,会运行consul-template和nginx服务,依赖consul服务

  • consul:使用zwffff/consul镜像启动,运行consul服务

  • registrator:使用docker hub上的gliderlabs/registrator镜像启动,运行registrator服务,依赖web服务

  • nginx1:使用nginx镜像启动,用来作为webservice1调用测试,依赖registrator服务

  • nginx2:使用nginx镜像启动,用来作为webservice2调用测试,作为webservice1服务的同级服务,用来进行负载均衡测试,依赖registrator服务

  • 创建自定义网络
    docker network create --subnet=172.12.0.0/16 consul_testconsul

  • 创建 docker-compose.yml文件

version: "2"
services:
 web:
  image: zwffff/nginx-consultemplate  # 指定容器所使用的镜像
  container_name: consultemplate  # 指定容器名称
  networks:                        #指定容器所使用的网络
   consul_testconsul:        # 自定义网络的名称,这个与第一步创建的网络名称一致,同时下面的networks必须进行定义
    ipv4_address: 172.12.0.2   #指定当前容器所使用的IP地址
  depends_on:    #指定该容器依赖的容器
   - consul
  ports:    #指定容器绑定的端口号
   - "8000:8000"

 consul:
  image: zwffff/consul
  # -bind指定了当前consul服务所绑定的IP地址
  command: consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=172.12.0.3 -client=0.0.0.0 -node=server01  
  networks:
   consul_testconsul:
     ipv4_address: 172.12.0.3
  container_name: consulserver
  ports:
    - "8300"
    - "8301"
    - "8301/udp"
    - "8302"
    - "8302/udp"
    - "8500"
    - "8602"
    - "8600/udp"
    - "80"

 registrator:
  image: gliderlabs/registrator:latest
  container_name: registrator
  network_mode: host      # 这里要把宿主机注册到consul上去,所以网络模式必须要使用host模式
  command: --ip 192.168.1.92 consul://172.12.0.3:8500
  depends_on:
    - web
  volumes:
      -  /var/run/docker.sock:/tmp/docker.sock
  restart: always

 nginx1:
   image: nginx
   container_name: nginx_81
   depends_on:
     - registrator
   ports:
     - "81:80"

 nginx2:
   image: nginx
   container_name: nginx_82
   depends_on:
     - registrator
   ports:
     - "82:80"

networks:
 consul_testconsul:
  external: true     #使用外部已创建的网络时,external属性必须设置为true

这样,我们五个容器都已经通过docker-compose编排好了。
通过执行docker-compose up指令即可一键运行整个集群服务了。

参考文章:
基于Consul+Registrator+Nginx实现容器服务自动发现的集群框架: https://blog.51cto.com/ganbing/2086851
consul官网:https://www.consul.io
consul github:https://github.com/hashicorp/consul
consul-template:https://github.com/hashicorp/consul-template
registrator:https://github.com/gliderlabs/registrator

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

推荐阅读更多精彩内容