Docker consul的容器服務更新與發現
服務註冊與發現
服務註冊與發現是微服務架構中不可或缺的重要元件。起初服務都是單節點的,不保障高可用性,也不考慮服務的壓力承載,服務之間呼叫單純的通過介面訪問。直到後來出現了多個節點的分散式架構,起初的解決手段是在服務前端負載均衡,這樣前端必須要知道所有後端服務的網路位置,並配置在配置檔案中。這裡就會有幾個問題:
●如果需要呼叫後端服務A-N,就需要配置N個服務的網路位置,配置很麻煩
●後端服務的網路位置變化,都需要改變每個呼叫者的配置
既然有這些問題,那麼服務註冊與發現就是解決這些問題的。後端服務A-N可以把當前自己的網路位置註冊到服務發現模組,服務發現就以K-V(鍵值對)的方式記錄下來,K一般是服務名,V就是IP:PORT。服務發現模組定時的進行健康檢查,輪詢檢視這些後端服務能不能訪問的了。前端在呼叫後端服務A-N的時候,就跑去服務發現模組問下它們的網路位置,然後再呼叫它們的服務。這樣的方式就可以解決上面的問題了,前端完全不需要記錄這些後端服務的網路位置,前端和後端完全解耦!
consul
consul是google開源的一個使用go語言開發的服務管理軟體。支援多資料中心、分散式高可用的、服務發現和配置共享。採用Raft演算法,用來保證服務的高可用。內建了服務註冊與發現框架、分佈一致性協議實現、健康檢查、Key/Value儲存、多資料中心方案,不再需要依賴其他工具(比如ZooKeeper等)。服務部署簡單,只有一個可執行的二進位制的包。每個節點都需要執行agent,他有兩種執行模式server 和 client。 每個資料中心官方建議需要3或5個server節點以保證資料安全,同時保證server-leader的選舉能夠正確的進行。
在client模式下,所有註冊到當前節點的服務會被轉發到server節點,本身是不持久化這些資訊。
在server模式下,功能和client模式相似,唯一不同的是,它會把所有的資訊持久化到本地,這樣遇到故障,資訊是可以被保留的。
server-leader是所有server節點的老大,它和其它server節點不同的是,它需要負責同步註冊的資訊給其它的server節點,同時也要負責各個節點的健康監測。
consul一些關鍵特性
服務註冊與發現:consul通過DNS或者HTTP介面使服務註冊和服務發現變的很容易,一些外部服務,例如saas提供的也可以一樣註冊。
健康檢查:健康檢測(探針)使consul可以快速的告警在叢集中的操作。和服務發現的整合,可以防止服務轉發到故障的服務上面。
Key/Value儲存
多資料中心:無需複雜的配置,即可支援任意數量的區域。
安裝consul是用於服務註冊,也就是容器本身的一些資訊註冊到consul裡面,其他程式可以通過consul獲取註冊的相關服務資訊,這就是服務註冊與發現。
consul 部署
伺服器 |
IP |
服務 |
consul伺服器 |
192.168.150.30 |
執行consul服務、nginx服務、consul-template守護程序 |
registrator伺服器 |
192.168.150.25 |
執行registrator容器、nginx容器 |
systemctl stop firewalld.service
setenforce 0
#配置consul伺服器
1、建立 Consul 服務
mkdir /opt/consul
cp consul_0.9.2_linux_amd64.zip /opt/consul
cd /opt/consul
unzip consul_0.9.2_linux_amd64.zip
mv consul /usr/local/bin/
2、設定代理,在後臺啟動 consul 服務端
consul agent \
-server \
-bootstrap \
-ui \
-data-dir=/var/lib/consul-data \
-bind=192.168.150.30\
-client=0.0.0.0 \
-node=consul-server01 &> /var/log/consul.log & #將啟動中的資訊放入到日誌中
欄位解析 |
|
-server |
以server身份啟動。預設是client。 |
-bootstrap |
用來控制一個server是否在bootstrap模式,在一個數據中心中只能有一個server處於bootstrap模式,當一個server處於 bootstrap模式時,可以自己選舉為 server-leader。 |
-bootstrap-expect=2 |
叢集要求的最少server數量,當低於這個數量,叢集即失效。 |
-ui |
指定開啟 UI 介面,這樣可以通過 http://localhost:8500/ui 這樣的地址訪問 consul 自帶的 web UI 介面。 |
-data-dir |
指定資料儲存目錄。 |
-bind |
指定用來在叢集內部的通訊地址,叢集內的所有節點到此地址都必須是可達的,預設是0.0.0.0。 |
-client |
指定 consul 繫結在哪個 client 地址上,這個地址提供 HTTP、DNS、RPC 等服務,預設是 127.0.0.1。 |
-node |
節點在叢集中的名稱,在一個叢集中必須是唯一的,預設是該節點的主機名。 |
-datacenter |
指定資料中心名稱,預設是dc1。 |
netstat -natp | grep consul
啟動consul後預設會監聽5個埠:
8300 |
replication、leader farwarding的埠(副本同步,轉發的埠) |
8301 |
lan cossip的埠(叢集內部連線的埠) |
8302 |
wan gossip的埠(叢集外部連線的埠) |
8500 |
web ui介面的埠(web介面的訪問埠) |
8600 |
使用dns協議檢視節點資訊的埠(DNS協議使用的埠) |
3、檢視叢集資訊
consul members #檢視members狀態
consul operator raft list-peers#檢視叢集狀態
consul info | grep leader #可以篩選出leader的資訊
4、通過 http api 獲取叢集資訊
curl 127.0.0.1:8500/v1/status/peers #檢視叢集server成員
curl 127.0.0.1:8500/v1/status/leader #叢集 server-leader
curl 127.0.0.1:8500/v1/catalog/services #註冊的所有服務
curl 127.0.0.1:8500/v1/catalog/nginx #檢視 nginx 服務資訊
curl 127.0.0.1:8500/v1/catalog/nodes #叢集節點詳細資訊
配置registrator伺服器
#容器服務自動加入 Nginx 叢集
5、安裝 Gliderlabs/Registrator
Gliderlabs/Registrator 可檢查容器執行狀態自動註冊,還可登出 docker 容器的服務到服務配置中心。目前支援 Consul、Etcd 和 SkyDNS2。
docker run -d \ #自動安裝拉取映象
--name=registrator \
--net=host \
-v /var/run/docker.sock:/tmp/docker.sock \ #-v即可以掛載目錄也可以掛載檔案
--restart=always \
gliderlabs/registrator:latest \#選擇映象
--ip=192.168.150.25\
consul://192.168.150.30:8500
欄位解析 |
|
--net=host |
把執行的docker容器設定為host網路模式,與主機共享ip和埠。 |
-v /var/run/docker.sock:/tmp/docker.sock |
把宿主機的Docker守護程序(Docker daemon)預設監聽的Unix域套接字掛載到容器中。 |
--restart=always |
設定在容器退出時總是重啟容器。 |
--ip |
剛才把network指定了host模式,所以指定ip為宿主機的ip。 |
consul |
指定consul伺服器的IP和埠。 |
6、測試服務發現功能是否正常
docker run -itd -p83:80 --name No1 -h No1 nginx
docker run -itd -p84:80 --name No2 -h No2 nginx
docker run -itd -p85:80 --name No3 -h No3 httpd
docker run -itd -p86:80 --name No4 -h No4 httpd #-h:設定容器主機名
7、驗證 http 和 nginx 服務是否註冊到 consul
瀏覽器中,輸入http://192.168.150.30:8500,在 Web 頁面中“單擊 NODES”,然後單擊“consurl-server01”,會出現 5個服務。
#在consul伺服器使用curl測試連線伺服器
curl 127.0.0.1:8500/v1/catalog/services
{"consul":[],"httpd":[],"nginx":[]}
consul-template
Consul-Template是基於Consul的自動替換配置檔案的應用。Consul-Template是一個守護程序,用於實時查詢Consul叢集資訊,並更新檔案系統上任意數量的指定模板,生成配置檔案。更新完成以後,可以選擇執行 shell 命令執行更新操作,重新載入 Nginx。
Consul-Template可以查詢Consul中的服務目錄、Key、Key-values 等。這種強大的抽象功能和查詢語言模板可以使 Consul-Template 特別適合動態的建立配置檔案。例如:建立Apache/Nginx Proxy Balancers 、 Haproxy Backends(後端代理配置)等。
1、準備 template nginx 模板檔案
在consul伺服器上操作
vim /opt/consul/nginx.ctmpl
#定義nginx upstream一個簡單模板
upstream nginx_backend {
{{range service "nginx"}} #固定格式range開頭,end結尾
server {{.Address}}:{{.Port}}; #{{XX}}代表一個變數
{{end}}
}
#定義一個server,監聽8000埠,反向代理到upstream
server {
listen 8000;
server_name localhost 192.168.150.30;
access_log /var/log/nginx/aaa.com-access.log; #修改日誌路徑
index index.html 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://nginx_backend;
}
}
2、編譯安裝nginx
yum -y install pcre-devel zlib-devel gcc gcc-c++ make
useradd -M -s /sbin/nologin nginx
tar zxvf nginx-1.12.0.tar.gz -C /opt/
cd /opt/nginx-1.12.0/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
3、配置 nginx
vim /usr/local/nginx/conf/nginx.conf
......
http {
include mime.types;
include vhost/*.conf; #新增虛擬主機目錄
default_type application/octet-stream;
......
mkdir /usr/local/nginx/conf/vhost #建立虛擬主機目錄
mkdir /var/log/nginx #建立日誌檔案目錄
nginx #啟動nginx
4、配置並啟動 template
unzip consul-template_0.19.3_linux_amd64.zip -d /opt/
cd /opt/
mv consul-template /usr/local/bin/
#在前臺啟動 template 服務,啟動後不要按 ctrl+c 中止 consul-template 程序。
consul-template --consul-addr 192.168.150.30:8500 \
--template "/opt/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/aaa.conf:/usr/local/nginx/sbin/nginx -s reload" \
--log-level=info
#/opt/consul/nginx.ctmpl:模板檔案路徑
#/usr/local/nginx/conf/vhost/aaa.conf:生成的檔案路徑
#另外開啟一個終端檢視生成配置檔案
cat /usr/local/nginx/conf/vhost/aaa.conf
upstream nginx_backend {
server 192.168.150.25:83;
server 192.168.150.25:84;
}
server {
listen 8000;
server_name 192.168.150.30;
access_log /var/log/nginx/aaa.cpm-access.log;
index index.html 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://nginx_backend;
}
}
5、訪問 template-nginx
#在registrator伺服器編輯nginx容器首頁檔案
docker ps -a
docker exec -it 54f260c3ddf2 bash
echo "this is No1 web" > /usr/share/nginx/html/index.html
docker exec -it 73560aabf83b bash
echo "this is No2 web" > /usr/share/nginx/html/index.html
瀏覽器訪問:http://192.168.150.30:8000/ ,並不斷重新整理
6、增加一個 nginx 容器節點
(1)增加一個 nginx 容器節點,測試服務發現及配置更新功能。
docker run -itd -p87:80 --name No5 -h No5nginx
#觀察 template 服務,會從模板更新/usr/local/nginx/conf/vhost/aaa.conf 檔案內容,並且過載 nginx 服務。
(2)檢視/usr/local/nginx/conf/vhost/aaa.conf 檔案內容
cat /usr/local/nginx/conf/vhost/aaa.conf
(3)檢視三臺 nginx 容器日誌,請求正常輪詢到各個容器節點上,並且日誌中會記錄真實的ip地址
docker logs -f No1
docker logs -f No2
docker logs -f No5
consul 多節點部署
#新增一臺已有docker環境的伺服器(例如:192.168.150.25/24)加入已有的群集中
unzip consul_0.9.2_linux_amd64.zip #解壓consul安裝包
mv consul /usr/local/bin/
consul agent \
-server \
-ui \
-data-dir=/var/lib/consul-data \
-bind=192.168.150.25\
-client=0.0.0.0 \
-node=consul-server02 \
-enable-script-checks=true \
-datacenter=dc1 \
-join 192.168.150.30&> /var/log/consul.log &
欄位解析 |
|
-enable-script-checks=true |
設定檢查服務為可用 |
-datacenter |
資料中心名稱 |
-join |
加入到已有的叢集中 |
consul members #檢視members狀態
consul operator raft list-peers#檢視叢集狀態