1. 程式人生 > 實用技巧 >第11章 服務自動註冊與發現(Docker +Consul +Registrator)

第11章 服務自動註冊與發現(Docker +Consul +Registrator)

  docker最核心的是容器,容器中有相應的業務環境,容器中跑的業務,那麼怎麼實現容器的建立和刪除,業務還能夠不收影響的提供服務

如果建立新的容器,怎麼樣快速發現業務並且提供服務?

這裡就講一下服務註冊

什麼是服務註冊中心?
服務註冊中心本質上是為了瞭解解耦服務提供者和服務消費者,對於任何一個微服務,原則上都存在多個支持者,所以為了支援彈性伸縮的特性,微服務的提供數量和分佈往往是不同變換的,所以需要引用額外的元件來管理微服務提供者的註冊和發現。而這個元件就是服務註冊中心。

服務註冊中心的軟體

  • Zookeeper

  主要的應用在大資料領域,是一種分散式,開放原始碼的分散式應用程式協調服務,是Hadoop和Hbase的重要元件,他是一個分散式應用提供的一致性的服務軟體。

  • Eureka

  是基於REST服務,主要是AWS雲服務為支援,提供服務發現並實現負載均衡和故障轉移

  • Etcd

是基於一個分散式鍵值對儲存系統,用於可靠,快速的儲存關鍵的資料,並提供訪問,通過分散式鎖,leader選舉和寫屏障

  • Consul

  是HashiCorp公司推出的開源工具,用來實現分散式系統的服務發現和配置,安裝包是一個可執行的檔案,方面部署

Consul 主要功能

  • 1, 服務發現

    通過DNS和HTTP介面使得消費者發現服務,應用程式可以輕鬆找到所依賴的服務

  • 2, 健康檢查

    防止將請求轉發到不健康的主機上

  • 3, 鍵值儲存

    可以使用分層鍵/值進行儲存

Consul agent 是Consul的核心元件,分為客戶端和服務端兩種模式

  1. 預設以客戶端模式執行,提供服務註冊,健康檢查,轉發查詢等
  2. server模式去啟動時使用-server的選項指定,用於維護Consul叢集狀態,Raft協議進行選舉。
  3. Agent 必須在每個Consul節點執行,所以執行的Consul agent節點構成Consul叢集。
  4. 建議Consul叢集至少有3或者5個節點執行Consul agent server模式,client節點不限
  5. 通過join和rejoin選項加入叢集,一旦加入,叢集資訊總使用gossip演算法同步到整個叢集節點

自動發現自動註冊的方案

  1. Docker+Etcd+Confd+Nginx
  2. 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;
    
           }
    
    }
    

至此部署成功。