srv 多端口解决
This commit is contained in:
134
docker/README.md
Normal file
134
docker/README.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# 遇到 “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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 如需为 9009(toolkit)提供域名服务,请另建一个站点块,指向 `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 混入了不该有的实例
|
||||
Reference in New Issue
Block a user