您好,登錄后才能下訂單哦!
反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現為一個服務器。通過在網絡各處放置反向代理節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,CDN系統能夠實時地根據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近的服務節點上。本文將用Docker+Etcd+Confd+Nginx架構實現反向代理。
本文中我們主要來介紹 Docker+Etcd+Confd+Nginx方案,此方案更加高效、快捷,并且維護代價和容錯率更低,分布式支持力度更強,如下圖所示:
上面示意圖的大概流程如下:
1、docker01主機上以二進制包的方式部署consul服務并后臺運行,其身份為leader;
2、docker02、docker03以容器的方式運行consul服務,并加入到docker01的consul群集中;
3、在主機docker02、docker03上后臺運行registrator容器,使其自動發現docker容器提供的服務;
4、在docker01上部署Nginx,提供反向代理服務,docker02、docker03主機上基于Nginx鏡像,各運行兩個web容器,提供不同的網頁文件,以便測試效果;
5、在docker01上安裝consul-template命令,將收集到的信息(registrator收集到容器的信息)寫入template模板中,并且最終寫入Nginx的配置文件中。
6、至此,實現客戶端通過訪問Nginx反向代理服務器(docker01),獲得docker02、docker03服務器上運行的Nginx容器提供的網頁文件。
注:registrator是一個自動發現docker container提供的服務,并且在后端服務注冊中心(數據中心)注冊服務。主要用來收集容器運行服務的信息,并且發送給consul。數據中心除了consul外,還有etcd、zookeeper等。
Docker+Consul+Nginx雖然看起來是三個組件的運用,但卻證明是一個有機的整體。它們互相聯系、互相作用,完全滿足我們對高可用、高效服務架構方案的需求,是Docker生態圈中最理想的組合之一,具有以下優勢:
1.發現與注冊組件consul使用 Raft 算法來保證一致性,比復雜的Paxos 算法更直接。相比較而言,zookeeper 采用的是 Paxos,而 etcd 使用的則是 Raft;
2.多數據中心,多數據中心集群可以避免單數據中心的單點故障,zookeeper 和 etcd 均不提供多數據中心功能的支持;
3.、實時發現及無感知服務刷新,具備資源彈性,伸縮自如;
4.健康檢查,負載能動態在可用的服務實例上進行均衡,etcd 不提供此功能;
5.足夠多臺Docker容器(前提架構資源足以保證性能支撐);
6.http 和dns 協議接口,zookeeper 的集成較為復雜,etcd 只支持 http 協議;
7.規模方便進行快速調整,官方提供web管理界面,etcd 無此功能;
8.nsul template 搭配consul使用,支持多種接入層,如Nginx、Haproxy。
主機 | iP地址 | 服務 |
---|---|---|
docker01 | 192.168.1.11 | consul+consul-template+nginx |
docker02 | 192.168.1.13 | consul+registrator |
docker03 | 192.168.1.20 | consul+registrator |
三臺主機關閉防火墻,禁用selinux,更改主機名如上所述。
[root@docker01 ~]# unzip consul_1.5.1_linux_amd64.zip
//現在是本地導入壓縮包,需要解壓
[root@docker01 ~]# mv consul /usr/local/bin/
//移動服務到bin目錄
[root@docker01 ~]# chmod +x /usr/local/bin/consul
//給予一個可執行權限
[root@docker01 ~]# consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.1.11 -client=0.0.0.0 -node=master
PS: //-bootstrap: 加入這個選項時,一般都在server單節點的時候用,自選舉為leader。
參數解釋:
-server:添加一個服務
-bootstrap:一般在server單節點的時候使用,自選舉為leader。
-data-dir:key/volume指定數據存放的目錄
-ui:開啟內部的web界面
-bind:指定開啟服務的ip
-client:指定訪問的客戶端
-node:在集群內部通信使用的名稱,默認是主機名。
現在這個ip是外部使用
PS:開啟的端口
8300 集群節點
8301 集群內部的訪問
8302 跨數據中心的通信
8500 web ui界面
8600 使用dns協議查看節點信息的端口
可參考下圖查看端口的意思:
這時,這條啟動consul的命令會占用終端,可以使用nohup命令讓它保持后臺運行。
[root@docker01 ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consule-data -bind=192.168.1.11 -client=0.0.0.0 -node=master &
[root@docker01 ~]# consul info
在 https://github.com/hashicorp/consul-template 上,下載consul-template
[root@docker01 ~]# unzip consul-template_0.19.5_linux_amd64.zip
//解壓安裝好的consul-template包
[root@docker01 ~]# mv consul-template /usr/local/bin/
//移動到命令目錄
[root@docker01 ~]# chmod +x /usr/local/bin/consul-template
//給予一個可執行權限
在docker01和docker02上操作
先來說一下在docker服務器上操作的大概思路:
分別在兩臺docker服務器上都創建registrator容器,注意到consul服務中心;
在docker01上運行兩臺nginx容器(端口隨機生成),在docker02上運行兩臺nginx容器(端口隨機生成);
修改這4臺nginx容器中的index.html頁面內容為(xgp-web01、xgp-web02、xgp-web03、xgp-web04)
訪問consul web界面驗證
訪問nginx服務器地址 http://192.168.1.11:8000 進行驗證;
這里我們采用容器的方式去運行consul服務。
[root@docker02 ~]# docker pull consul
[root@docker02 ~]# docker run -d --name consul -p 8301:8301 -p 8301:8301/udp -p 8500:8500 -p 8600:8600 -p 8600:8600/udp --restart always progrium/consul -join 192.168.1.11 -advertise 192.168.1.13 -client 0.0.0.0 -node=node01
參數解釋:
-d:守護進程
--name:容器名稱
--restart:容器隨著docker服務一直運行
-advertise:聲明本機地址
-join:聲明服務端地址
-node:consul集群中的名稱
[root@docker01 ~]# consul members
registrator是一個能自動發現docker container提供的服務,并在后端服務注冊中心注冊服務或取消服務的工具,后端注冊中心支持conusl、etcd、 skydns2、zookeeper等。
[root@docker02 ~]# docker pull registrator
//下載registrator鏡像
[root@docker02 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.1.13:8500
參數說明:
--network:把運行的docker容器設定為host網絡模式;
-v /var/run/docker.sock:把宿主機的Docker守護進程(Docker daemon)默認監聽的Unix域套接字掛載到容器中;
--ip : 剛才把network指定了host模式,所以我們指定下IP為宿主機的IP;
consul:j最后這個選項是配置consul服務器的IP和端口。(3)開啟一臺nginx容器
[root@docker02 ~]# docker run -d —P --name nginx nginx:latest
配置nginx,大概配置的思路為:
在/usr/local/nginx/conf中創建目錄consul,目錄名自定義;
在consul目錄中創建nginx.ctmpl模板;
在nginx.conf配置中添加include項并指向consul目錄 ;
重啟nginx服務;
安裝nginx依賴包
[root@docker01 ~]# yum -y install pcre pcre-devel openssl openssl-devel zlib zlib-devel
編譯安裝nginx
[root@docker01 ~]# cd nginx-1.14.0/
[root@docker01 nginx-1.14.0]# ./configure --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module && make && make install
創建所需用戶和鏈接命令目錄
[root@docker01 nginx-1.14.0]# useradd -M -s /sbin/nologin nginx
[root@docker01 nginx-1.14.0]# ln -s /usr/local/nginx/sbin/* /usr/local/bin/
檢查nginx是否有問題,并開啟nginx
[root@docker01 nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@docker01 nginx-1.14.0]# nginx
PS:這里nginx作為反向代理,代理后端docker02、 docker03 上nginx的容器服務,所以我們先去docker02、docker03. 上部署一些服務, 為了方便等會看到負載的效果,所以,我們運行完成容器之后,做一個主界面內容的區分。
[root@docker01 nginx-1.14.0]# curl 127.0.0.1
主機 | 服務 | |
---|---|---|
docker02 | nginx | web01,web02 |
docker03 | nginx | web03,web04 |
[root@docker02 ~]# docker pull nginx
//下載nginx鏡像
基于nginx鏡像運行上述所說的容器并設置測試頁面
web01
[root@docker02 ~]# docker run -itd --name web01 -P nginx:latest
[root@docker02 ~]# docker exec -it web01 /bin/bash
root@44b59d07202f:/# cd /usr/share/nginx/html/
root@44b59d07202f:/usr/share/nginx/html# echo web01 > index.html
web02
[root@docker02 ~]# docker run -itd --name web02 -P nginx:latest
[root@docker02 ~]# docker exec -it web02 /bin/bash
root@44b59d07202f:/# cd /usr/share/nginx/html/
root@44b59d07202f:/usr/share/nginx/html# echo web02 > index.html
基于nginx鏡像運行上述所說的容器并設置測試頁面
web03
[root@docker03 ~]# docker run -itd --name web03 -P nginx:latest
[root@docker03 ~]# docker exec -it web03 /bin/bash
root@fd8e8b2df136:/# cd /usr/share/nginx/html/
root@fd8e8b2df136:/usr/share/nginx/html# echo web03 > index.html
root@fd8e8b2df136:/usr/share/nginx/html# exit
web04
[root@docker03 ~]# docker run -itd --name web04 -P nginx:latest
[root@docker03 ~]# docker exec -it web04 /bin/bash
root@fd8e8b2df136:/# cd /usr/share/nginx/html/
root@fd8e8b2df136:/usr/share/nginx/html# echo web04 > index.html
root@fd8e8b2df136:/usr/share/nginx/html# exit
[root@docker01 ~]# cd /usr/local/nginx/
//進入nginx配置文件目錄
[root@docker01 nginx]# mkdir consul
//創建consul目錄
[root@docker01 nginx]# cd consul/
//進入consul目錄
[root@docker01 consul]# vim nginx.ctmpl
upstream http_backend {
{{range service "nginx"}}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
nginx.ctmpl模板中的內容就是兩段意思,熟悉nginx的朋友一看也能明白:第1 定義nginx upstream一個簡單模板,第2 定義一個server,監聽8000端口,反向代理到upstream。
[root@docker01 consul]# cd /usr/local/nginx/conf/
[root@docker01 conf]# vim nginx.conf
include /usr/local/nginx/consul/*.conf; #文件最后添加(要在大括號里面)
使用consul-template命令,根據模板生產新的配置文件,并重新加載nginx的配置文件。
[root@docker01 conf]# consul-template -consul-addr 192.168.1.11:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/bin/nginx -s reload"
參數說明:
--consul-addr:指定consul服務的ip和端口;
./nginx.ctmpl:這是用nginx.ctmpl這個模板來啟動進程,這是寫的相對路徑,也可以寫絕對路徑;
vhost.conf:nginx.ctmpl模板生成后的文件名,這也可以寫絕對路徑,如果不寫絕對路徑,這個文件就在當前目錄生成(/usr/local/nginx/consul/)
這時,這條命令會占用終端,可以使用nohup命令讓它保持后臺運行,并重啟nginx服務。
[root@docker01 conf]# nohup consul-template -consul-addr 192.168.1.11:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload" &
查看一下文件是否生成,里面是否有內容
[root@docker01 ~]# cd /usr/local/nginx/consul/
[root@docker01 consul]# ls
nginx.ctmpl vhost.conf
[root@docker01 consul]# cat vhost.conf
此時,應該能夠看到,新生產的vhost.conf配置文件已經生效,訪問本機8000端口可以得到不同容器提供的服務。
[root@docker01 consul]# curl 127.0.0.1:8000
web01
此時可以看到負載均衡的效果!
查看端口8000是否開啟
[root@docker01 consul]# ss -lnt
檢查nginx配置文件
[root@docker01 consul]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
檢查自己編寫的nginx配置文件
[root@docker01 consul]# cd /usr/local/nginx/consul/
[root@docker01 consul]# cat nginx.ctmpl
upstream http_backend {
{{range service "nginx"}}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
如果nginx配置文件沒問題,重啟nginx
[root@docker01 consul]# nginx -s reload
docker02 創建測試容器
[root@docker02 ~]# docker run -itd --name web05 -P nginx:latest
[root@docker02 ~]# docker exec -it web05 /bin/bash
root@44b59d07202f:/# cd /usr/share/nginx/html/
root@44b59d07202f:/usr/share/nginx/html# echo web02 > index.html
[root@docker02 ~]# docker ps
docker01查看
[root@docker01 consul]# cd /usr/local/nginx/consul/
[root@docker01 consul]# cat vhost.conf
docker01測試訪問
[root@docker01 consul]# curl 127.0.0.1:8000
//同上
此時可以看到負載均衡的效果!
這時不需要考慮后端的web服務器添加還是刪除都會自動更新的,這是因為在運行consul-template這條命令后添加的/usr/local/sbin/nginx -s reload的作用!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。