搭建多数据中心的基于Nginx和Consul构建自动发现的Docker服务框架
文章目录
consul安装包:https://releases.hashicorp.com/consul/1.13.2/consul_1.13.2_linux_amd64.zip
consul-template安装包:https://releases.hashicorp.com/consul-template/0.28.1/consul-template_0.28.1_linux_amd64.zip
consul安装包:https://releases.hashicorp.com/consul/1.13.2/consul_1.13.2_linux_amd64.zip
consul-template安装包:https://releases.hashicorp.com/consul-template/0.28.1/consul-template_0.28.1_linux_amd64.zip
环境准备:
此次使用是部署多数据中心consul分布式架构
主机 | 主机IP | 安装工具 |
---|---|---|
consul-server01服务器 | 192.168.18.130 | Consul、Consul-template模板 |
consul-server02服务器 | 192.168.18.111 | Consul、Consul-template模板 |
consul-clinet01服务器 | 192.168.18.112 | Consul、Consul-template模板 |
容器服务器 | 192.168.18.102 | Docker、registrator、nginx服务 |
理解:
1、首先,这个架构使用Docker容器运行服务。Docker是一种轻量级的容器化技术,可以使应用程序及其依赖项在独立的容器中运行,这使得它们更易于部署和管理。在这个架构中,我们将多个Docker容器运行相同的服务,以实现服务的高可用和负载均衡。
2、其次,这个架构使用Consul来实现服务发现和服务注册。Consul是一个开源的服务发现和配置工具,它允许我们自动发现和注册Docker容器中运行的服务。当一个Docker容器启动时,它会向Consul注册自己所提供的服务。其他服务可以通过Consul查询服务的位置和相关信息,从而找到并访问它们所需的服务。
3、最后,这个架构使用Nginx来实现负载均衡。Nginx是一种高性能的Web服务器和反向代理服务器,它可以根据负载均衡算法将请求分配给不同的Docker容器,从而实现服务的负载均衡。Nginx使用Consul服务发现来自动更新其配置文件,并根据配置文件中的服务列表将请求路由到可用的Docker容器上。
这个架构的整个工作流程如下:
- Docker容器启动后,向Consul注册自己提供的服务。
- 其他服务可以通过Consul查询服务的位置和相关信息,从而找到并访问它们所需的服务。
- Nginx使用Consul服务发现自动更新其配置文件,以反映当前可用的Docker容器列表。
- 当请求到达Nginx时,Nginx根据其负载均衡算法将请求分配给一个可用的Docker容器。
- Docker容器处理请求并返回响应。
架构图:
所有consul服务器都必须有
mkdir /root/consul
cd /root/consul
mv /root/consul_0.9.2_linux_amd64.zip ~/consul
unzip consul_0.9.2_linux_amd64.zip 解压zip安装包,无法使用unzip命令(yum install -y unzip)
mv consul /usr/bin #使得全局可使用此命令工具
Ⅰ:多节点集群机器方式部署
一、部署:
1、运行Agent
①、创建consul-server01
在consul-server01创建server
consul agent -server -bootstrap-expect=2 -data-dir=/var/lib/consul-data -bind=192.168.18.130 -client=0.0.0.0 -node=consul-server01 -datacenter=zhaoqing -ui &> /var/log/consul.log &
命令解释:
consul agent -server #定义本机运行模式为server
-bootstrap
-ui #可视化界面
-datacenter=zhaoqing #数据中心名称
-data-dir=/var/lib/consul-data #指定数据存储目录
-bind=192.168.18.125 #监听自己 #用于集群内部通信
-client=0.0.0.0 #监听所有地址
-node=consul-server01 #节点在集群中的名称
&> /var/log/consul.log & #放入后台运行
②、创建consul-server02
在consul-server02创建server
consul agent -server -bootstrap-expect=2 -data-dir=/var/lib/consul-data -bind=192.168.18.111 -client=0.0.0.0 -node=consul-server02 -datacenter=zhaoqing -ui &> /var/log/consul.log &
③、创建consul-clinet
consul agent -data-dir=/var/lib/consul-data \ #指定 Consul Agent 的数据目录
-node=consul-client01 -bind=192.168.18.112 \
-enable-script-checks=true \ #开启 Consul Agent 的脚本检查功能
-config-dir=/var/lib/consul-data \ #指定 Consul Agent 的配置目录
-datacenter=zhaoqing \
-client 0.0.0.0 -ui &> /var/log/consul.log &
此时consul集群还不能提供服务,因为还没选举管理者
④、加入consul集群
在consul-server02和consul-clinet执行
consul join 192.168.18.130
⑤、验证consul服务
打开http://192.168.18.130:8500
⑥、简单集群参数get/set测试
在consul-server01进行set:
consul kv put addr cwc
在另外三个agent上进行get:
consul kv get addr
都可以得到key的值cwc,则证明集群已经同步
查看集群状态:
[root@docker_project consul-data]# consul operator raft list-peers
Node ID Address State Voter RaftProtocol
consul-server01 529a4e25-572b-491e-91b6-9d23d5e942fa 192.168.18.130:8300 leader true 3
consul-server02 0ce706fe-734d-d24c-cc81-b07eb9c5dcf0 192.168.18.111:8300 follower true 3
[root@docker_project consul-data]# consul members
Node Address Status Type Build Protocol DC Partition Segment
consul-server01 192.168.18.130:8301 alive server 1.13.2 2 zhaoqing default <all>
consul-server02 192.168.18.111:8301 alive server 1.13.2 2 zhaoqing default <all>
consul-client01 192.168.18.112:8301 alive client 1.13.2 2 zhaoqing default <default>
2、搭建registrator
在发布服务的机器上进行
192.168.18.102
,
①、运行注册机
此工具可检查容器运行状态,自动注册和注销docker容器的服务到服务配置中心,服务注册到192.168.18.112
docker run -d --name=registrator --net=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest -ip=192.168.18.102 consul://192.168.18.112:8500
命令解释:
docker run -d
--name=registrator #容器名
--net=host #网络模式
-v /var/run/docker.sock:/tmp/docker.sock
--restart=always
gliderlabs/registrator:latest #镜像名
-ip=192.168.18.102 #自己的IP
consul://192.168.18.112:8500 #指向consul服务器
②、安装consul-template
在节点
192.168.18.112
进行
vim /root/consul/nginx.ctmpl
准备模板文件
upstream httpd_back { #地址池
{{range service "nginx"}}
server {{.Address}}:{{.Port}};
{{end}}
}
server { #代理服务
listen 88;
server_name localhost 192.168.18.112; #本机IP
access_log /var/log/nginx/nginx.cn-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://httpd_back;
}
}
关联虚拟主机配置文件
vim /etc/nginx/nginx.conf
配置并启动
unzip consul-template_0.19.3_linux_amd64.zip
mv consul-template /usr/bin
启动nginx服务:nginx
consul-template -consul-addr 192.168.18.112:8500 -template "/root/consul/nginx.ctmpl:/etc/nginx/vhost/cwc.conf:/usr/sbin/nginx -s reload" --log-level=info
命令解释:
consul-template -consul-addr 192.168.18.112:8500
-template
"/root/consul/nginx.ctmpl: #模板文件路径
/etc/nginx/vhost/cwc.conf: #生成路径
/usr/sbin/nginx -s reload" #主机nginx启动命令路径 -s relpad 重启
--log-level=info #linux日志级别
③、注册发现服务
在安装了注册机registrator容器的机器
192.168.18.102
进行创建服务,即可被发现,通过docker创建nginx服务,并且暴露端口到宿主机上才能被发现。
命令: docker run -itd --name text -P nginx bash
成功被发现。
同时,根据192.168.18.112的启动的consul-template自动生成nginx配置文件,可通过访问http://192.168.18.112:88
这里使用的nginx服务就是192.168.18.102
的docker容器发布的nginx服务
二、Consul 多数据中心配置
由于资源有限,我将
192.168.18.102
作为另外一个数据中心的agent使用,搭建zhangjiang数据中心
①、创建zhangjiang-server
consul agent -server -bootstrap-expect 1 -data-dir=/var/lib/consul-data -node consul-server01 -bind=192.168.18.102 -client=0.0.0.0 -datacenter zhangjiang -ui &> /var/log/consul.log &
②、加入zhaoqing数据中心
[root@k8s-node01 ~]# consul join -wan 192.168.18.130
③、验证
查询当前集群下拥有的datacenter信息:
[root@k8s-node01 ~]# consul members -wan
Node Address Status Type Build Protocol DC Partition Segment
consul-server01.zhangjiang 192.168.18.102:8302 alive server 1.13.2 2 zhangjiang default <all>
consul-server01.zhaoqing 192.168.18.130:8302 alive server 1.13.2 2 zhaoqing default <all>
consul-server02.zhaoqing 192.168.18.111:8302 alive server 1.13.2 2 zhaoqing default <all>http://192.18.18.130:8500
访问http://192.18.18.130:8500,在ui界面也可以看到两个数据中心,即配置成功。
-------------------------补充---------------------------
报错记录:
Consul注册中心删除某个服务
curl --request PUT http://127.0.0.1:8500/v1/agent/service/deregister/微服务ID
通过 http api 获取集群信息
查看集群server成员 curl 127.0.0.1:8500/v1/status/peers
集群Raf leader curl 127.0.0.1:8500/v1/status/leader
注册的所有服务 curl 127.0.0.1:8500/v1/catalog/services
查看nginx服务信息 curl 127.0.0.1:8500/v1/catalog/nginx
集群节点详细信息 curl 127.0.0.1:8500/v1/catalog/nodes
nginx启动端口被占用(把占用的端口进程kill掉)
fuser -n tcp 80
nginx容器内80端口被占用
在主机输入netstat -tanlp
查看端口
将该容器pid杀死,重启容器
启动consul-template时:
nginx: [emerg] no servers are inside upstream in /etc/nginx/vhost/cwc.conf:3
2022-09-29T00:00:14.779-0700 [ERR] (cli) 1 error occurred:
* failed to execute command "[\"/usr/sbin/nginx -s reload\"]" from "/root/consul/nginx.ctmpl" => "/etc/nginx/vhost/cwc.conf": child: command exited with a non-zero exit status:
sh -c /usr/sbin/nginx -s reload
解决:
删除cwc.conf文件,重新执行该命令,需确保有服务存在才能被发现,无服务会自动报错
-------------------更新于2023年08月13日-------------------
Ⅱ:docker容器部署方式
1、安装docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
docker version
2、安装docker-compose
去官网拉取
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.5.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
3、创建目录
mkdir -pv /data/consul/server{1,2,3,-shenzhen}
# 目录结构
[root@localhost data]# ll /data/consul/*/*
-rw-r--r-- 1 root root 207 Jul 23 13:55 /data/consul/server1/server1.json
-rw-r--r-- 1 root root 243 Jul 23 13:56 /data/consul/server2/server2.json
-rw-r--r-- 1 root root 243 Jul 23 13:56 /data/consul/server3/server3.json
-rw-r--r-- 1 root root 249 Jul 23 13:56 /data/consul/server-shenzhen/server-shenzhen.json
4、编写配置文件
①、docker-compose.yml
vim /data/consul/docker-compose.yml
version: '3'
services:
consul-server1:
image: consul
container_name: consul-server1
command: consul agent -server -bootstrap-expect=3 -config-file=/consul/config/server1.json
ports:
- "8500:8500"
- "8300:8300"
- "8301:8301"
- "8301:8301/udp"
- "8302:8302"
- "8302:8302/udp"
- "8600:8600"
- "8600:8600/udp"
volumes:
- "/data/consul/server1:/consul/data"
- "/data/consul/server1/server1.json:/consul/config/server1.json"
consul-server2:
image: consul
container_name: consul-server2
command: consul agent -server -bootstrap-expect=3 -config-file=/consul/config/server2.json
ports:
- "8501:8500"
- "8303:8300"
- "8304:8301"
- "8304:8301/udp"
- "8305:8302"
- "8305:8302/udp"
- "8601:8600"
- "8601:8600/udp"
volumes:
- "/data/consul/server2:/consul/data"
- "/data/consul/server2/server2.json:/consul/config/server2.json"
depends_on:
- consul-server1
consul-server3:
image: consul
container_name: consul-server3
command: consul agent -server -bootstrap-expect=3 -config-file=/consul/config/server3.json
ports:
- "8502:8500"
- "8306:8300"
- "8307:8301"
- "8307:8301/udp"
- "8308:8302"
- "8308:8302/udp"
- "8602:8600"
- "8602:8600/udp"
volumes:
- "/data/consul/server3:/consul/data"
- "/data/consul/server3/server3.json:/consul/config/server3.json"
depends_on:
- consul-server1
- consul-server2
consul-server-shenzhen:
image: consul
container_name: consul-server-shenzhen
command: consul agent -server -bootstrap-expect=1 -config-file=/consul/config/server-shenzhen.json
ports:
- "8503:8500"
- "8309:8300"
- "8310:8301"
- "8310:8301/udp"
- "8311:8302"
- "8311:8302/udp"
- "8603:8600"
- "8603:8600/udp"
volumes:
- "/data/consul/server-shenzhen:/consul/data"
- "/data/consul/server-shenzhen/server-shenzhen.json:/consul/config/server-shenzhen.json"
depends_on:
- consul-server1
- consul-server2
- consul-server3
registrator:
image: gliderlabs/registrator
container_name: registrator
command: consul://consul-server1:8500
volumes:
- "/var/run/docker.sock:/tmp/docker.sock"
depends_on:
- consul-server1
- consul-server2
- consul-server3
- consul-server-shenzhen
②、server1.json
{
"server": true,
"datacenter": "guangzhou",
"node_name": "consul-server1",
"bind_addr": "0.0.0.0",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"ui": true,
"client_addr": "0.0.0.0"
}
③、server2.json
{
"server": true,
"datacenter": "guangzhou",
"node_name": "consul-server2",
"bind_addr": "0.0.0.0",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"ui": true,
"client_addr": "0.0.0.0",
"retry_join": ["consul-server1"]
}
④、server3.json
{
"server": true,
"datacenter": "guangzhou",
"node_name": "consul-server3",
"bind_addr": "0.0.0.0",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"ui": true,
"client_addr": "0.0.0.0",
"retry_join": ["consul-server1"]
}
⑤、server-shenzhen.json
{
"server": true,
"datacenter": "shenzhen",
"node_name": "consul-server-shenzhen",
"bind_addr": "0.0.0.0",
"bootstrap_expect": 1,
"data_dir": "/consul/data",
"ui": true,
"client_addr": "0.0.0.0",
"retry_join_wan": ["consul-server1"]
}
4、启动
在/data/consul/目录运行
docker-compose up -d
5、验证
访问http://192.168.1.214:8500
5.1、guangzhou数据中心
5.2、shenzhen数据中心
5.3、发现服务
docker启动一个nginx服务,暴露端口为32771(nginx容器必须暴露端口,否则无法发现服务)
查看consul,成功发现nginx服务