分布式中件间-Consul基础使用

概述

Consul是一种分布式服务网格(Service Mesh)解决方案,提供服务发现、健康检查、键/值存储、多数据中心管理等功能。核心组件包括客户端(Agent)、服务器(Server)、以及多种通信协议(Gossip、Raft、RPC)的协同工作。

consul提供的功能特性:

  • 多数据中心:Consul 被构建为数据中心感知的,可以支持任意数量的区域,而不需要复杂的配置。
  • 服务网格/服务细分:使用自动 TLS 加密和基于身份的授权实现安全的服务对服务通信。应用程序可以在服务网格配置中使用 sidecar 代理为入站和出站连接建立 TLS 连接,而完全不知道连接方。
  • 服务发现:Consul 使服务注册自己和通过 DNS 或 HTTP 接口发现其他服务变得简单。也可以注册外部服务,如 SaaS 提供者。
  • 健康检查:健康检查使得 Consul 能够就集群中的任何问题快速向操作员发出警报。与服务发现的集成可以防止将流量路由到不健康的主机,并启用服务级断路器。
  • Key/Value存储:一个灵活的键/值存储允许存储动态配置、特性标记、协调、领导选举等。简单的 HTTP API 使得在任何地方都可以轻松使用。

Agent,在Consul中不管Client或是Server都是Agent:

  • Client(客户端/Agent):客户端是无状态的,负责将服务注册、健康检查等请求转发给Consul服务器。它运行在每个需要使用Consul服务节点(物理机、虚拟机或容器)的守护进程,维护着本地节点和服务的状态,并通过Gossip协议与集群中的其他代理通信。
  • Server(服务器):负责存储、复制和管理集群状态的关键数据。服务器节点通常部署3到5台,以确保高可用性和数据一致性,底层通过Raft一致性算法选举出一个Leader(领导者),其他节点为Follower(追随者)。所有关键数据的写入和事务请求都由Leader处理,Follower则响应RPC查询并负责数据同步。

以dev模式运行示例:单机运行通常使用consul agent -dev,下面是带配置文件的运行方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#server.hcl
datacenter = "dev-dc1"
primary_datacenter = "dev-dc1"
data_dir = "/opt/app-data/consul"
bind_addr = "127.0.0.1"
node_name = "consul-server-01"
client_addr = "127.0.0.1"

server = true
bootstrap_expect = 1
#retry_join = ["192.168.1.10", "192.168.1.11", "192.168.1.12"]

encrypt = "E2V40IyXw7QsbQEDh+gjMbHeBDK0J4K9JLQvKIRx7vY="

acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens {
initial_management = "1fb9ffca-d8cb-4cb5-be9a-5c4bcfca1ed0"
agent = "622dc12d-ad9d-cfa4-654d-3597bf7954a1"
}
}

log_file = "/opt/app-data/consul/log/consul.log"

log_level = "INFO"
log_rotate_bytes = 104857600
log_rotate_duration = "24h"

enable_script_checks = false
enable_local_script_checks = false

ui_config {
enabled = true
}

执行命令:

1
2
3
consul agent -config-file=./server.hcl
consul acl policy create -name "agent-token-policy" -rules @agent-policy.hcl # 如果不执行,会报[WARN] agent: Coordinate update blocked by ACLs: accessorID="anonymous token"
consul acl token create -description "Token for Consul agent internal operations" -policy-name "agent-token-policy"

其中SecretID就是 agent token,然后在 server.hcl文件中添加:

1
2
3
4
5
6
7
8
9
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens {
initial_management = "1fb9ffca-d8cb-4cb5-be9a-5c4bcfca1ed0"
agent = "622dc12d-ad9d-cfa4-654d-3597bf7954a1" # 添加这一行
}
}

重启:

1
consul agent -config-file=./server.hcl

