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

135 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 遇到 “SRV 混入错误端口 / 脏实例” 怎么查 & 清
> 这是一份可直接照抄执行的操作手册。以 `rustfs` 为例,目标是让 `_rustfs._tcp.service.consul` 只返回期望端口(例如 `:9000`),并避免将来再次混入(如 `:9009`)。
---
## 0. 先定义变量(按你的环境修改)
```bash
# 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 是否含有异常端口
```bash
# 观察 SRV 记录,确认是否仅剩 :$GOOD_PORT
Dig命令
dig +short @"$CONSUL_DNS" -p 8600 _${SERVICE}._tcp.service.consul SRV
```
> 如果输出中出现非 `$GOOD_PORT` 的目标(例如 `:9009`),说明已经混入,需要继续下面的清理。
---
## 2. 列出 Catalog 中的所有实例(看端口/节点/ServiceID
```bash
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 时好使)
```bash
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更通用
```bash
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 仅返回期望端口
```bash
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配合标签过滤的示例
```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 srv``resolvers` 只负责 SRV 解析;**ACME 的 `tls { resolvers ... }` 与之无关**
* 容器 `/etc/resolv.conf` 里是 `127.0.0.11`Docker 内置 DNS也没关系只要 `dynamic srv` 的 resolvers 指向 Consul 即可
* 如果访问 404/500 且日志里出现错误端口(如 `:9009`),十有八九是 SRV 混入了不该有的实例