当前位置: 首页 > news >正文

Kubernetes Service 请求打不通:Pod 明明 Running,从 selector 到 kube-proxy 逐层定位

Kubernetes Service 请求打不通:Pod 明明 Running,从 selector 到 kube-proxy 逐层定位

你部署了一个服务,kubectl get pod显示全是Running,可另一个 Pod 里curl http://my-svc:8080就是超时或 connection refused。日志没报错、探针也过了,偏偏请求进不去。这类问题最耗人,因为「Pod 是好的」这个假象会把你引向错误方向。这篇按数据流的顺序,一层一层把断点找出来。

先建立心智模型:一个请求要穿过几道门

从 caller Pod 发出的请求,到真正落到目标容器,中间要过这些关卡:

  1. DNS:my-svc解析成 ClusterIP。
  2. Service:ClusterIP 是个虚拟 IP,本身不监听端口。
  3. Endpoints / EndpointSlice:Service 靠 selector 把匹配的 Pod IP 收进来,这才是真正的后端列表。
  4. kube-proxy:在每个节点上把发往 ClusterIP 的流量 DNAT 到某个 Pod IP。
  5. 目标 Pod:容器进程真的在监听那个targetPort

任何一道门断了,现象都是「打不通」,但修法完全不同。排查就是顺着这条链逐段确认。

第一刀:Endpoints 有没有后端

九成的「Service 不通」都断在这里——selector 和 Pod label 对不上,Endpoints 是空的。

# 直接看这个 Service 背后有没有真实的 Pod IPkubectl get endpoints my-svc# 空的话长这样,NAME 后面是 <none>:# NAME ENDPOINTS AGE# my-svc <none> 10m

如果 ENDPOINTS 是<none>,说明没有任何 Pod 被选中。对比 Service 的 selector 和 Pod 的 label:

# Service 想选的 labelkubectl get svc my-svc-ojsonpath='{.spec.selector}'# {"app":"myapp"}# Pod 实际带的 labelkubectl get pods --show-labels|grepmyapp# myapp-xxx 1/1 Running app=my-app,... ← 注意:app=my-app 不是 my-app

上面这个例子里,Service 选app=myapp,Pod 却是app=my-app,一个连字符之差,Endpoints 就永远是空的。修 Service 的 selector 或 Deployment 的template.metadata.labels,让它们完全一致。

关键点:Service 的 selector 匹配的是Pod 的 label,不是 Deployment 的 name,也不是 Pod 的 name。改完 selector 后 Endpoints 会自动重新填充,不用重启 Pod。

第二刀:端口对不对

Endpoints 有 IP 了还是不通,下一个高发点是端口。Service 有两个端口概念,新手常搞混:

apiVersion:v1kind:Servicemetadata:name:my-svcspec:selector:app:myappports:-port:8080# Service 对外暴露的端口(你 curl my-svc:8080 的那个)targetPort:3000# 转发到 Pod 容器里的端口(容器进程真正监听的)

port是别人访问 Service 用的,targetPort必须等于容器里进程真正监听的端口。如果你的应用监听 3000 却把targetPort写成 8080,请求会被转发到 Pod 的 8080——那里没人监听,直接 connection refused。

确认容器到底监听哪个端口,别猜,进去看:

# 进目标 Pod 看进程监听的端口(容器里没有 ss/netstat 时用这招)kubectlexec-itmy-svc-pod --sh-c'cat /proc/net/tcp'# 或者直接在 Pod 内自己 curl 自己,先排除 Service 层kubectlexec-itmy-svc-pod --curl-svhttp://127.0.0.1:3000/health

这一步很关键:如果在 Pod 内部curl 127.0.0.1:3000都不通,那问题根本不在 Service,而是应用没起来、或者只监听了127.0.0.1而不是0.0.0.0。很多服务默认 bind localhost,容器外(包括 kube-proxy)就永远连不上。

# 常见错误:应用配置里 bind 127.0.0.1,只能容器内自己访问# 正确:监听 0.0.0.0:3000,才能被 Pod 网络里的其他节点访问

第三刀:是 DNS 还是网络

如果 Endpoints、端口都对,Pod 内自己也能 curl 通,问题就在跨 Pod 的路径上。先切开 DNS 和网络两个变量——直接用 ClusterIP 绕过 DNS:

# 拿到 ClusterIPkubectl get svc my-svc-ojsonpath='{.spec.clusterIP}'# 10.96.0.42# 从另一个 Pod 用 IP 直连,绕过 DNSkubectl run tmp--rm-it--image=nicolaka/netshoot --\curl-svhttp://10.96.0.42:8080/health
  • 用 ClusterIP 通、用域名不通→ DNS 问题。检查 CoreDNS Pod 是否正常、/etc/resolv.conf里的 nameserver 对不对:
kubectl get pods-nkube-system-lk8s-app=kube-dns kubectlexec-ittmp --cat/etc/resolv.conf# 应该有 nameserver 指向 CoreDNS 的 ClusterIP,search 域含 svc.cluster.local

跨 namespace 访问时,短名字解析不到是常见坑——my-svc只在同 namespace 生效,跨 namespace 要用全名my-svc.other-ns.svc.cluster.local

  • 用 ClusterIP 也不通→ kube-proxy 或 CNI 网络层。看 kube-proxy 是否在每个节点都健康:
kubectl get pods-nkube-system-lk8s-app=kube-proxy-owide# 确认每个节点都有一个 Running 的 kube-proxy

kube-proxy 挂了或规则没同步,发往 ClusterIP 的流量就不会被 DNAT 到后端 Pod,表现就是连 ClusterIP 超时。