配置参数说明:

  • datacenter: 指定当前 Consul 节点所属的数据中心名称,默认值 dc1。所有未显式指定数据中心的操作默认在该 DC 内进行。多数据中心部署时,每个 DC 应使用唯一名称,同一集群内所有节点必须属于同一个数据中心。
  • primary_datacenter:指定 主数据中心。用于ACL 系统与Connect CA。
  • data_dir:Consul 存放持久化数据的目录(如 Raft 日志、快照、服务注册信息等)。必须为 绝对路径,Server 节点必须使用本地磁盘(不能是 NFS 等网络存储)。
  • enable_script_checks:是否允许通过 script 字段定义健康检查脚本(如 “script”: “/check.sh”)。出于安全考虑,默认禁用的,若启用,需确保脚本来源可信,防止任意代码执行,推荐使用 HTTP/TCP/Docker 检查替代。
  • bind_addr:Consul Agent 用于集群通信(Gossip、RPC)的绑定地址,默认值0.0.0.0。通常设为节点内网 IP(如 192.168.10.5),必须能被集群内其他节点访问。生产环境不要设为 127.0.0.1。HTTP API 地址由 client_addr 控制(默认仅 127.0.0.1),与 bind_addr 不同
  • node_name:当前节点在 Consul 集群中的唯一名称,默认值为主机名(hostname),必须在整个集群中唯一。
  • enable_local_script_checks:允许仅在本地注册的服务(通过 HTTP API 或 CLI 注册)使用脚本健康检查。比 enable_script_checks 更细粒度,仍存在安全风险,生产环境建议关闭。
  • log_file:指定日志文件路径,启用日志文件输出。需配合 log_rotate_bytes 和 log_rotate_duration 使用。
  • log_level:设置日志级别,默认值为INFO。生产环境通常用 INFO 或 WARN,调试时可用 DEBUG。可选值:TRACE, DEBUG, INFO, WARN, ERROR。
  • log_rotate_bytes:单个日志文件的最大大小(超过则轮转)。
  • log_rotate_duration:强制日志轮转的时间间隔(即使未达到 log_rotate_bytes)。
  • encrypt:用于 Gossip 协议通信加密 的密钥(Base64 编码),可通过 consul keygen 生成,集群内所有节点必须使用相同的密钥。注意:此加密仅用于 - Serf Gossip(成员关系、事件广播),不用于 RPC 或 HTTP API。
  • acl.enabled:是否启用 ACL(访问控制列表)系统。启用后,所有 API 请求需携带有效 Token。
  • acl.default_policy:默认 ACL 策略行为。allow,未匹配任何规则时允许操作(宽松模式)。deny,未匹配时拒绝操作(零信任,推荐生产使用)。
  • acl.enable_token_persistence:是否将通过 API 创建的 Token 持久化到 Raft 日志(即重启后保留)。若为 false,Token 仅存在于内存(重启丢 失),生产环境应设为 true。
  • acl.tokens.initial_management:设置 初始 Master Token(也称 Bootstrap Token)。仅在首次启动 ACL 系统时使用,拥有最高权限(可管理所有策略和 Token),首次启动后应立即删除或妥善保管,并创建更细粒度的 Token。后续启动无需再配置此字段(否则会报错)。

consul基础命令

CLI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
consul
Usage: consul [--version] [--help] <command> [<args>]

Available commands are:
acl Interact with Consul's ACLs
agent Runs a Consul agent
catalog Interact with the catalog
connect Interact with service mesh functionality
debug Records a debugging archive for operators
event Fire a new event
exec Executes a command on Consul nodes
force-leave Forces a member of the cluster to enter the "left" state
info Provides debugging information for operators.
intention Interact with service mesh intentions
join Tell Consul agent to join cluster
keygen Generates a new encryption key
keyring Manages gossip layer encryption keys
kv Interact with the key-value store
leave Gracefully leaves the Consul cluster and shuts down
lock Execute a command holding a lock
login Login to Consul using an auth method
logout Destroy a Consul token created with login
maint Controls node or service maintenance mode
members Lists the members of a Consul cluster
monitor Stream logs from a Consul agent
operator Provides cluster-level tools for Consul operators
peering Create and manage peering connections between Consul clusters
reload Triggers the agent to reload configuration files
rtt Estimates network round trip time between nodes
services Interact with services
snapshot Saves, restores and inspects snapshots of Consul server state
tls Builtin helpers for creating CAs and certificates
troubleshoot Provides tools to troubleshoot Consul's service mesh configuration
validate Validate config files/directories
version Prints the Consul version
watch Watch for changes in Consul

