Consul 是由 HashiCorp 开发的一款开源工具,用于实现服务发现、配置管理和分布式系统的多数据中心协调。其高可用集群(High Availability Cluster)设计旨在确保服务持续可用、数据一致性和故障容错能力。
1. 核心组件
-
Server 节点:
-
领导者(Leader):负责处理所有写操作(如服务注册、KV存储更新),并通过 Raft 协议保证数据一致性。
-
跟随者(Follower):复制 Leader 的数据,参与 Raft 选举,故障时可晋升为 Leader。
-
推荐配置:至少 3-5 个 Server 节点(避免脑裂,Raft 要求多数节点存活)。
-
-
Client节点:-
轻量级代理,将请求转发给 Server 节点,不参与 Raft 选举。 -
部署在每个服务节点上,用于服务注册和健康检查。
-
2. 高可用关键机制
-
Raft 共识算法:
-
所有 Server 节点通过 Raft 选举 Leader,确保数据强一致性。
-
写操作需多数节点(N/2 + 1)确认,例如 3 节点集群需至少 2 个节点确认。
-
-
多数据中心支持:
-
不同数据中心(DC)的 Consul 集群通过 WAN Gossip 通信。
-
支持跨数据中心服务发现,但各 DC 的 Server 集群独立运行 Raft。
-
-
Gossip 协议:
-
使用 UDP 广播节点状态(存活/故障),快速检测故障。
-
分 LAN Gossip(同一数据中心)和 WAN Gossip(跨数据中心)。
-
-
自动故障转移:
-
Leader 故障时,Follower 通过 Raft 选举新 Leader(通常在秒级完成)。
-
客户端请求自动重定向到新 Leader。
-
3. 部署建议
-
Server 节点:
-
奇数数量(如 3、5),分布在不同可用区(AZ)或物理机器。
-
配置 -bootstrap-expect=N 指定初始集群大小(如 -bootstrap-expect=3)。
-
-
Client 节点:
-
无状态,可水平扩展,通常与业务服务共置。
-
-
网络要求:
-
Server 节点间低延迟(Raft 对延迟敏感)。
-
开放端口:TCP 8300(Server RPC)、8301(LAN Gossip)、8302(WAN Gossip)、8500(HTTP API)。
-
4. 数据持久性与一致性
-
持久化存储:Server 节点将数据(如 KV、服务目录)存储在本地(可通过 -data-dir 指定路径)。
-
一致性模式:
-
default:读 Leader,强一致性。
-
stale:读任意节点,可能过期。
-
consistent:读多数节点,线性一致性。
-
5. 监控与运维
-
健康检查:
-
内置服务健康检查(HTTP/TCP/脚本)。
-
节点故障通过 Gossip 协议快速传播。
-
-
监控指标:
-
通过 /v1/agent/metrics 接口或集成 Prometheus。
-
关键指标:Raft 任期(term)、提交索引(commit index)、节点存活状态。
-
-
备份与恢复:
-
定期备份 -data-dir 下的 raft/ 和 serf/ 目录。
-
使用 consul snapshot save/restore 命令。
-
6. 典型应用场景
-
服务网格:与 Connect 功能结合实现 mTLS 加密通信。
-
配置中心:通过 KV 存储动态配置(如 vault 集成)。
-
多云/混合云:跨数据中心服务发现。
7. 注意事项
-
脑裂问题:网络分区时,少数派节点会拒绝写入(需人工干预或配置 autopilot 自动清理)。
-
性能权衡:更多 Server 节点提高容错能力,但会增加 Raft 协商开销。
-
版本升级:建议滚动升级,确保多数 Server 节点始终在线。
-
集群数量:建议以
奇数
集群为主,确保不会出现 Leader 选举不出的情况。
集群IP示例
部署保活服务*supervisor
-
部署所在服务器:
master
slave
arbiter
-
部署命令:
yum -y install supervisor
编写Consul集群所需文件
-
Consul.ini 启动文件内容
-
部署所在服务器:
master
slave
arbiter
-
启动文件所在位置:
/etc/supervisord.d/
-
启动文件名称:
consul.ini
-
[program:consul]
command=/opt/app/consul/consul agent -server -http-port=8500 -data-dir=/data/data/consul/ -node=192e168e1e1 -bind=192.168.1.1 -bootstrap-expect=3 -client=0.0.0.0 -datacenter=xiaopalu -ui -config-dir=/opt/app/consul/config/
process_name=%(program_name)s
numprocs=1
directory=/opt/app/consul
autostart=true ; 系统启动时自动启动此程序
autorestart=true ; 进程崩溃后自动重启
startsecs=5 ; 进程启动后必须保持运行至少5秒才算成功
startretries=3 ; 启动失败时最多尝试3次
stopsignal=QUIT ; 停止程序时发送的信号
stopwaitsecs=5 ; 等待5秒钟让程序优雅退出
user=root ; 以root用户身份运行(注意安全风险)
redirect_stderr=true ; 将标准错误输出重定向到标准输出
stdout_logfile=/var/log/consul.log ; 日志文件路径
stdout_logfile_maxbytes=10MB ; 日志文件最大尺寸
stdout_logfile_backups=5 ; 日志轮换备份数量
; 以下为可选环境变量配置(当前被注释)
; environment=A=1,B=2
; 以下为可能的额外配置(被注释)
; serverurl=AUTO
-
文件内容注解:
-
启动Consul代理,作为一个服务器节点(
-server
) -
设置HTTP端口为
8500
-
指定数据存储目录
-
设置节点名为
192e168e1e1
-
绑定IP为
192.168.1.1
-
预期启动3个服务器节点(
-bootstrap-expect=3
) -
允许所有IP访问HTTP接口(
-client=0.0.0.0
) -
指定数据中心名称为
xiaopalu
-
启用UI界面(
-ui
) -
指定配置文件目录(
-config-dir
)
-
-
Auth.hcl 鉴权文件
-
部署所在服务器:
master
slave
arbiter
-
鉴权文件所在位置:
/opt/app/consul/config/
-
鉴权文件名称:
auth.hcl
-
{
"acl": {
"enabled": true, // 启用ACL功能
"default_policy": "deny", // 默认策略:拒绝所有未授权请求
"enable_token_persistence": true, // 启用Token持久化,重启后保持Token状态
"tokens": {
"master": "xiaopaluliulangji" // 集群的鉴权Token(Master权限Token)
}
}
}
-
Consulha.hcl 集群节点文件
-
部署所在服务器:
master
slave
arbiter
-
鉴权文件所在位置:
/opt/app/consul/config/
-
鉴权文件名称:
consulha.hcl
-
注:本文件中的IP地址 必须 与
Consul.ini
启动文件中bind
参数的IP地址保持一致,且三个IP必须可以相互 PING 通! -
测试方式:
ping -I 本节点IP地址 其他节点的IP地址
-
例子:
ping -I 192.168.1.1 192.168.1.2
-
-
-
server = true # 启用服务器模式
retry_join = ["192.168.1.1", "192.168.1.2", "192.168.1.3"] # 其他节点的IP地址
-
Consul 二进制启动文件
-
部署所在服务器:
master
slave
arbiter
-
二进制文件所在目录:
/opt/app/consul/
-
二进制文件名称:
consul
-
放入后添加权限:
chmod +x /opt/app/consul/consul
-
-
更新
supervisor
保活服务:supervisorctl update
-
注:这一步
supervisorctl update
是用来同步配置文件的变更到Supervisor
进程中的命令,确保配置的修改得以生效。
-
-
启动
Consul
服务:supervisorctl start consul
-
注:Consul 集群同步端口为
8301
,记得开放8301
端口,否则会显示端口连接超时(timeout
)
-
-
Consul集群额外命令
-
查看集群节点:
/opt/app/consul/consul members -token xiaopaluliiulangji
-
页面查看集群节点:
http://192.168.1.1:8500/