云原生-08-DNS-Ingress-Consul在内部平台里怎么协同工作
内部平台一旦同时引入 DNS、Ingress 和 Consul,最容易出现一种表面上很丰富、现场却很混乱的状态:
- 域名已经配了,但访问还是不通
- Ingress 规则已经发布,入口还是 404 或 502
- 服务在 Kubernetes 里能访问,跨服务调用却又绕去了 Consul
- Consul 健康检查显示通过,业务方仍然说目标服务不可用
- 同一条链路里,入口层、服务发现层、内部解析层都留下了证据,但没人能快速说清根因落在哪一段
这类问题的根因通常不是组件有多复杂,而是职责边界没有先拆清。
在内部平台场景里,这三者更适合承担的是不同角色:
DNS负责把名称解析到正确入口或正确服务地址Ingress负责处理来自外部或统一入口的 HTTP/HTTPS 流量Consul负责内部服务发现、健康检查和一部分服务注册信息
如果这三层边界不清,后面最容易出现三种失真:
- 同一个服务同时存在多种访问方式,没人知道哪条才是标准路径
- 问题出现时,各层都像正常,整体却不通
- 一次配置变更影响了解析、入口和注册中心,但证据没有收在同一时间线上
这篇文章只讨论一个核心问题:
在内部平台里,DNS、Ingress 和 Consul 应该怎么协同,问题发生时应该按什么链路排查,哪些坑最容易反复出现。
一、先把职责边界拆开
这三层如果不先拆清,后面任何“访问不通”都会被粗暴归成网络问题。
1. DNS 负责“名字到地址”的第一跳
DNS 这一层最该回答的是:
- 域名最终解析到了哪
- 是解析到 Ingress 入口,还是直接解析到内部服务
- TTL 是否合理
- 是否存在旧记录缓存
内部平台里常见的 DNS 对象包括:
- 外部访问域名
- 平台统一入口域名
- 集群内服务域名
- 部门内部自定义短域名
2. Ingress 负责“入口到服务”的第二跳
Ingress 关注的是:
- Host 和 Path 是否命中
- 后端 Service 是否正确
- TLS 证书是否匹配
- Controller 是否真正加载了最新规则
这一层最容易被误解的地方是:
- Ingress 正常不等于后端一定正常
- Ingress 配好了不等于 DNS 已经指到它
3. Consul 负责“内部服务发现和健康信息”
Consul 更适合承担这些职责:
- 内部服务注册
- 健康检查结果暴露
- 服务实例地址管理
- 某些场景下的跨集群或跨环境发现
这一层最容易被误判的地方是:
- 健康检查通过,不代表业务调用链一定通
- 服务注册成功,不代表上层已经切到新实例
二、内部平台里更稳的协同方式
更适合长期维护的协同方式,通常不是让三者互相替代,而是让它们各负责一段。
1. 外部访问链路
一条更清晰的外部访问链路通常是:
用户域名 -> DNS -> Ingress VIP / LB -> Ingress Controller -> Service -> Pod
这条链路里:
- DNS 决定入口地址
- Ingress 决定流量路由规则
- Kubernetes Service 决定后端实例集合
2. 内部服务调用链路
内部平台服务之间如果接入 Consul,更常见的是:
调用方 -> Consul 服务名 -> 实例地址 / 健康实例 -> 目标服务
这条链路的重点在于:
- Consul 只负责内部发现,不负责统一外部入口
- 内部调用最好不要再绕回 Ingress
3. 混合场景
很多内部平台的真实现场是混合场景:
- 外部用户走 DNS + Ingress
- 平台内部服务间调用走 DNS + Consul 或直接走 Consul
- 管理后台、回调入口、Webhook 仍走统一 Ingress
这个时候最重要的不是“统一一种技术”,而是明确每种访问方式的标准入口。
三、排查时按四层走,不要一起翻
更适合现场的排查方式,是把链路拆成四层:
- 解析层
- 入口层
- 服务发现层
- 后端实例层
1. 解析层:先确认名字到底指向了哪
这一层需要先确认:
- 域名解析结果是否正确
- 是不是命中了旧记录
- 不同客户端解析结果是否一致
- 集群内和集群外解析是否一致
高频动作包括:
- 看 A 记录 / CNAME
- 对照 TTL
- 对照发布和变更时间
2. 入口层:确认 Ingress 是否真正接住了流量
这一层需要确认:
- Host 和 Path 是否匹配
- Ingress Controller 日志是否有请求记录
- 后端 Service 是否健康
- TLS 证书和 SNI 是否匹配
3. 服务发现层:确认 Consul 是否真的指向了正确实例
这一层需要确认:
- 服务实例是不是都注册上来了
- 健康检查是不是过于宽松或过于严格
- 返回的实例地址是否是当前环境的真实地址
- 下线实例是否还残留在注册列表里
4. 后端实例层:最后才看 Pod / 进程 / 端口
前面三层都对的时候,再往下确认:
- Pod 是否 Ready
- Service selector 是否正确
- 端口监听是否一致
- 应用是否能真正处理请求
四、最小排查骨架
下面这套顺序更适合在内部平台现场直接复用。
1. 先问访问路径
- 这次是外部访问还是内部调用
- 走的是平台统一域名还是服务名
- 预期应该经过 Ingress 还是直接走 Consul
2. 再问解析结果
- DNS 最终解析到哪
- 是否有旧缓存
- 是否和当前发布环境一致
3. 再问流量有没有到入口
- Ingress 是否有匹配日志
- 后端 Service 是否有 endpoints
- 入口层是否返回 404、502、504
4. 再问服务发现是否正确
- Consul 是否返回健康实例
- 是否返回了旧实例或错误环境实例
- 健康检查是否只测端口、不测业务可用性
5. 最后问实例本身
- Pod 是否 Ready
- 端口是否监听
- 应用日志是否能对上请求时间线
五、最小记录表
| 时间 | 路径 | 解析结果 | Ingress 结果 | Consul 结果 | 实例状态 | 结论 |
|---|---|---|---|---|---|---|
| 10:12 | 外部域名访问 | 指向旧 VIP | 规则未命中 | 不涉及 | Pod Ready | DNS 缓存未刷新 |
| 11:05 | 内部服务调用 | 正常 | 不涉及 | 返回旧实例 | 新实例 Ready | Consul 下线残留 |
六、常见坑
1. 把 Ingress 当内部服务发现来用
服务间调用如果绕回 Ingress,链路会变长,定位也更难。
2. 同一服务存在多个标准入口
一会儿走平台域名,一会儿走 Consul 名称,一会儿又直连 Service,最终没人知道哪条才是正式路径。
3. DNS TTL 太长,变更后旧记录迟迟不退
入口已经切了,客户端还在命中旧地址。
4. Consul 健康检查过于简单
只测端口是否打开,很容易把“能连”误判成“可用”。
5. 只看 Pod Ready,不看 Endpoints 和入口日志
后端实例健康,不代表入口层已经把流量接过去。
6. 证据不在同一时间线
DNS 改动、Ingress 发布、Consul 注册更新如果没有统一时间线,后续复盘很难说明到底是哪一步先出错。
七、真实案例:入口访问 502,但根因并不在 Ingress
1. 场景
内部平台某个管理后台在版本发布后,外部域名访问持续返回 502。现场最先怀疑的是 Ingress 规则配错了,因为同一时间还改了域名和入口配置。
2. 执行
现场先看 DNS,解析结果已经指向新的 Ingress VIP;随后看 Ingress Controller 日志,确认请求确实打到了入口,规则也命中了预期后端 Service。
3. 现象
解析层和入口层都基本正常,但 502 说明 Ingress 转到后端时出了问题。
4. 排查
继续检查 Service 和 Endpoints,发现 Kubernetes 侧后端实例都在;再看内部服务发现链路,发现管理后台依赖的一个内部鉴权服务仍通过 Consul 返回旧实例地址,而旧实例已经被下线但健康检查残留。结果是:
- 用户请求先经 DNS 和 Ingress 到管理后台
- 管理后台再经 Consul 调用鉴权服务
- Consul 返回旧地址,内部调用失败
- 最终外部看起来像入口
502
5. 修复
现场先清理 Consul 残留实例并收紧健康检查条件,让下线实例及时摘除;随后补了三项动作:
- 外部入口和内部依赖分别建链路图
- 发布记录里固定记录 DNS、Ingress、Consul 三类变更时间
- 对关键依赖增加“业务可用性”健康检查,而不是只测端口
八、结论
DNS、Ingress 和 Consul 在内部平台里最重要的不是“都能用”,而是职责边界清楚、链路标准明确、问题出现时有固定排查顺序。
更稳的协同方式通常是:
- DNS 负责名字到地址
- Ingress 负责统一入口流量
- Consul 负责内部服务发现
- 排查时按解析、入口、服务发现、实例四层推进
这样才能避免把所有问题都混成一句“平台网络不通”。