第11章 服務自動註冊與發現(Docker +Consul +Registrator)
docker最核心的是容器,容器中有相應的業務環境,容器中跑的業務,那麼怎麼實現容器的建立和刪除,業務還能夠不收影響的提供服務
如果建立新的容器,怎麼樣快速發現業務並且提供服務?
這裡就講一下服務註冊
什麼是服務註冊中心?
服務註冊中心本質上是為了瞭解解耦服務提供者和服務消費者,對於任何一個微服務,原則上都存在多個支持者,所以為了支援彈性伸縮的特性,微服務的提供數量和分佈往往是不同變換的,所以需要引用額外的元件來管理微服務提供者的註冊和發現。而這個元件就是服務註冊中心。
服務註冊中心的軟體
- Zookeeper
主要的應用在大資料領域,是一種分散式,開放原始碼的分散式應用程式協調服務,是Hadoop和Hbase的重要元件,他是一個分散式應用提供的一致性的服務軟體。
- Eureka
是基於REST服務,主要是AWS雲服務為支援,提供服務發現並實現負載均衡和故障轉移
- Etcd
是基於一個分散式鍵值對儲存系統,用於可靠,快速的儲存關鍵的資料,並提供訪問,通過分散式鎖,leader選舉和寫屏障
- Consul
是HashiCorp公司推出的開源工具,用來實現分散式系統的服務發現和配置,安裝包是一個可執行的檔案,方面部署
Consul 主要功能
- 1, 服務發現
通過DNS和HTTP介面使得消費者發現服務,應用程式可以輕鬆找到所依賴的服務
- 2, 健康檢查
防止將請求轉發到不健康的主機上
- 3, 鍵值儲存
可以使用分層鍵/值進行儲存
Consul agent 是Consul的核心元件,分為客戶端和服務端兩種模式
- 預設以客戶端模式執行,提供服務註冊,健康檢查,轉發查詢等
- server模式去啟動時使用-server的選項指定,用於維護Consul叢集狀態,Raft協議進行選舉。
- Agent 必須在每個Consul節點執行,所以執行的Consul agent節點構成Consul叢集。
- 建議Consul叢集至少有3或者5個節點執行Consul agent server模式,client節點不限
- 通過join和rejoin選項加入叢集,一旦加入,叢集資訊總使用gossip演算法同步到整個叢集節點
自動發現自動註冊的方案
- Docker+Etcd+Confd+Nginx
- Docker+Consul+Nginx
註冊器(registrator):根據服務執行狀態,註冊/登出服務。主要要解決的問題是,何時發起註冊/登出動作。
登錄檔(registry):儲存服務資訊。常見的解決方案有zookeeper、etcd、cousul等。
發現機制(discovery):從登錄檔讀取服務資訊,給使用者封裝訪問介面。
專案部署(Docker+Consul+Nginx)
使用Docker 將Consul,Consul Template,Registrator 和nginx結合成一個可拓展的服務架構,此架構可以新增和移除服務,具體部署如下
- 當容器啟動後registrator就會進行註冊
- registrator會將註冊資訊傳送給consul agent client
- consul agent client將檔案直接傳送給leader
- leader會將新的資訊更新到consul template上
- consul template會將資料寫入到nginx.conf中
- nginx會根據nginx.xonf檔案給web提供資料
服務搭建
伺服器 |
IP地址 |
軟體 |
作業系統 |
Consul |
192.168.2.224 |
Nginx consul conul-temliate |
Centos7 |
Docker01 |
192.168.2.222 |
Docker-ce registrator |
Centos7 |
Docker02 |
192.168.2.223 |
Docker-ce registrator |
Centos7 |
1.部署consul
- 解壓consul包
-
[root@consul ~]# unzip consul_0.9.2_linux_amd64.zip Archive: consul_0.9.2_linux_amd64.zip inflating: consul [root@consul ~]# mv consul /usr/bin/
- 指定leader的consul,並且指定相應的資料引數
-
[root@consul ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.2.224 -client=0.0.0.0 -node=consul-server01 &> /var/log/consul.log & [1] 2602
- 命令解釋
- consul agent -server -bootstrap :本身設定成為leader,一個的話指定一下,多個就不需要了
- nohup英文全稱 no hang up(不掛起),用於在系統後臺不掛斷地執行命令,退出終端不會影響程式的執行。
- -ui:指定開啟UI介面顯示
- -data-dir=/var/lib/consul-data 資料放在的路徑
- -bind=192.168.2.224 監聽的IP
- -client=0.0.0.0 繫結在哪個client地址
- -node=consul-server01 節點在叢集中的名字,在叢集中節點是唯一的,預設是該節點的主機名
- 檢視是否執行中
-
[root@consul ~]# jobs [1]+ 執行中 nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.2.224 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &
- 檢視consul叢集成員的資訊(因為只部署了一個consul,所以現在只能可檢視到一個)
-
[root@consul ~]# consul members Node Address Status Type Build Protocol DC consul-server01 192.168.2.224:8301 alive server 0.9.2 2 dc1
- 檢視consul叢集中的leader
-
[root@consul ~]# consul info |grep leader leader = true leader_addr = 192.168.2.224:8300
- 檢視consul所管理的服務
-
[root@consul ~]# consul catalog services Consul 一共五個埠 8300 replication leader farwarding的埠相互複製的埠 8301 lan cossip的埠 8302 wan gossip的埠 8500 web ui介面的埠 8600 使用dns協議檢視節點資訊的埠
- 下載映象
-
[root@docker01 docker]# docker pull gliderlabs/registrator:latest latest: Pulling from gliderlabs/registrator Image docker.io/gliderlabs/registrator:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/ c87f684ee1c2: Pull complete a0559c0b3676: Pull complete a28552c49839: Pull complete Digest: sha256:6e708681dd52e28f4f39d048ac75376c9a762c44b3d75b2824173f8364e52c10 Status: Downloaded newer image for gliderlabs/registrator:latest docker.io/gliderlabs/registrator:latest
2.部署registrator容器服務
- 執行registrator容器
-
[root@docker01 docker]# docker run -d --name=registrator --net=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest -ip=192.168.2.222 consul://192.168.2.224:8500
[root@docker02 docker]# docker run -d --name=registrator --net=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest -ip=192.168.2.223 consul://192.168.2.224:8500
- 測試服務發現功能是正常
-
宿主機訪問http://192.168.2.224:8500/ui/#/dc1/services
- 編寫web指令碼,要進行測試
-
[root@docker01 docker]# vim /web/index.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>登入</title> </head> <body> <form action="LoginServlet" method="post"> <table> <tr> <td>賬號</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密碼</td> <td><input type="password" name="password"></td> </tr> <tr> <td><input type="submit" value="登入"></td> </tr> </table> </form> </body>
-
開啟兩臺容器進行測試
-
[root@docker01 docker]# docker run -itd -p:8002:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t2 -h docker01-t2 tomcat b51abc4d730170b906bc033c69bd2fa3eb44369fcabd41ea6c90eb55f116b02f [root@docker01 docker]# docker run -itd -p:8001:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t1 -h docker01-t1 tomcat 7314559a133f23d5eebd08846922964ea5d9eeccd5cf3281c7bcfc5ff6061b0e
- 測試成功
- 增加兩臺tomcat,表示測試成功
- 再次不同埠增加兩臺tomcat容器
-
[root@docker02 docker]# docker run -itd -p:8001:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t1 -h docker01-t1 tomcat Unable to find image 'tomcat:latest' locally latest: Pulling from library/tomcat 6c33745f49b4: Pull complete c87cd3c61e27: Pull complete 05a3c799ec37: Pull complete a61c38f966ac: Pull complete 396b39798a69: Pull complete 576b6480761a: Pull complete 0d66e5d46fdf: Pull complete c9a19e25684c: Pull complete 511576b95265: Pull complete 7cbc3d736630: Pull complete Digest: sha256:f728ca177fee0851aea29499fbb2013737231a00264f517cc3d185f6f8bf09a8 Status: Downloaded newer image for tomcat:latest 4f73eefca98e2e5eee55463e3a298e1d20529b08be2fb25971bcdaa657484af6 [root@docker02 docker]# docker run -itd -p:8002:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t2 -h docker01-t2 tomcat ef8b5c1174cb45441a9ce68b124688c07ba228456fac8bef54a551bf2701fdac [root@docker02 docker]#
- 進行測試
3. 安裝consul-template
-
[root@consul ~]# mkdir consul [root@consul ~]# cd consul [root@consul consul]# vim /root/consul/nginx.tmp [root@consul consul]# cat /root/consul/nginx.tmp uptream http_backend { {{range service "tomcat"}} server {{ .Address }}:{{ .Port }}; {{ end }} } server { listen 8080; server_name localhost 192.168.2.224; access_log /usr/local/nginx/logs/crushlinux-access.log; index index.html index.jsp index.php; location / { proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Client-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://http_backend; } }
4.安裝NGINX
-
[root@consul consul]# yum -y install gcc gcc-c++ make pcre-devel zlib-devel openssl-devel [root@consul ~]# tar xf nginx-1.12.1.tar_\(1\).gz -C /usr/src/ [root@consul nginx-1.12.1]# cd /usr/src/nginx-1.12.1/ [root@consul nginx-1.12.1]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module && make -j 2 && make install
- 修改配置檔案
-
將下列加入配置檔案: [root@consul nginx-1.12.1]# vim /usr/local/nginx/conf/nginx.conf include vhost/*.conf;
-
建立目錄,重新啟動NGINX
-
[root@consul ~]# mkdir /usr/local/nginx/conf/vhost/ [root@consul ~]# /usr/local/nginx/sbin/nginx
5.測試:
- 目前目錄下無東西,基於consul模板生成子檔案
-
[root@consul ~]# ls /usr/local/nginx/conf/vhost/ [root@consul ~]# ls consul nginx.tmp
- 配置並啟用consul-template
-
[root@consul ~]# unzip consul-template_0.19.3_linux_amd64_\(1\).zip Archive: consul-template_0.19.3_linux_amd64_(1).zip inflating: consul-template [root@consul ~]# ls anaconda-ks.cfg downloads.html CentOS-7-x86_64-DVD-1810.zip index.html centos-7-x86_64.tar.gz mnt consul mysql consul_0.9.2_linux_amd64.zip nginx-1.12.1 consul-template nginx-1.12.1.tar_(1).gz consul-template_0.19.3_linux_amd64_(1).zip stress [root@consul ~]# mv consul-template /usr/bin/ [root@consul ~]# consul-template -consul-addr 192.168.2.224:8500 -template "/root/consul/nginx.tmp:/usr/local/nginx/conf/vhost/Carrie.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info
- 檢視子檔案,已經出現了相應內容
-
[root@consul ~]# ls /usr/local/nginx/conf/vhost/ Carrie.conf [root@consul ~]# cat /usr/local/nginx/conf/vhost/Carrie.conf uptream http_backend { server 192.168.2.222:8001; server 192.168.2.222:8002; server 192.168.2.223:8001; server 192.168.2.223:8002; } server { listen 8080; server_name localhost 192.168.2.224; access_log /usr/local/nginx/logs/crushlinux-access.log; index index.html index.jsp index.php; location / { proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Client-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://http_backend; } }
至此部署成功。