第四刀:NetworkPolicy 悄悄拦了

前面全对却还是不通,最后查一个隐形杀手——NetworkPolicy。它一旦对目标 Pod 生效,默认会拒绝所有未显式放行的入站流量,而且不留任何错误日志,现象和「网络不通」一模一样。

# 看目标 Pod 所在 namespace 有没有 NetworkPolicykubectl get networkpolicy-nmy-namespace

如果有,读它的ingress规则,确认调用方的 Pod label / namespace 在放行名单里。一个典型的「default deny」策略会挡掉一切没被 allow 的来源:

# 这条策略一旦存在,没被其他 allow 规则覆盖的入站流量全部被丢弃apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:default-deny-ingressspec:podSelector:{}# 选中该 namespace 所有 PodpolicyTypes:-Ingress# 只管入站,且没写 ingress 规则 = 全拒

补一条放行调用方的规则即可,别直接删 default-deny(那是安全基线)。

一条命令快速定位在哪一层

把上面浓缩成一个排查顺序,照着走通常几分钟见分晓:

# 1. 后端列表空不空kubectl get endpoints my-svc# 2. Pod 内自己通不通(排除应用/bind 问题)kubectlexec-it<pod>--curl-s127.0.0.1:<targetPort>/health# 3. 换个 Pod 用 ClusterIP 直连(排除 DNS)kubectl run tmp--rm-it--image=nicolaka/netshoot --curl-s<clusterIP>:<port>/health# 4. 用域名再试一次(3 通 4 不通就是 DNS)kubectl run tmp--rm-it--image=nicolaka/netshoot --curl-smy-svc:<port>/health# 5. 查 NetworkPolicykubectl get networkpolicy-n<ns>

小结

Service 打不通不是玄学,它就是一条固定的数据流,断点无非这几处:

  • Endpoints 为空:selector 和 Pod label 没对上——最高频,先查这个。
  • 端口错位:targetPort必须等于容器真实监听端口;应用别 bind127.0.0.1,要0.0.0.0
  • DNS:ClusterIP 通、域名不通,查 CoreDNS 和跨 namespace 全名。
  • kube-proxy / CNI:ClusterIP 都不通,查每个节点的 kube-proxy。
  • NetworkPolicy:全对还不通,查有没有 default-deny 悄悄拦截。

记忆点:永远从kubectl get endpoints开始——后端列表是空还是有,一眼就把问题劈成「选不中 Pod」和「网络路径」两半,剩下的顺着数据流往下走就行。

http://www.jsqmd.com/news/1300543/

相关文章:

  • 2026深圳黄金回收实测调研:走访106家本地老牌,避开4大本地变现套路 - 日常比对手册
  • 终极宽屏解决方案:5分钟让《植物大战僵尸》完美适配现代显示器
  • 有没有好用的Office插件推荐?老师们日常备课提升效率用的
  • 2026年菏泽全屋整装挑选攻略 附优客逸居等企业实测梳理 - 资讯在线
  • Wireshark安全分析实战:从流量抓取到攻击链还原
  • 3分钟搞定Windows ADB Fastboot驱动安装:告别设备连接烦恼的终极指南
  • 长沙黄金回收避坑指南,看懂这些套路不卖亏! - 一日一测评
  • 弱网适配表现优异十六型人格测试渠道汇总,安卓苹果全机型兼容,老旧手机流畅运行 - 时讯资讯
  • 珠海口碑真空包装机,双诚智能助力高效包装解决方案
  • 终极指南:如何用GoldHEN Cheats Manager轻松管理1490+款PS4游戏作弊代码
  • 寄大件哪个物流公司最便宜?2026大件物流价格深度对比攻略 - 快递物流资讯
  • 2026金华东阳永康中巴大巴公司团建婚车租赁包车盘点 - LYL仔仔
  • 传统翻译评估为何总是失准?COMET为你重新定义机器翻译质量评估
  • 如何快速掌握通达信缠论分析:ChanlunX插件的完整使用指南
  • AI推动工业智能化转型~系列文章04:机器学习体系总览:监督、无监督与强化学习的工业映射
  • GPT-SoVITS v4:基于1分钟语音的高质量语音克隆技术完全指南 [特殊字符]
  • ComfyUI智能修复革命:三步搞定AI图像局部修复,效率提升80%
  • 2026年度权威高速伺服电机公司供应链能力测评与实战选型指南 - 品牌报告
  • Android APK二次打包实战:修改包名与配置的完整工具链与流程
  • 全屋定制橡胶木板材十大品牌?为什么他不在榜单中? - 趣闻早乐评
  • Prompt Engineering:让LLM听懂你的话 — 从硬编码到模板化到多段式
  • 从音频分析到3D渲染:专业舞蹈视频制作全链路技术解析
  • 代码随想录算法训练营第七天 | 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字
  • 字母编码记忆法:用图像与故事攻克英语单词拼写难题
  • Python字典get()方法详解:告别KeyError,实现安全取值
  • 从避坑要点到实操步骤:结婚证公证线上办理全能指南
  • 测评数据本地加密留存不上传云端|MBTI 安全自测榜单,全方位降低隐私泄露风险 - 时讯资讯
  • 2026 年苏州上门测漏服务怎么选?精准定位不用瞎砸,5 家实测对比 - 趣闻早乐评
  • 终极免费音频转换器指南:fre:ac如何让音乐格式转换变得简单快速
  • C#操作Excel全攻略:COM、NPOI、EPPlus、OpenXML与云API深度对比