1、 目的mysql
在服务在容器中部署时,外部调用服务须要知道服务接口ip及端口号,这样致使部署时须要配置,从而增长部署的困难。本文档主要介绍如何使用ningx反向代理和consul进行自动化服务发现与部署,从而使外部访问服务只须要访问nginx代理便可解决,同时也能够解决分布式服务及大访问量负载问题。nginx
场景说明:若有一个数据服务data-service,若是在docker集群中部署的话,ip和port均可能变化,这时线上服务必须更改配置,才能访问到data-service服务。而采用本方案的话,只须要配置好ningx负载均衡的ip与地址,数据服务可随时从新部署调整,不须要从新配置。web
2、 概述sql
Nginx是经常使用的轻量级反向代理插件,使用Ningx可让服务统一入口,经过Ningx配置服务路径请求转发路径,将对应的请求路由到对应的服务中处理。使用Ningx可使后端服务部署更加灵活。docker
Consul包含多个组件,可是做为一个总体,为你的基础设施提供服务发现和服务配置的工具.他提供如下关键特性:bootstrap
服务发现 Consul的客户端可用提供一个服务,好比 api 或者mysql ,另一些客户端可用使用Consul去发现一个指定服务的提供者.经过DNS或者HTTP应用程序可用很容易的找到他所依赖的服务. 后端
健康检查 Consul客户端可用提供任意数量的健康检查,指定一个服务(好比:webserver是否返回了200 OK 状态码)或者使用本地节点(好比:内存使用是否大于90%). 这个信息可由operator用来监视集群的健康.被服务发现组件用来避免将流量发送到不健康的主机. api
Key/Value存储 应用程序可用根据本身的须要使用Consul的层级的Key/Value存储.好比动态配置,功能标记,协调,领袖选举等等,简单的HTTP API让他更易于使用. bash
多数据中心 Consul支持开箱即用的多数据中心.这意味着用户不须要担忧须要创建额外的抽象层让业务扩展到多个区域. 服务器
Consul面向DevOps和应用开发者友好.是他适合现代的弹性的基础设施.
3、 部署方案
i. 部署图
图1 部署图
ii. 部署过程
docker run -d --name=consul_server -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h docker_server progrium/consul -server -bootstrap
docker run -d --name=consul_registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest -ip="192.168.1.60" consul://192.168.1.60:8500
-ip:使用主机ip,由于nginx转发可能涉及到跨主机的服务请求转发,因此须要绑定主机ip;
consul://192.168.1.60:8500:为consul server的ip和端口。
docker -d run liberalman/nginx-consul-template:latest
Nginx配置存储路径为:/etc/nginx/conf.d,使用的是分文件,该文件是由consul template自动更新的,不须要进行配置。
配置文件存储的路径为:/etc/consul-templates/nginx.conf.ctmpl,该文件为consul template在监控consul server服务有改动时,进行配置修改,并存储到/etc/nginx/conf.d/app.conf当中。
示例配置:
upstream solr { least_conn; {{range service "solr"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } upstream data_service { least_conn; {{range service "data_service"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } server { listen 80 default_server; location /solr { proxy_pass http://solr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /data { proxy_pass http://data_service; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
配置一个服务须要俩个地方进行配置修改。
upstream solr { least_conn; {{range service "solr"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} }
1) upstream配置
2) server配置
location /solr:配置路由进行转发
proxy_pass http://data_service:配置对应的路由转发到哪一个upstream上。
location /solr { proxy_pass http://solr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
该段代码表示将请求路径/solr的请求转发到服务名为solr的地址上。
以app.conf为例:
upstream solr { least_conn; server 192.168.1.60:8080 max_fails=3 fail_timeout=60 weight=1; } upstream data_service { least_conn; server 192.168.1.60:5000 max_fails=3 fail_timeout=60 weight=1; } server { listen 80 default_server; location /solr { proxy_pass http://solr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /data { proxy_pass http://data_service; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
假设nginx部署在192.168.1.112服务器上,那么访问 http://192.168.1.112/solr,该请求会被转发到http://192.168.1.60:8080/solr
4. 启动服务
1) 若是须要忽略不注册到consul上,则在建立容器时添加环境变量SERVICE_IGNORE=true
2) 若是须要注册到consul上,则须要设置服务名,使用SERVICE_NAME=[服务名]进行设置,也可将容器对应的不一样端口设置为不一样的服务名,例如须要将容器暴露的端口8088设置为bussiness服务名,则使用SERVICE_8088_NAME=[服务名],即在中间加上端口号便可
3) 若是须要对服务加上标签,可以使用环境变量SERVICE_TAGS进行设置,多个标签以英文逗号隔开
iii. 采用docker compose部署
Docker compose部署能够解决容器前后启动顺序问题
version: '2' services: load_balancer: image: nginx-consul-template:latest hostname: lb container_name: consul-nginx-template links: - consul_server depends_on: - consul_server ports: - "80:80" environment: - SERVICE_IGNORE=true consul_server: image: progrium/consul hostname: consul_server container_name: consul_server ports: - "8300:8300" - "8301:8301" - "8302:8302" - "8400:8400" - "8500:8500" - "8600:8600" environment: - SERVICE_IGNORE=true command: -server -bootstrap registrator: image: gliderlabs/registrator:latest hostname: registrator container_name: consul_registrator links: - consul_server depends_on: - consul_server volumes: - "/var/run/docker.sock:/tmp/docker.sock" environment: - SERVICE_IGNORE=true command: -ip 192.168.1.60 consul://192.168.1.60:8500
4、 常见问题
待补充...