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、 常見問題
待補充...