☰
K8s网络不通先查哪一跳?Radar网络路径诊断Reachability静态追踪+主动探测原理详解
2026/9/28 20:24:54 网站建设 项目流程

K8s网络不通先查哪一跳?Radar网络路径诊断Reachability静态追踪+主动探测原理详解

【免费下载链接】radarThe missing open-source Kubernetes UI with a built-in MCP server for AI agents. See what's broken, why, and what changed. Issues, Topology, event timeline, Helm, GitOps, live service traffic, and cluster audits - all in one Go binary.项目地址: https://gitcode.com/gh_mirrors/radar32/radar

当你遇到Kubernetes 网络不通时,最痛苦的不是"服务挂了",而是"不知道断在哪一跳"——Ingress、Service、Endpoints、Pod,任何一环都可能出问题。开源 Kubernetes UI 工具Radar的Reachability(网络可达性)网络路径诊断功能,专门回答一个问题:如果流量发往这个资源,它能不能到达健康进程?如果不能,第一跳断在哪里?

Radar 是单二进制的开源 K8s UI,内置拓扑、资源、Helm、GitOps、流量、审计与 MCP 服务器。Reachability 于 v1.9.1 引入,支持 Service、Ingress、HTTPRoute/GRPCRoute、Gateway 四类网络入口资源,官方文档见 docs/reachability.md。

为什么 K8s 网络故障排查这么难?

传统排查方式是逐层kubectl get+curl:DNS 解析了吗?Ingress 有 backend 吗?Service selector 匹配到 Pod 吗?Pod Ready 了吗?每一跳都要人肉确认。

Radar 的做法是把整条路径画成一张按流量方向排列的跳(hop)图,并给每一跳附上:

  • 资源引用(Kind / Namespace / Name)与边标签(如HTTPRoute → Service)
  • Findings:复用 Radar 已有问题管道的检测结果,挂到故障可观测的那一跳
  • kubectl 复现命令:每条 finding 都自带一条可直接粘贴的排查命令

心智模型:Upstream 并行,Downstream 链式

Radar 把路径分成两段,判定逻辑完全不同:

方向结构判定规则
Upstreams(指向主体的入口)并行多个 Ingress 各判各的;只有全部 broken 才整体 broken
Downstream(从主体向下的链路)链式Service → 选中的 Pods;第一个 critical 发现即brokenAt(断点)

这意味着一个 Service 同时被 Ingress A 和 Ingress B 引用时,A 坏了不代表 Service 坏了——B 还在正常送流量。

下图展示了一个 Service 同时被 Ingress 和 HTTPRoute 两个入口引用的场景,Radar 对每个入口独立判定,右侧面板显示 HTTPRoute 未挂载到任何 listener:

原理详解:静态追踪层(永远在线)

静态层回答"配置接对了吗",实现在 internal/trace/trace.go:

纯函数跑在内存 informer 缓存上 零逐次 API 请求 · 零 RBAC 请求 · 零用户配置

它检查每跳的 declared 配置 + 当前 Pod 状态:端口是否存在(如gwroute:backend-port-mismatch:HTTPRoute 引用了不存在的 Service 端口)、Gateway 路由的父条件(Accepted=False/ResolvedRefs=False)、Pod 的 selected/ready 数量、headless 与无 selector 标记等。

性能目标:典型 <100ms,200 Pod 的 namespace <300ms;打开 Reachability 标签页时 UI 每 5 秒轮询一次,客户端缓存保证切页秒开。

刻意不做的事(保持可信):

  • 不读 EndpointSlice——端点信号用 Pod readiness 近似,并诚实标注endpointSource: pod-readiness
  • NetworkPolicy 只预测、不裁决——CNI 才是唯一执行权威,Radar 给出的是"集群网络规则会拦截这些 Pod 的流量"这类预测性警告
  • 不加新 CRD——一切来自 Radar 既有的 informer 缓存

原理详解:主动探测层(DNS/TCP/TLS/HTTP 分层)

主动层回答"真发一个请求,哪层先失败"。核心探测实现在 pkg/probe/probe.go,每一层有严格超时,高层成功严格蕴含低层成功:

层超时说明
DNS250ms解析声明的主机名,区分 split-horizon 场景
TCP700ms直连 ClusterIP:port 或 PodIP:port
TLS1sHTTPS 才走;证书信任失败 ≠ 不可达
HTTP1s仅 HTTP 形态端口;非 HTTP 端口(如 Redis 6379)止步于 TCP

总预算 3 秒,各跳并行执行,单个死跳不会拖垮整轮。打开标签页时自动跑一次代理视角探测(Run test可重跑),In-cluster Job 测试保持手动点击。

关键设计:探测目标必须来自集群声明的配置(Service 端口、Ingress 地址、Gateway listener),不接受用户随手输入的 URL;同时内置 SSRF 防护,拒绝直接探测回环地址、link-local 地址(含云厂商 metadata 端点 169.254.169.254、100.100.100.100 等)。

一个 Ingress 主体的典型探测