重要命令说明:

  1. 启动 / 版本 / 帮助:
  • consul version: 查看版本
  • consul -h/consul <subcommand> -h:查看帮助
  • consul agent -dev:快速启动一个开发模式的单节点 agent

  1. Agent / 成员 / 加入 / 离开
  • consul agent -config-dir=/etc/consul.d:启动 agent(server 或 client 由 -server 指定,或在配置文件中设置)
  • consul join <IP|HOST> :加入集群(把当前 agent 加入到已有节点),如 consul join 10.0.0.5
  • consul leave:离开集群
  • consul members:列出当前 agent 能看到的成员

  1. Catalog(节点/服务目录)
  • consul catalog services:列出集群中所有服务
  • consul catalog nodes -service=<SERVICE_NAME>:列出某服务对应的节点
  • consul catalog register service.json consul catalog deregister service.json:手动注册/反注册

  1. 服务与健康检查(通过 agent 注册服务)
  • 使用 JSON 文件注册服务:这是常见方式。consul services register svc.json consul services deregister svc.json:
  • 通过 agent 本地命令注册:consul agent service register -name web -address 10.0.0.10 -port 80 consul agent service deregister <service_id>

  1. KV(键值存储)
  • 写入键:consul kv put <key> <value>
  • 读取键(默认显示 base64 编码结果):consul kv get <key>
  • 删除键:consul kv delete <key>
  • 递归删除前缀:consul kv delete -recurse <prefix>
  • 列出前缀下所有键:consul kv get -recurse <prefix>

  1. ACL(访问控制):在启用 ACL 时,需要设置 CONSUL_HTTP_TOKEN 环境变量或在请求中加入 ?token=<token>
  • 引导:首次启动时获得管理 token, consul acl bootstrap
  • 创建: consul acl token create -description “deploy token”
  • 列表 / 查看: token consul acl token list consul acl token read <token-id>

  1. Raft / operator(运维相关)
  • 查看 Raft 节点与 leader(典型): consul operator raft list-peers
  • 强制移除 Raft peer(谨慎): consul operator raft remove-peer <ID>
  • 保存/恢复快照(备份/恢复): consul snapshot save backup.snap consul snapshot restore backup.snap

  1. Consul Connect(服务网格相关)
  • 启动本地代理: consul connect proxy -sidecar-for <service>
  • 列出 intentions:服务间访问控制,consul connect intentions list

  1. 监控 / 日志 / 信息
  • 实时查看 agent 日志输出:consul monitor
  • 获取 agent 信息(配置、成员等):consul info

  1. Watch(事件/Key 触发)
  • 使用 watch 的简单命令行方式(通常写在配置中) consul watch -type=key -key=”config/foo” -handler=”/path/to/script.sh”

示例:注册mysql到consul

1
2
3
4
5
6
7
8
9
10
11
12
13
{ 
"service": {
"name": "mysql",
"tags": ["database"],
"port": 3306
},
"checks": [ {
"name": "MySQL TCP Check",
"tcp": "localhost:3306",
"interval": "10s",
"timeout": "1s"
} ]
}

注册:

1
consul services register mysql-service.json

Consul API

Consul不仅有丰富的 CLI 命令,还提供了一套强大的 API,用于与 Consul 服务进行交互。Consul HTTP API 为 /v1/ 开头,如 /v1/kv、/v1/catalog 等。支持 HTTP/HTTPS,若开启 ACL,需要在请求中通过 HTTP 头 X-Consul-Token 或环境变量 CONSUL_HTTP_TOKEN 提供 token。响应格式通常为 JSON。KV 的值在默认 JSON 返回中为 base64 编码,可以使用 ?raw 来获取原始值。

