摘要
Consul 有以下幾個關鍵特性:
- 服務發現:支持服務發現。你可以通過 DNS 或 HTTP 的方式獲取服務信息。
- 健康檢查:支持健康檢查。可以提供與給定服務相關聯的任何數量的健康檢查(如 web 狀態碼或 cpu 使用率)。
- K/V 存儲:鍵/值對存儲。你可用通過 consul 存儲如動態配置之類的相關信息。
- 多數據中心:支持多數據中心,開箱即用。
- WEB-UI:支持 WEB-UI。點點點,你就能夠了解你的服務現在的運行情況,一目了然,對開發運維是非常友好的。
一、案例概述
公司提出一個新需求,使用Docker將Consul、Consul Template、Registrator和Nginx組裝成一個值得信任且可擴展的服務框架,可在這個框架中添加和移除服務,不需要重寫任何配置,也不需要重啟任何服務,一切都能正常運行
1.1、Docker Compose
1.1.1、Docker Compose的前身是Fig,它是一個定義及運行多個Docker容器的工具
1.1.2、使用Docker Compose不再需要使用Shell腳本來啟動容器
1.1.3、Docker Compose非常適合組合多個容器進行開發的場景
1.2、Consul
1.2.1、Consul是HashiCorp公司推出的開源工具,用於實現分布式系統的服務發現與配置
1.2.2、Consul的特性
支持健康檢查,允許存儲鍵值對
基於Golong語言,可移植性強
支持ACL訪問控制
1.2.3、與Docker等輕量級容器可無縫配合
二、使用docker-compose搭建consul集群環境
2.1、案例環境
主機 |
操作系統 |
主機名/IP地址 |
主要軟件及版本 |
服務器 server1 |
Centos 7.4 |
Consul/20.0.0.10 |
Docker、Compose Consul、Consul-template |
服務器 server2 |
Centos 7.4 |
Registrator/20.0.0.20 |
Docker、registrator |
2.2、案例需求
- 實現單機網絡下容器與容器之間互通
- 使用Docker Compose創建容器
- 搭建Consul服務實現自動發現和更新
2.3、Docker Compose容器編排
2.3.1、YAML是一種標記語言很直觀的數據序列化格式
2.3.2、文件格式及編寫注意事項
- 不支持制表符tab鍵縮進,需要使用空格縮進
- 通常開頭縮進2個空格
- 字符后縮進1個空格,如冒號、逗號、橫桿
- 用#號注釋
- 如果包含特殊字符用單引號引起來
- 布爾值必須用引號括起來
2.4、Docker Compose配置常用字段
字段 |
描述 |
build dockerfile context |
指定Dockerfile文件名構建鏡像上下文路徑 |
image |
指定鏡像 |
command |
執行命令,覆蓋默認命令 |
container name |
指定容器名稱,由於容器名稱是唯一的,如果指定自定義名稱,則無法scale |
deploy |
指定部署和運行服務相關配置,只能在Swarm模式使用 |
environment |
添加環境變量 |
networks |
加入網絡 |
ports |
暴露端口號,與-p相同,但端口號不能低於60 |
volume |
掛載宿主機路徑或命令卷 |
restart |
重啟策略,默認no,always,no-failure,unless-stoped |
hostname |
容器主機名 |
2.5、Docker Compose常用命令
字段 |
描述 |
build |
重新構建服務 |
ps |
列出容器 |
up |
創建和啟動容器 |
exec |
在容器里面執行命令 |
scale |
指定一個服容器啟動數量 |
top |
顯示容器進程 |
logs |
查看容器輸出 |
down |
刪除容器、網絡、數據卷和鏡像 |
stop/start/restart |
停止/啟動/重啟服務 |
2.6、Compose命令說明
2.6.1、基本的使用格式
1 docker-compose [options] [COMMAND] [ARGS...]
2.6.2、docker-compose選項
- --verbose 輸出更多調試信息
- --version 打印版本並退出
- -f,--file FILE使用特定的compose模板文件,默認為docker-compose.yml
- -p,--project-name NAME 指定項目名稱,默認使用目錄名稱
三、案例部署
3.1、server1和server2安裝docker(server1上演示)
3.1.1、安裝依賴包
1 [root@server1 yum.repos.d]# yum -y install yum-utils device-mapper-persistent-data lvm2
2
3 #yum-utils 提供了 yum-config-manager
4 #device mapper 存儲驅動程序需要 device-mapper-persistent-data 和 lvm2
5 #device mapper 是 linux2.6 內核中支持邏輯卷管理的通用設備映射機制,它為實現用於存儲資源管理的塊設備驅動提供了一個高度模塊化的內核架構
3.1.2、設置阿里雲鏡像源並重建元數據庫
1 [root@server1 yum.repos.d]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
2
3 [root@server1 yum.repos.d]# yum clean all
4
5 [root@server1 yum.repos.d]# yum makecache
3.1.3、安裝docker-ce並設置環境
1 [root@server1 yum.repos.d]# systemctl stop firewalld.service
2 [root@server1 yum.repos.d]# setenforce 0
3 [root@server1 yum.repos.d]# yum -y install docker-ce
4 [root@server1 yum.repos.d]# systemctl start docker.service
5 [root@server1 yum.repos.d]# systemctl enable docker.service
3.1.4、網絡優化
1 [root@server1 yum.repos.d]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf #開啟路由功能
2 [root@server1 yum.repos.d]# sysctl -p #配置生效
3 net.ipv4.ip_forward = 1
4 [root@server1 yum.repos.d]# systemctl restart network
5 [root@server1 yum.repos.d]# systemctl restart docker
3.1.5、鏡像加速(到阿里雲鏡像加速尋找自己的加速器,具體操作查看Docker基本操作)
1 [root@server1 yum.repos.d]# tee /etc/docker/daemon.json <<-'EOF'
2 > { 3 > "registry-mirrors": ["https://......"] 4 > } 5 > EOF 6
7 [root@server1 yum.repos.d]# systemctl daemon-reload 8 [root@server1 yum.repos.d]# systemctl restart docker
3.2、server1上安裝Compose
1 上傳docker-compose到/root目錄下 2
3 將docker-compose移動到/usr/local/bin 4 [root@server1 ~]# cp -p docker-compose /usr/local/bin/
5 [root@server1 ~]# chmod +x /usr/local/bin/docker-compose 6 [root@server1 ~]# mkdir compose 7
8 將需要的文件放入compose目錄內 9 [root@server1 compose]# yum -y install tree 10 [root@server1 compose]# tree ./
11 ./
12 ├── docker-compose.yml #創建模板腳本 13 └── nginx #nginx目錄 14 ├── Dockerfile #復制容器腳本 15 ├── nginx-1.12.2.tar.gz #復制源碼包 16 └── run.sh #啟動服務腳本 17
18 [root@server1 compose]# vim docker-compose.yml 19 version: '3'
20 services: 21 nginx: 22 hostname: nginx 23 build: 24 context: ./nginx 25 dockerfile: Dockerfile 26 ports: 27 - 2222:80
28 - 3333:443
29 networks: 30 - xuhao 31 volumes: 32 - ./wwwroot:/usr/local/nginx/html 33 networks: 34 xuhao: 35
36 查看docker-compose版本 37 [root@server1 compose]# docker-compose -v 38 docker-compose version 1.21.1, build 5a3f1a3 39
40 發布服務 41 [root@server1 compose]# docker-compose -f docker-compose.yml up -d 42
43 [root@server1 compose]# docker ps -a 44 CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 45 83df4fbe0ec7 compose_nginx "/run.sh" 7 seconds ago Up 6 seconds tcp, 0.0.0.0:3333->443/tcp compose_nginx_1 46
47 [root@server1 compose]# tree ./
48 ./
49 ├── docker-compose.yml 50 ├── nginx 51 │ ├── Dockerfile 52 │ ├── nginx-1.12.2.tar.gz 53 │ └── run.sh
54 └── wwwroot #發布后會創建一個wwwroot目錄 55
56 在wwwroot目錄下創建一個網頁 57 [root@server1 compose]# cd wwwroot/
58 [root@server1 wwwroot]# echo '<h1>docker-compose!!</h1>' > index.html 59 [root@server1 wwwroot]# cat index.html 60 <h1>docker-compose!!</h1>
測試
3.3、在server1上安裝consul
1 上傳consul_0.9.2_linux_amd64.zip到/root目錄下 2
3 [root@server1 ~]# mkdir consul 4 [root@server1 ~]# cp consul_0.9.2_linux_amd64.zip /root/consul 5 [root@server1 ~]# cd consul/
6 [root@server1 consul]# unzip consul_0.9.2_linux_amd64.zip
7 Archive: consul_0.9.2_linux_amd64.zip
8 inflating: consul 9 [root@server1 consul]# ll 10 總用量 51772
11 -rwxr-xr-x. 1 root root 42777946 8月 10 2017 consul 12 -rw-r--r--. 1 root root 10233177 11月 30 15:54 consul_0.9.2_linux_amd64.zip
13
14 將consul移動到/usr/local/bin 15 [root@server1 consul]# mv consul /usr/local/bin/
16 [root@server1 consul]# consul agent \ #使用代理功能 17 > -server \ 18 > -bootstrap \ #參與選舉為領袖 19 > -ui \ 20 > -data-dir=/var/lib/consul-data \ #數據文件存放位置 21 > -bind=20.0.0.10 \ #監聽地址 22 > -client=0.0.0.0 \ #所有網段 23 > -node=consul-server01 &> /var/log/consul.log &
24 [1] 90519
25
26 [root@server1 consul]# jobs #查看后台運行情況 27 [1]+ 運行中 consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=20.0.0.10 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &
28
29 [root@server1 consul]# consul members #查看集群信息 30 Node Address Status Type Build Protocol DC 31 consul-server01 20.0.0.10:8301 alive server 0.9.2 2 dc1
1 [root@server1 consul]# consul info | grep leader 2 leader = true
3 leader_addr = 20.0.0.10:8300
4
5 進入容器 6 [root@server1 consul]# docker exec -it 83df4fbe0ec7 /bin/bash 7
8 安裝tools工具 9 [root@nginx nginx-1.12.2]# yum -y install net-tools 10
11 查看網絡狀態 12 [root@nginx nginx-1.12.2]# ifconfig
13 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
14 inet 172.18.0.2 netmask 255.255.0.0 broadcast 172.18.255.255 #使用compose時,地址是172.18.0.2,因為docker-compose.yml重新定義了network
15 ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet) 16 RX packets 235 bytes 327727 (320.0 KiB) 17 RX errors 0 dropped 0 overruns 0 frame 0
18 TX packets 169 bytes 9587 (9.3 KiB) 19 TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
通過httpd api 獲取集群信息
1 查看集群server成員 2 [root@server1 consul]# curl 127.0.0.1:8500/v1/status/peers 3 集群Raf leader 4 [root@server1 consul]# curl 127.0.0.1:8500/vi/status/leader 5 注冊的所有服務 6 [root@server1 consul]# curl 127.0.0.1:8500/vi/catalog/services 7 查看nginx服務信息 8 [root@server1 consul]# curl 127.0.0.1:8500/vi/catalog/nginx 9 集群節點詳細信息 10 [root@server1 consul]# curl 127.0.0.1:8500/vi/catalog/nodes
3.5、在server2上安裝Gliderlabs/Registrator
1 安裝registrator 2 [root@server2 ~]# docker run -d \ 3 > --name=registrator \ #容器名稱 4 > --net=host \ #指定網絡 5 > -v /var/run/docker.sock:/tmp/docker.sock \ #掛載 6 > --restart=always \ 7 > gliderlabs/registrator:latest \ #鏡像名稱 8 > -ip=20.0.0.20 \ 9 > consul://20.0.0.10:8500
10
11 查看鏡像 12 [root@server2 ~]# docker images 13 REPOSITORY TAG IMAGE ID CREATED SIZE 14 gliderlabs/registrator latest 3b59190c6c80 4 years ago 23.8MB 15
16 查看容器 17 [root@server2 ~]# docker ps -a 18 \CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 19 928b8c8580ad gliderlabs/registrator:latest "/bin/registrator -i…" About a minute ago Up About a minute registrator
網頁登錄http://20.0.0.10:8500,查看節點服務狀態
3.6、在server2上安裝兩個httpd及nginx容器
1 [root@server2 ~]# docker run -dit -p 83:80 --name test1 -h test1 nginx 2 [root@server2 ~]# docker run -dit -p 84:80 --name test1 -h test2 nginx 3 [root@server2 ~]# docker run -dit -p 88:80 --name test3 -h test3 httpd 4 [root@server2 ~]# docker run -dit -p 89:80 --name test4 -h test4 httpd 5
6 查看容器狀態 7 [root@server2 ~]# docker ps -a 8 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9 178332ffa010 httpd "httpd-foreground" 6 seconds ago Up 4 seconds 0.0.0.0:89->80/tcp test4 10 140f0c57c15a httpd "httpd-foreground" 47 seconds ago Up 46 seconds 0.0.0.0:88->80/tcp test3 11 37b796ddca46 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:84->80/tcp test2 12 f47a5aaf1e4d nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:83->80/tcp test1
網頁登錄http://20.0.0.10:8500,查看節點服務狀態
將兩個nginx服務移除查看,網頁監控服務也被移除
1 [root@server2 ~]# docker stop 37b796ddca46 2 37b796ddca46 3 [root@server2 ~]# docker rm 37b796ddca46 4 37b796ddca46 5 [root@server2 ~]# docker stop f47a5aaf1e4d 6 f47a5aaf1e4d 7 [root@server2 ~]# docker rm f47a5aaf1e4d 8 f47a5aaf1e4d 9 [root@server2 ~]# docker ps -a 10 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11 178332ffa010 httpd "httpd-foreground" 5 minutes ago Up 5 minutes 0.0.0.0:89->80/tcp test4 12 140f0c57c15a httpd "httpd-foreground" 6 minutes ago Up 6 minutes 0.0.0.0:88->80/tcp test3
3.7、在server1上安裝consul-template
consul-template是一個守護進程,用於實時查詢consul集群信息,並更新文件系統上任意數量的指定模板,生成配置文件,更新完成以后,可以選擇運行shell命令執行更新操作,重新加載Nginx。consul-template可以查詢consul中的服務目錄、Key、Key-values等。這種強大的抽象功能和查詢語言模板可以使consul-template特別適合動態的創建配置文件
1 准備template nginx 模板文件 2 [root@server1 consul]# vim nginx.ctmpl 3 upstream http_backend { 4 {{range service "nginx"}} 5 server {{.Address}}:{{.Port}}; 6 {{end}} 7 } 8
9 server { 10 listen 83; 11 server_name localhost 20.0.0.10; 12 access_log /var/log/nginx/aa-access.log; 13 index index.html index.php; 14 location / { 15 proxy_set_header HOST $host; 16 proxy_set_header X-Real-IP $remote_addr; 17 proxy_set_header Client-IP $remote_addr; 18 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 19 proxy_pass http://http_backend;
20 } 21 } 22
23 編譯安裝nginx(將nginx上傳到/root目錄下) 24 [root@server1 consul]# yum -y install gcc gcc-c++ make pcre-devel zlib-devel 25 [root@server1 ~]# tar zxvf nginx-1.12.2.tar.gz -C /opt 26 [root@server1 ~]# cd /opt/nginx-1.12.2/
27 [root@server1 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx 28 [root@server1 nginx-1.12.2]# make && make install
29
30 配置nginx 31 [root@server1 nginx-1.12.2]# vim /usr/local/nginx/conf/nginx.conf 32 http { 33 include mime.types; 34 include vhost/*.conf; #添加虛擬主機目錄 35 default_type application/octet-stream; 36
37 創建虛擬主機目錄 38 [root@server1 nginx-1.12.2]# mkdir /usr/local/nginx/conf/vhost 39
40 創建日志文件目錄 41 [root@server1 nginx-1.12.2]# mkdir /var/log/nginx 42
43 啟動nginx並查看端口 44 [root@server1 nginx-1.12.2]# /usr/local/nginx/sbin/nginx 45 [root@server1 nginx-1.12.2]# netstat -anpt | grep nginx 46 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 69573/nginx: master 47
48 配置並啟動template(上傳template到/root目錄下) 49 [root@server1 ~]# unzip consul-template_0.19.3_linux_amd64.zip #解壓縮 50 Archive: consul-template_0.19.3_linux_amd64.zip 51 inflating: consul-template 52 [root@server1 ~]# mv consul-template /usr/local/bin #移動 53 [root@server1 ~]# consul-template -consul-addr 20.0.0.10:8500 -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/xh.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info 54
55 再開一個server1終端查看 56 [root@server1 ~]# cd /usr/local/nginx/conf/vhost/ 57 [root@server1 vhost]# cat xh.conf 58 upstream http_backend { 59
60 server 20.0.0.20:83; #會自動識別並添加,等會將容器服務關閉后查看 61
62 } 63
64 server { 65 listen 83; 66 server_name localhost 20.0.0.10; 67 access_log /var/log/nginx/aa-access.log; 68 index index.html index.php; 69 location / { 70 proxy_set_header HOST $host; 71 proxy_set_header X-Real-IP $remote_addr; 72 proxy_set_header Client-IP $remote_addr; 73 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 74 proxy_pass http://http_backend; 75 } 76 }
網頁訪問然后查看日志
1 server2上再啟動一個nginx服務容器 2 [root@server2 ~]# docker run -dit -p 89:80 --name test6 -h test6 nginx 3 [root@server2 ~]# docker run -dit -p 88:80 --name test6 -h test6 nginx
4 在server1上查看 5 [root@server1 vhost]# cat xh.conf 6 upstream http_backend { 7
8 server 20.0.0.20:83; 9
10 server 20.0.0.20:88; 11
12 server 20.0.0.20:89; #節點自動添加 13
14 } 15
16 server { 17 listen 83; 18 server_name localhost 20.0.0.10; 19 access_log /var/log/nginx/aa-access.log; 20 index index.html index.php; 21 location / { 22 proxy_set_header HOST $host; 23 proxy_set_header X-Real-IP $remote_addr; 24 proxy_set_header Client-IP $remote_addr; 25 proxy_set_header X-Fprwarded-For $proxy_add_x_forwarded_for; 26 proxy_pass http://http_backend;
27 } 28 } 29
30 在server2上查看日志(訪問20.0.0.10可以訪問后面的節點) 31 [root@server2 ~]# docker logs -f test5 32 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration 33 /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
34 /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
35 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf 36 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf 37 /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
38 /docker-entrypoint.sh: Configuration complete; ready for start up 39 20.0.0.10 - - [01/Dec/2020:05:45:42 +0000] "GET / HTTP/1.0" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47" "-"
40
41 [root@server2 ~]# docker logs -f test6 42 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration 43 /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
44 /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
45 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf 46 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf 47 /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
48 /docker-entrypoint.sh: Configuration complete; ready for start up 49 20.0.0.10 - - [01/Dec/2020:05:48:53 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47" "-"
刪除一個容器查看能否自動移除
1 刪除容器 2 [root@server2 ~]# docker stop 601bce2a82e6 3 601bce2a82e6 4 [root@server2 ~]# docker rm 601bce2a82e6 5 601bce2a82e6 6
7 查看會發現節點自動移除 8 [root@server1 vhost]# cat xh.conf 9 upstream http_backend { 10
11 server 20.0.0.20:83; 12
13 server 20.0.0.20:88; 14
15 } 16
17 server { 18 listen 83; 19 server_name localhost 20.0.0.10; 20 access_log /var/log/nginx/aa-access.log; 21 index index.html index.php; 22 location / { 23 proxy_set_header HOST $host; 24 proxy_set_header X-Real-IP $remote_addr; 25 proxy_set_header Client-IP $remote_addr; 26 proxy_set_header X-Fprwarded-For $proxy_add_x_forwarded_for; 27 proxy_pass http://http_backend;
28 } 29 }
3.8、consul多節點
1 上傳consul壓縮包到server3上 2
3 解壓縮 4 [root@server3 ~]# unzip consul_0.9.2_linux_amd64.zip
5 Archive: consul_0.9.2_linux_amd64.zip
6 inflating: consul 7 [root@server3 ~]# mv consul /usr/local/bin/
8
9 加入已有的群集中 10 [root@server3 ~]# consul agent \ 11 > -bootstrap \ 12 > -ui \ 13 > -data-dir=/var/lib/consul-data \ 14 > -server \ 15 > -bind=20.0.0.30 \ 16 > -client=0.0.0.0 \ 17 > -node=consul-server3 \ 18 > -enable-script-checks=true \ 19 > -datacenter=dc1 \ 20 > join 20.0.0.10 &> /var/log/consul.log &
21 [1] 17753
22
23 查看運行狀態 24 [root@server3 ~]# jobs 25 [1]+ 運行中 consul agent -bootstrap -ui -data-dir=/var/lib/consul-data -server -bind=20.0.0.30 -client=0.0.0.0 -node=consul-server3 -enable-script-checks=true -datacenter=dc1 join 20.0.0.10 &>/var/log/consul.log &