Radar 从你的机器拨打 Ingress 声明的主机名(DNS → TCP → TLS → HTTP),后端应答 308 重定向。注意顶部判定措辞的克制:

非 HTTP 服务与双协议端口

Redis 这类非 HTTP 服务只验证到 TCP,底部明确标注"TCP connections only — application protocol not checked",绝不冒充应用层可达:

kube-dns 在 53 端口同时声明 TCP 和 UDP,Radar 把两条路径拆开:TCP 可测,UDP 保留为明示的缺口而不是悄悄吞掉:

观测点(Vantage):从哪打决定证明了什么

这是 Radar 最核心的概念——探测结果脱离"从哪发起"毫无意义。界面围绕两个显式选择构建:

  1. 测哪条路径(PATH 选择器,每条声明路由一行)
  2. 从哪个观测点(三种视角胶囊):
    • Radar on your machine:作为客户端直拨
    • API-server proxy:经 K8s API 的/proxy/子资源中继
    • In-cluster probe:集群内一次性探针 Pod

切换观测点会真正重绘路径图、重算判定——笔记本上的成功永远不会被画进 in-cluster 泳道。Radar 宁可说"从这个视角无法确认",也绝不给健康路径泼脏水。

In-cluster 探针:一次性自毁 Job 的安全模型

集群内测试创建短命 Job 跑radar probe,实现在 internal/reachability/runner.go。这是整个诊断面唯一的变更操作,因此被重重设防:

防线细节
RBAC 预检创建前逐项校验create jobs/list pods/get pods/log,缺一项直接拒绝并给可复制的 kubectl 兜底命令
Pod 规格non-root、只读根文件系统、drop ALL capabilities、不挂载 SA token
生命周期25 秒 ActiveDeadline、60 秒 TTL 兜底清理、单次调用最多 5 个 Job
镜像解析四级回退:显式--reachability-image→ 自读 radar 自身运行镜像 →RADAR_IMAGE环境变量 → 版本匹配的公开镜像
结果折叠探针 Pod 身份与真实客户端不同,其失败只作信息参考,绝不升级静态判定

权限不足时 Radar 会降级为一条可直接复制执行的 kubectl 命令(参数与 Job 完全一致),而不是给你一个误导性结果。

判定语义:四种结论 + 结果可信度

路由结果(outcome)滚动汇总为判定(verdict):

判定触发条件
healthy所有被测路由在真实流量上可达
degraded5xx、部分路由失败、或良性 scale-to-0(读作琥珀色而非红色)
broken真实路径上出现不可达
unknown无法主动测试,或仅经 API-server 代理可达——永不给自信的绿色

每个路由还带独立的可信度:real(按真实流量方式测试,可设定判定)与indirect(仅经 API-server 代理,只标注、不置绿)。把unknown当作"暂停并调查"信号——它意味着追踪无法诚实回答,而不是"一切正常"。

探针失败但业务正常?先怀疑视角,再怀疑工作负载

配置健康但探测失败时,常见四因(均与负载本身无关):

  • Service mesh mTLS(Istio/Linkerd):网外探测无 mesh 证书,TLS 层必失败——识别特征:Pod 带istio-proxysidecar 或 mesh 标签。此时应信任集群内测试
  • NetworkPolicy:策略放行真实负载间流量、却拦了 Radar 的代理身份
  • DNS split-horizon:内部域名在你的笔记本上解析不出来,探测以"附原因的跳过"呈现而非失败
  • API-server 中继限制:中继被拒或拨不到仅内部地址

处理方式:跑Test in-cluster从真实数据平面探测;若真实流量确实被丢,去 Traffic 视图的逐流面板看插件上报的原因与 NetworkPolicy 归因。

小结

Radar Reachability 的设计哲学可以浓缩为一句话:把"网络不通"变成"第一跳断在哪",并且每个结论都带着它从哪个视角、用什么证据得出。

  • 静态追踪:纯缓存函数,永远在线,回答配置是否正确接线
  • 主动探测:DNS/TCP/TLS/HTTP 分层 + 3 秒预算,回答真实请求走到哪层失败
  • 观测点一等公民:笔记本 / API-server 中继 / 集群内探针,三泳道互不污染
  • 安全边界:RBAC 预检 + 自毁探针 Job + 可复制 kubectl 兜底

AI Agent 同样受益:内置 MCP 服务器的通用diagnose工具对网络入口类资源直接返回这份路径化诊断(传in_cluster: true可跑集群内探测),一次调用拿到路径形状的答案。

📚 更多资料:

  • 官方功能文档:docs/reachability.md
  • 静态路径追踪源码:internal/trace/trace.go
  • 分层探测实现:pkg/probe/probe.go
  • 集群内探针 Runner:internal/reachability/runner.go
  • 多路由探针编排:internal/reachability/incluster.go

【免费下载链接】radarThe missing open-source Kubernetes UI with a built-in MCP server for AI agents. See what's broken, why, and what changed. Issues, Topology, event timeline, Helm, GitOps, live service traffic, and cluster audits - all in one Go binary.项目地址: https://gitcode.com/gh_mirrors/radar32/radar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询