核心认证/请求头:

  • X-Consul-Token (请求头):ACL token,用于授权所有需要权限的 API 调用(读/写/管理)。这是 Consul 官方推荐的方式;也可以用 ?token= 查询参数,但不推荐用于公开场景。curl -H "X-Consul-Token: $CONSUL_TOKEN" http://127.0.0.1:8500/v1/kv/app/conf?raw
  • Authorization: Bearer <token>:部分版本/集成支持,但 X-Consul-Token 始终是明确的首选。
  • X-Request-Id:自定义追踪头,由前端代理或网关提供请求 ID,便于追踪与排错,Consul 本身不强制,但可传递。
  • Content-Type:标准HTTP头,在请求方法POST/PUT/PUT JSON 数据时设为 application/json。
  • Accept:标准HTTP头,指定能接受的响应类型(一般默认 JSON)。

响应头重要项:用于一致性、长轮询与状态

  • X-Consul-Index:服务端返回的全局修改索引,用于实现阻塞查询(long-polling)。客户端保存此索引并在后续请求通过 ?index=<last-index>&wait=<duration>实现阻塞等待数据变更,请求会在有更新或超时后返回,并在响应头包含新的 X-Consul-Index。通常在KV、Catalog、Health 等可以用来做高效事件监听/同步。
  • X-Consul-KnownLeader:布尔值(”true”/“false”),表示 agent 是否知道当前 datacenter 的 Raft leader。用于判断节点是否与 leader 通信正常,适合健康检查与监控告警。
  • X-Consul-LastContact:与 leader 的最后接触时间(ms),可用于判定网络抖动或 leader 连接问题。

