Files
rustfs-s3-toolkit/docker/README.md
2025-09-28 20:38:34 +08:00

4.5 KiB
Raw Permalink Blame History

遇到 “SRV 混入错误端口 / 脏实例” 怎么查 & 清

这是一份可直接照抄执行的操作手册。以 rustfs 为例,目标是让 _rustfs._tcp.service.consul 只返回期望端口(例如 :9000),并避免将来再次混入(如 :9009)。


0. 先定义变量(按你的环境修改)

# Consul 的 DNS 与 HTTP API示例值按需替换
CONSUL_DNS=172.24.0.15            # Consul DNS 服务器(通常是 server/统一的 DNS 容器)
CONSUL_HTTP=http://100.64.0.1:8500 # Consul Server 的 HTTP API 地址

# 需要排查的服务名与“唯一允许”的端口
SERVICE=rustfs
GOOD_PORT=9000

1. 证实SRV 是否含有异常端口

# 观察 SRV 记录,确认是否仅剩 :$GOOD_PORT
Dig命令
dig +short @"$CONSUL_DNS" -p 8600 _${SERVICE}._tcp.service.consul SRV

如果输出中出现非 $GOOD_PORT 的目标(例如 :9009),说明已经混入,需要继续下面的清理。


2. 列出 Catalog 中的所有实例(看端口/节点/ServiceID

curl -s "$CONSUL_HTTP/v1/catalog/service/$SERVICE" \
| jq -r '.[] | "\(.ServiceID)\t\(.ServiceAddress):\(.ServicePort)\t\(.Node)"'

这会打印出该服务在 Consul Catalog 中的所有条目(无论来自哪个节点/agent便于你确认哪些是“错误端口”。


3. 一键清理“非 $GOOD_PORT”的实例2 选 1

方式 A通过 agent 接口按 ServiceID 摘除(条目属于某个 agent 时好使)

curl -s "$CONSUL_HTTP/v1/catalog/service/$SERVICE" \
| jq -r ".[] | select(.ServicePort!=$GOOD_PORT) | .ServiceID" \
| xargs -r -n1 -I{} curl -s -X PUT "$CONSUL_HTTP/v1/agent/service/deregister/{}"

方式 B通过 catalog 接口跨节点摘除(带 Node/DC更通用

curl -s "$CONSUL_HTTP/v1/catalog/service/$SERVICE" \
| jq -c ".[] | select(.ServicePort!=$GOOD_PORT) | {Datacenter:.Datacenter, Node:.Node, ServiceID:.ServiceID}" \
| while read -r obj; do
  curl -s -X PUT -d "$obj" "$CONSUL_HTTP/v1/catalog/deregister" >/dev/null
done

任一方式执行后,建议再跑第 2 步查看是否已清空异常端口实例。


4. 再次验证 SRV 仅返回期望端口

dig +short @"$CONSUL_DNS" -p 8600 _${SERVICE}._tcp.service.consul SRV
# 现在应只显示 :$GOOD_PORT

5. 防止复发(建议至少做其中 1 条,推荐都做)

5.1 服务名拆分(最清晰)

  • 9000 只注册为 rustfs
  • 9009 注册为 rustfs-toolkit(或任意新名称)
  • Caddy/Nginx 按不同的服务名走不同站点/域名,互不干扰

5.2 标签 + SRV 过滤(即使误注册也不会被捞到)

  • 9000 注册时加标签:console
  • Caddy 的 SRV 查询只取带该标签的实例:_rustfs._tcp.console.service.consul

在 Caddy 的 dynamic srv 里写 name console.service.consul 即可(见下方示例)。

5.3 健康检查 + 自动摘除(强烈推荐)

  • 注册 JSON 里为服务附带健康检查HTTP 或 TCP并设置

    • DeregisterCriticalServiceAfter: "1m"
  • 好处:即使 agent 异常退出/网络断开,持续失败 1 分钟Consul 会自动把该实例从 Catalog 移除。

5.4 Agent 优雅离群

  • 给各个 Consul agent 配置:CONSUL_LOCAL_CONFIG='{"leave_on_terminate": true}'
  • 再配合容器的 stop_grace_period: 30s,确保容器停止时有足够时间执行 leave

Caddy配合标签过滤的示例

rfs.jmsu.top {
  reverse_proxy {
    dynamic srv {
      service rustfs
      proto   tcp
      name    console.service.consul    # 只取打了 console 标签的实例
      refresh 5s
      resolvers udp/172.24.0.15:8600 tcp/172.24.0.15:8600
    }
    # 让上游看到真实域名,满足 RustFS 等应用的 Host 校验
    header_up Host {http.request.host}
    lb_policy least_conn
  }
}

如需为 9009toolkit提供域名服务请另建一个站点块指向 service rustfs-toolkit 或者 name toolkit.service.consul(若采用标签)。


附:常见排障提示

  • SRV 名字写错:_service._tcp.service.consul不要多/少下划线
  • Caddy dynamic srvresolvers 只负责 SRV 解析;ACME 的 tls { resolvers ... } 与之无关
  • 容器 /etc/resolv.conf 里是 127.0.0.11Docker 内置 DNS也没关系只要 dynamic srv 的 resolvers 指向 Consul 即可
  • 如果访问 404/500 且日志里出现错误端口(如 :9009),十有八九是 SRV 混入了不该有的实例