前言
Docker Compose 则进一步简化了多个容器应用的编排与管理。另一方面,Consul 作为一款先进的服务发现工具,为分布式和微服务架构提供了可靠的服务注册与发现机制。本文将探讨 Docker Compose 和 Consul 在容器化环境中的协同作用,以及它们如何共同帮助开发人员更高效地构建、部署和管理其应用程序。
Docker Compose相关介绍请参考:
Docker-Compose单机多容器应用编排与管理-CSDN博客
目录
一、概述
1. 服务注册与发现
consul-toc" style="margin-left:40px;">2. 什么是 consul
3. 服务架构
3.1 传统架构
consul%20%E6%9E%B6%E6%9E%84-toc" style="margin-left:80px;">3.2 consul 架构
4. 关键特性
二、Consul 部署
1. 容器服务更新与发现拓扑图
2. 部署信息
consul%20%E6%9C%8D%E5%8A%A1%E5%99%A8-toc" style="margin-left:40px;">3. consul 服务器
consul%20%E6%9C%8D%E5%8A%A1-toc" style="margin-left:80px;">3.1 建立 consul 服务
3.2 查看集群信息
3.3 通过 http api 获取集群信息
4. registrator 服务器
4.1 安装 Gliderlabs/Registrato
4.2 测试服务发现功能是否正常
consul%C2%A0-toc" style="margin-left:80px;">4.3 验证 http 和 nginx 服务是否注册到 consul
consul-template%C2%A0-toc" style="margin-left:40px;">5. consul-template
5.1 准备 template nginx 模板文件
5.2 安装配置 nginx 服务
5.3 配置并启动 template
5.4 访问 template-nginx
5.5 增加一个 nginx 容器节点
consul%20%E5%A4%9A%E8%8A%82%E7%82%B9-toc" style="margin-left:40px;">6. consul 多节点
docker%C2%A0-toc" style="margin-left:80px;">6.1 安装 docker
consul%20%E7%9B%B8%E5%85%B3%E6%9C%8D%E5%8A%A1%E6%96%87%E4%BB%B6%EF%BC%8C%E5%90%AF%E5%8A%A8%20consul%20%E6%9C%8D%E5%8A%A1-toc" style="margin-left:80px;">6.2 拷贝 consul 相关服务文件,启动 consul 服务
6.3 查看集群信息
一、概述
1. 服务注册与发现
① 服务注册:在Docker中运行的应用程序可以通过Consul客户端向Consul服务注册自己的信息,包括服务名称、IP地址、端口号等。这样,Consul就会维护一个服务目录,记录着所有可用的服务实例及其位置信息。
② 服务发现:其他Docker容器或应用程序可以通过Consul客户端查询Consul服务注册中心,动态地发现和连接到需要的服务。Consul根据服务名称、标签、健康状态等条件来选择合适的服务实例,实现服务间的通信和协作。
consul">2. 什么是 consul
Consul 是一种开源的服务发现和配置管理工具,由 HashiCorp 开发。它提供了一系列功能,包括服务注册、服务发现、健康检查、KV存储等,旨在简化构建和管理分布式系统的过程。
① 服务注册与发现:Consul 允许服务实例向 Consul 注册其信息,包括服务名称、网络位置(IP地址和端口号)、健康状态等。其他服务或客户端可以通过 Consul 查询服务注册中心,动态地发现和连接到需要的服务,从而实现服务间的通信。
② 健康检查:Consul 可以定期对服务实例进行健康检查,以确保服务的可用性。如果一个服务实例不健康,Consul 会将其标记为不可用,同时通知其他服务实例进行相应的调整,保证系统的稳定性。
③ KV 存储:Consul 提供了一个分布式的键值存储系统,允许用户存储和检索配置信息、应用程序状态等。这个功能对于动态配置和共享状态在分布式系统中是非常有用的。
④ 多数据中心支持:Consul 支持多数据中心部署,可以轻松地在不同地理位置的数据中心中管理和发现服务,提高系统的可用性和容错性。
3. 服务架构
3.1 传统架构
在 upstream 块中,需要指定后端服务器的 IP 地址和端口号,即 ip:port;在proxy_pass指令中,需要指定转发请求的目标;
当需要添加新的后端服务器时,需要修改代理端配置文件,且需要重启服务才可以生效,有一定的局限性。
consul%20%E6%9E%B6%E6%9E%84" style="background-color:transparent;">3.2 consul 架构
后端服务 A-N 可以把当前自己的网络位置注册到服务发现模块,服务发现就以 K-V 的方式记录下来,K 一般是服务名,V 就是 ip:port。服务发现模块定时的进行健康检查,轮询查看这些后端服务能不能访问的了。前端在调用后端服务 A-N 的时候,会先询问服务发现模块后端服务的网络位置,然后再调用它们的服务。
4. 关键特性
- 服务注册与发现:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册;
- 健康检查:健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面;
- Key/Value存储:一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
- 多数据中心:无需复杂的配置,即可支持任意数量的区域。
二、Consul 部署
1. 容器服务更新与发现拓扑图
Consul Template
- Consul Template守护进程是Consul Template工具的一部分,用于监视Consul中的键值存储(KV)中的变化,并根据这些变化来更新本地的配置文件。它可以在后台运行,并定期检查Consul中的数据,以确保生成的配置文件与最新的配置信息保持同步;
- 是一个配置文件模板,可以获取注册中心所有的服务发现,然后将服务发现的名称:端口号转发给 Nginx,并且更新 nginx.conf 文件。
Consul Server
- 作为注册中心,Consul Server 负责维护服务目录,记录当前可用的服务实例及其位置信息;
- 负责执行健康检查来确保服务的可用性,定期检查服务实例的健康状态,如果某个服务实例出现故障或不可用,Consul会将其标记为不健康,并从服务目录中移除;同时服务实例新增或者恢复,Consul会将其加入到服务目录中;
- 提供了KV存储,用于存储配置信息、应用程序状态等。这个分布式键值存储可以用于共享配置、动态更新应用程序参数等场景;
- 支持事件处理机制,可以发布和订阅各种事件,例如服务状态变更、健康检查结果等。
Consul Agent
- 是一个轻量级的代理程序,用于运行在每个部署了服务的节点上。它负责与Consul集群通信,并执行各种任务,包括服务注册、健康检查、服务发现和处理来自其他节点的RPC请求等。
Registrator
- 是一个服务注册器,它是一个独立的进程,运行在容器编排环境中;它的主要作用是监视运行中的服务实例,并将它们注册到服务发现系统中,例如Consul或etcd。通过这种注册,其他服务可以发现并与这些服务进行通信,而无需事先知道它们的位置或IP地址。
2. 部署信息
服务节点 | ip | 安装运行服务 | docker版本 |
consul 服务器 | 192.168.190.107 | 运行consul服务、nginx服务、consul-template守护进程 | 26.0.2 |
registrator 服务器 | 192.168.190.108 | 运行registrator容器、运行nginx容器 | 20.10.17 |
consul 服务器 | 192.168.190.106 | 运行consul服务 | 26.0.2 |
consul%20%E6%9C%8D%E5%8A%A1%E5%99%A8" style="background-color:transparent;">3. consul 服务器
consul%20%E6%9C%8D%E5%8A%A1" style="background-color:transparent;">3.1 建立 consul 服务
① 二进制包直接安装
[root@consul ~]# mkdir /opt/consul
[root@consul ~]# cd /opt/consul/
[root@consul consul]# ls
consul_0.9.2_linux_amd64.zip # 准备二进制包
[root@consul consul]# unzip consul_0.9.2_linux_amd64.zip
[root@consul consul]# mv consul /usr/local/bin/
② 设置代理,后台启动 consul 服务端
[root@consul consul]# consul agent \
> -server \
> -bootstrap \
> -ui \
> -data-dir=/var/lib/consul-data \
> -bind=192.168.190.107 \
> -client=0.0.0.0 \
> -node=consul-server01 &> /var/log/consul.log &
[1] 7694
③ 启动 consul 后默认会监听5个端口
[root@consul consul]# netstat -natp | grep consul
tcp 0 0 192.168.190.107:8300 0.0.0.0:* LISTEN 37870/consul
tcp 0 0 192.168.190.107:8301 0.0.0.0:* LISTEN 37870/consul
tcp 0 0 192.168.190.107:8302 0.0.0.0:* LISTEN 37870/consul
tcp6 0 0 :::8500 :::* LISTEN 37870/consul
tcp6 0 0 :::8600 :::* LISTEN 37870/consul
# 8300:replication、leader farwarding的端口
# 8301:lan cossip的端口
# 8302:wan gossip的端口
# 8500:web ui界面的端口
# 8600:使用dns协议查看节点信息的端口
3.2 查看集群信息
① 查看members状态
[root@consul consul]# consul members
Node Address Status Type Build Protocol DC
consul-server01 192.168.190.107:8301 alive server 0.9.2 2 dc1
② 查看集群状态
[root@consul consul]# consul operator raft list-peers # 获取Consul集群中Raft协议的节点列表
Node ID Address State Voter RaftProtocol
consul-server01 192.168.190.107:8300 192.168.190.107:8300 leader true 2
[root@consul consul]# consul info | grep leaderleader = trueleader_addr = 192.168.190.107:8300
3.3 通过 http api 获取集群信息
[root@consul consul]# curl 127.0.0.1:8500/v1/status/peers
["192.168.190.107:8300"]
# 查看集群server成员
[root@consul consul]# curl 127.0.0.1:8500/v1/status/leader
"192.168.190.107:8300"
# 集群 server-leader
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[]}
# 注册的所有服务
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/nginx
# 查看 nginx 服务信息
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/nodes
[{"ID":"f17caaee-ff27-b4e8-c592-afcdad3a2e47","Node":"consul-server01","Address":"192.168.190.107","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.190.107","wan":"192.168.190.107"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}]
# 集群节点详细信息
4. registrator 服务器
4.1 安装 Gliderlabs/Registrato
Gliderlabs/Registrator 可检查容器运行状态自动注册,还可注销 docker 容器的服务到服务配置中心。目前支持 Consul、Etcd 和 SkyDNS2。运行一个 Registrator 容器,开启自动发现服务:
[root@registrator ~]# docker run -d \ # 运行Docker容器并将其设置为后台运行
> --name=registrator \ # 指定名称为"registrator"
> --net=host \ # 使用主机网络模式
> -v /var/run/docker.sock:/tmp/docker.sock \
# 将主机的Docker守护进程的Unix套接字映射到容器内的/tmp/docker.sock,这样Registrator容器就可以与 Docker守护进程通信
> --restart=always \ # 容器遇到错误或意外退出时自动重启
> gliderlabs/registrator:latest \ # 使用镜像gliderlabs/registrator来运行容器,:latest表示使用最新版本的镜像
> --ip=192.168.190.108 \ # 设置Registrator容器的IP地址为192.168.10.13
> consul://192.168.190.107:8500 # 192.168.190.107:8500是Consul的地址和端口
4.2 测试服务发现功能是否正常
[root@registrator ~]# docker run -itd -p:1080:80 --name nginx-01 -h nginx1 nginx
[root@registrator ~]# docker run -itd -p:1081:80 --name nginx-02 -h nginx2 nginx
[root@registrator ~]# docker run -itd -p:1082:80 --name apache-01 -h apache1 httpd
[root@registrator ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3004e92d23e4 httpd "httpd-foreground" 8 seconds ago Up 7 seconds 0.0.0.0:1082->80/tcp, :::1082->80/tcp apache-01
108612e81495 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:1081->80/tcp, :::1081->80/tcp nginx-02
dfbfe87308ed nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:1080->80/tcp, :::1080->80/tcp nginx-01
53166bf2c442 gliderlabs/registrator:latest "/bin/registrator --…" 23 minutes ago Up 23 minutes registrator
# 一个发现服务,两个容器服务
consul%C2%A0">4.3 验证 http 和 nginx 服务是否注册到 consul
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[],"httpd":[],"nginx":[]}
consul-template%C2%A0">5. consul-template
Consul-Template是基于Consul的自动替换配置文件的应用。Consul-Template是一个守护进程,用于实时查询Consul集群信息,并更新文件系统上任意数量的指定模板,生成配置文件。更新完成以后,可以选择运行 shell 命令执行更新操作,重新加载 Nginx。
Consul-Template可以查询Consul中的服务目录、Key、Key-values 等。这种强大的抽象功能和查询语言模板可以使 Consul-Template 特别适合动态的创建配置文件。例如:创建Apache/Nginx Proxy Balancers 、 Haproxy Backends等。
5.1 准备 template nginx 模板文件
在consul服务器上操作:
[root@consul consul]# vim /opt/consul/nginx.ctmpl
upstream http_backend {{{range service "nginx"}}server {{.Address}}:{{.Port}};{{end}}
}
# 定义nginx upstream一个模板server {listen 8000;server_name localhost 192.168.190.107;access_log /var/log/nginx/kgc.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://http_backend;}
}
# 定义一个server,监听8000端口,反向代理到upstream
5.2 安装配置 nginx 服务
在 consul 节点安装:
[root@consul consul]# yum install -y epel-release.noarch
[root@consul consul]# yum install -y nginx
[root@consul consul]# vim /etc/nginx/nginx.conf
http {include vhost/*.conf; # 添加虚拟主机目录创建虚拟主机目录:
[root@consul consul]# cd /etc/nginx/
[root@consul nginx]# mkdir vhost
启动nginx服务:
[root@consul nginx]# systemctl start nginx.service
5.3 配置并启动 template
在 consul 节点操作:
[root@consul opt]# ls
consul-template_0.19.3_linux_amd64.zip # 准备安装包
[root@consul opt]# unzip consul-template_0.19.3_linux_amd64.zip
[root@consul opt]# mv consul-template /usr/local/bin/在前台启动template服务,启动后不要按ctrl+c中止consul-template进程:
consul-template --consul-addr 192.168.190.107:8500 \
--template "/opt/consul/nginx.ctmpl:/etc/nginx/vhost/fqlnginx.conf:/usr/sbin/nginx -s reload" \
--log-level=info另外打开一个终端查看生成配置文件:
[root@consul opt]# cd /etc/nginx/vhost/
[root@consul vhost]# ls
fqlnginx.conf
[root@consul vhost]# cat fqlnginx.conf
upstream http_backend {server 192.168.190.108:1080;server 192.168.190.108:1081;}server {listen 8000;server_name localhost 192.168.190.107;access_log /var/log/nginx/kgc.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://http_backend;}
}
5.4 访问 template-nginx
在 registrator 节点操作:
[root@registrator ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3004e92d23e4 httpd "httpd-foreground" 15 hours ago Up 15 hours 0.0.0.0:1082->80/tcp, :::1082->80/tcp apache-01
108612e81495 nginx "/docker-entrypoint.…" 15 hours ago Up 15 hours 0.0.0.0:1081->80/tcp, :::1081->80/tcp nginx-02
dfbfe87308ed nginx "/docker-entrypoint.…" 15 hours ago Up 15 hours 0.0.0.0:1080->80/tcp, :::1080->80/tcp nginx-01
53166bf2c442 gliderlabs/registrator:latest "/bin/registrator --…" 15 hours ago Up 15 hours registrator[root@registrator ~]# docker exec -it nginx-01 /bin/bash
root@nginx1:/# echo "this is web1 nginx_01" > /usr/share/nginx/html/index.html
root@nginx1:/# exit
[root@registrator ~]# docker exec -it nginx-02 /bin/bash
root@nginx2:/# echo "this is web2 nginx_02" > /usr/share/nginx/html/index.html
root@nginx2:/# exit
访问 192.168.190.107:8000/ 查看轮询结果:
[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
5.5 增加一个 nginx 容器节点
① 增加一个 nginx 容器节点,测试服务发现及配置更新功能
[root@registrator ~]# docker run -itd -p:1083:80 --name nginx-03 -h nginx3 nginx
# 观察template服务,会从模板更新/usr/local/nginx/conf/vhost/kgc.conf文件内容,并且重载nginx服务
② 查看 cousul 节点 template 更新的配置文件内容
[root@consul vhost]# pwd
/etc/nginx/vhost
[root@consul vhost]# ls
fqlnginx.conf
[root@consul vhost]# cat fqlnginx.conf
upstream http_backend {server 192.168.190.108:1080;server 192.168.190.108:1081;server 192.168.190.108:1083; # 新增了一个nginx服务}
……
③ 访问 192.168.190.107:8000/ 查看轮询结果
[root@registrator ~]# docker exec -it nginx-03 /bin/bash
root@nginx3:/# echo "this is web3 nginx_03" > /usr/share/nginx/html/index.html
root@nginx3:/# exit[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
④ 停用 nginx-01 服务,查看 template 更新的配置文件内容,以及轮询结果
[root@registrator ~]# docker stop nginx-01
nginx-01
[root@registrator ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9814459efac nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 0.0.0.0:1083->80/tcp, :::1083->80/tcp nginx-03
108612e81495 nginx "/docker-entrypoint.…" 15 hours ago Up 9 minutes 0.0.0.0:1081->80/tcp, :::1081->80/tcp nginx-02
53166bf2c442 gliderlabs/registrator:latest "/bin/registrator --…" 15 hours ago Up 9 minutes registrator[root@consul vhost]# cat fqlnginx.conf
upstream http_backend {server 192.168.190.108:1081;server 192.168.190.108:1083;}
……[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
consul%20%E5%A4%9A%E8%8A%82%E7%82%B9" style="background-color:transparent;">6. consul 多节点
添加一台 docker 环境的服务器 192.168.190.106/24 加入已有的群集中,实际是为了扩展 consul 集群的规模和容量,以提高系统的可用性和可靠性。
docker%C2%A0">6.1 安装 docker
安装依赖包:
yum install -y yum-utils device-mapper-persistent-data lvm2
设置阿里云镜像源:
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装最新版本:
yum install -y docker-ce docker-ce-cli containerd.io systemctl start docker.service
systemctl enable docker.service
consul%20%E7%9B%B8%E5%85%B3%E6%9C%8D%E5%8A%A1%E6%96%87%E4%BB%B6%EF%BC%8C%E5%90%AF%E5%8A%A8%20consul%20%E6%9C%8D%E5%8A%A1">6.2 拷贝 consul 相关服务文件,启动 consul 服务
192.168.190.107:
[root@consul vhost]# scp /usr/local/bin/consul 192.168.190.106:/usr/local/bin/
192.168.190.106:
[root@ha02 ~]# consul agent \
> -server \
> -ui \
> -data-dir=/var/lib/consul-data \
> -bind=192.168.190.106 \ # 指定Consul agent监听的IP地址,用于节点间通信
> -client=0.0.0.0 \
> -node=consul-server02 \ # 指定当前节点的名称为"consul-server02"
> -enable-script-checks=true \
> -datacenter=dc1 \ # 指定Consul集群所属的数据中心名称为"dc1"
> -join 192.168.190.107 &> /var/log/consul.log &
# 加入已知的Consul节点,这里指定加入IP地址为192.168.190.107的节点
[1] 3171
6.3 查看集群信息
查看members状态:
[root@ha02 ~]# consul members
Node Address Status Type Build Protocol DC
consul-server01 192.168.190.107:8301 alive server 0.9.2 2 dc1
consul-server02 192.168.190.106:8301 alive server 0.9.2 2 dc1
查看集群状态:
[root@ha02 ~]# consul operator raft list-peers
Node ID Address State Voter RaftProtocol
consul-server01 192.168.190.107:8300 192.168.190.107:8300 leader true 2
consul-server02 192.168.190.106:8300 192.168.190.106:8300 follower true 2
# 192.168.190.106状态为follower