重要接口说明

  1. KV(键值存储)
  • 路径 / 方法
    • GET /v1/kv/ — 读取键(返回 JSON 或 ?raw)
    • PUT /v1/kv/ — 写入键(请求体为值)
    • DELETE /v1/kv/ — 删除键
    • GET /v1/kv/?recurse — 递归列出前缀
  • 重要参数
    • ?raw、?recurse、?flags、?cas、?acquire、?release
    • 长轮询:?index=&wait=
  • 示例
    1
    2
    3
    curl --request PUT http://127.0.0.1:8500/v1/kv/config/name -d 'myapp'
    curl http://127.0.0.1:8500/v1/kv/config/name?raw
    curl "http://127.0.0.1:8500/v1/kv/config/name?index=100&wait=5m"
  • 注意
    • 值在 JSON 返回中为 base64;使用 ?raw 简化读取。
    • 支持与 session 结合的分布式锁(acquire/release)。

  1. Agent(本地 agent 操作)
  • 路径 / 方法
    • GET /v1/agent/services — 列出本地注册服务
    • PUT /v1/agent/service/register — 本地注册服务(JSON body)
    • PUT /v1/agent/service/deregister/ — 注销服务
    • GET /v1/agent/self — agent 本身信息
  • 示例
    1
    2
    curl --request PUT --data @svc.json http://127.0.0.1:8500/v1/agent/service/register
    curl http://127.0.0.1:8500/v1/agent/services

  1. Catalog(节点/服务目录)
  • 路径 / 方法
    • GET /v1/catalog/services — 列出服务名和标签
    • GET /v1/catalog/service/ — 列出提供该服务的节点
    • GET /v1/catalog/nodes — 列出节点
  • 示例
    1
    2
    curl http://127.0.0.1:8500/v1/catalog/services
    curl http://127.0.0.1:8500/v1/catalog/service/web

  1. Health(健康检查)
  • 路径 / 方法
    • GET /v1/health/checks/ — 返回服务的检查项
    • GET /v1/health/service/ — 返回带健康状态的服务实例列表
    • GET /v1/health/state/ — state = passing|warning|critical
  • 示例
    1
    2
    curl http://127.0.0.1:8500/v1/health/service/web
    curl http://127.0.0.1:8500/v1/health/state/critical

  1. Session(会话,用于锁/选主)
  • 路径 / 方法
    • PUT /v1/session/create — 创建 session(JSON body)
    • GET /v1/session/list — 列出 sessions
    • PUT /v1/session/destroy/ — 销毁 session
  • 示例
    1
    curl --request PUT --data '{"LockDelay":"15s","Name":"my-session"}' http://127.0.0.1:8500/v1/session/create
  • 场景
    • 与 KV 的 ?acquire= / ?release= 实现分布式锁或 leader 选举。

  1. Transactions(原子事务)
  • 路径 / 方法
    • PUT /v1/txn — 接受一个操作数组,原子执行
  • 示例(伪)
    1
    curl --request PUT --data '[{"KV":{"Verb":"set","Key":"a","Value":"b64"}}]' http://127.0.0.1:8500/v1/txn
  • 注意
    • 支持多步原子操作(KV、service 等),失败时返回错误详情。

  1. ACL(访问控制)
  • 路径 / 方法
    • PUT /v1/acl/bootstrap — 初始化(返回管理 token)
    • PUT /v1/acl/token — 创建 token
    • GET /v1/acl/token/ — 读取 token
    • GET /v1/acl/tokens — 列表
  • 示例
    1
    2
    curl --request PUT http://127.0.0.1:8500/v1/acl/bootstrap
    curl -H "X-Consul-Token: $BOOTSTRAP" --request PUT --data @token.json http://127.0.0.1:8500/v1/acl/token
  • 安全
    • 在生产建议用 HTTPS,最小权限策略,避免将 token 放 URL。

  1. Operator(运维 / Raft / 快照)
  • 路径 / 方法
    • GET /v1/operator/raft/configuration — Raft peers
    • PUT /v1/operator/raft/remove-peer — 移除 peer(谨慎)
    • GET /v1/operator/snapshot — 下载 snapshot
  • 示例
    1
    2
    curl http://127.0.0.1:8500/v1/operator/raft/configuration
    curl --output backup.snap http://127.0.0.1:8500/v1/operator/snapshot

  1. Status(集群状态)
  • 路径 / 方法
    • GET /v1/status/leader — 返回 leader 地址
    • GET /v1/status/peers — 返回 raft peers 列表
  • 示例
    1
    2
    curl http://127.0.0.1:8500/v1/status/leader
    curl http://127.0.0.1:8500/v1/status/peers

  1. Connect(服务网格)
  • 路径 / 方法
    • GET/POST /v1/connect/intentions — 列出/创建 intentions(服务间访问控制)
    • GET /v1/connect/proxy — 代理相关信息
  • 示例
    1
    curl http://127.0.0.1:8500/v1/connect/intentions

  1. Events(事件广播)
  • 路径 / 方法
    • PUT /v1/event/fire/ — 触发事件(body 可带负载)
    • GET /v1/event/list — 列出事件(按名称/时间)
  • 示例
    1
    curl --request PUT --data '{"reason":"reload"}' http://127.0.0.1:8500/v1/event/fire/reload

  1. Prepared Queries / Query(高级查询)
  • 路径 / 方法
    • POST /v1/query — 创建 prepared query
    • GET /v1/query//execute — 执行 prepared query
  • 用途
    • 预定义发现策略(过滤/排序/健康策略),便于跨团队复用与权限控制。

小结

常见错误码与含义

  • 200 OK / 204 No Content / 201 Created:正常
  • 400 Bad Request:请求格式或参数错误
  • 403 Forbidden:ACL 权限不足或 token 无效
  • 404 Not Found:资源不存在
  • 500/5xx:服务器错误或内部故障

注意点:

  • 使用 X-Consul-Token 而非 URL token,且通过 HTTPS 传输。
  • 长轮询使用 X-Consul-Index + ?index/&wait,避免频繁短轮询。
  • 对会被代理缓存的端点(如阻塞查询)在代理层设置 no-cache。
  • 在自动化脚本中使用事务(/v1/txn)避免中间不一致状态。
  • 在生产使用配置文件 + systemd 管理 Agent,避免 -dev 模式。

分布式中件间-Consul基础使用
http://example.com/2025/08/10/分布式中间件-consul基础使用/
作者
ares
发布于
2025年8月10日
许可协议