资讯动态

Kubernetes生产运维06:Service访问不通,怎么顺着EndpointSlice和kube-proxy找到断点

发布时间:2026/8/27 20:41:54 来源:尧图企业网站定制
Kubernetes生产运维06Service访问不通怎么顺着EndpointSlice和kube-proxy找到断点写在前面Service访问不通时常见的第一反应是怀疑网络出了问题然后开始抓包、重启kube-proxy或者重建Service。但Service只是一层抽象它把稳定的访问入口和一组随时变化的Pod关联起来。请求从客户端到达真正的容器中间要经过DNS解析、ClusterIP、Service、EndpointSlice、kube-proxy规则、Pod就绪状态、容器端口还可能受NetworkPolicy约束。任何一段断了表现都是访问不通但根因和修复完全不同。因此Service排查要沿着这条链路逐段确认断点在哪访问不通 → 确认要访问的Service和端口是什么 → Service是否有Endpoint → 没有EndpointSelector不匹配还是Pod未就绪 → 有Endpoint端口、kube-proxy、NetworkPolicy还是应用本身 → 定位断点后针对性修复 → 补链路监控与配置校验本文按照Kubernetes官方机制和命令参考整理。由于当前没有连接可验证的实验集群命令没有在统一版本的真实集群完整执行案例和终端输出均为C级生产化重建不是生产原始记录。不同Kubernetes版本、CNI插件、kube-proxy模式、DNS实现和云厂商可能改变字段、命令和行为执行前应以目标集群的kubectl explain、命令帮助和实际状态为准。一、先理解Service到Pod的链路1.1 EndpointSlice是Service和Pod之间的名册对于带Selector的Service控制平面会自动创建EndpointSlice其中引用所有匹配Selector且就绪的Pod。kube-proxy根据这些端点在节点上编程转发规则DNS把Service名解析到ClusterIP。这条链路里有几个关键事实Service通过Selector选择Pod匹配关系体现在EndpointSlice里。只有通过就绪检查的Pod才会作为可用端点被加入。一个Service可能对应多个EndpointSlice需要合并看全部端点。kube-proxy把端点转成内核转发规则规则没生效时即使有端点也连不上。1.2 没有Endpoint和连接被拒是两回事两种现象都表现为访问不通但断点位置不同现象含义断点位置Service没有Endpoint没有匹配且就绪的后端PodSelector或Pod就绪连接超时请求发出后没有响应网络策略、路由、kube-proxy或节点网络连接被拒绝目标可达但端口上无人监听或拒绝端口不匹配、容器未监听、应用拒绝先判断是落空没有后端还是被拒/超时有后端但连不上能快速把排查范围减半。1.3 端口的三段对应Service访问涉及三个端口必须一一对应Service的port客户端访问Service用的端口。Service的targetPort转发到Pod上的端口。容器的containerPort与实际监听端口应用真正监听的端口。targetPort要对上Pod实际监听的端口。如果targetPort写错或应用监听的端口和声明不一致即使有端点也会连接被拒或超时。二、Service排查决策树访问不通 │ ├─ 确认目标Service、命名空间和端口 │ ├─ Service有Endpoint吗 │ ├─ 无端点 │ │ ├─ Selector与Pod标签不匹配 │ │ ├─ Pod未就绪Readiness失败 │ │ └─ Pod不存在或不在同命名空间 │ └─ 有端点 │ ├─ 端口/targetPort不匹配 → 连接被拒 │ ├─ NetworkPolicy拦截 → 超时 │ ├─ kube-proxy规则未生效 → 超时 │ └─ 应用本身错误 → 有响应但报错 │ ├─ 定位断点后针对性修复 │ └─ 补链路监控与校验先用一条命令区分有没有端点NSnamespaceSVCservice-namekubectl get endpointslices-n$NS-lkubernetes.io/service-name$SVC-owide有就绪端点则往端口、策略、kube-proxy查没有端点则往Selector和Pod就绪查。三、取证逐段确认3.1 确认Service本身kubectl get svc$SVC-n$NS-owide kubectl describe svc$SVC-n$NS关注Type、ClusterIP、Portsport和targetPortSelectordescribe底部的Endpoints一行是否为空3.2 确认端点kubectl get endpointslices-n$NS-lkubernetes.io/service-name$SVC\-ocustom-columnsNAME:.metadata.name,ADDRESSES:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready,PORTS:.ports[*].port如果没有任何EndpointSlice或地址为空是没有端点分支。如果有地址但ready为false说明匹配到了Pod但未就绪。3.3 没有端点查Selector和就绪对比Service的Selector和Pod的标签kubectl get svc$SVC-n$NS-ojsonpath{.spec.selector}{\n}kubectl get pods-n$NS--show-labels kubectl get pods-n$NS-lselector-from-service-owide用Service的Selector去筛Pod如果筛不到是Selector不匹配。如果筛得到但READY不是全就绪是Pod未就绪转向Readiness探针和应用启动。3.4 有端点查端口、策略和kube-proxykubectl get svc$SVC-n$NS\-ojsonpath{range .spec.ports[*]}{.name}{ port}{.port}{ targetPort}{.targetPort}{\n}{end}kubectl get podbackend-pod-n$NS\-ojsonpath{range .spec.containers[*]}{.name}{ ports}{.ports}{\n}{end}kubectl get networkpolicy-n$NStargetPort要对上Pod实际监听端口。有NetworkPolicy时确认是否放行了来源到该端口的流量。如果端口和策略都正常仍超时再查kube-proxy和节点网络这类问题往往需要节点侧和CNI排查属于更深一层。3.5 边界kubectl get endpointslices受版本和权限影响旧集群也可用kubectl get endpoints作为补充视角。NetworkPolicy行为取决于CNI是否支持未安装支持的CNI时策略可能不生效。抓包和内核规则排查会改变现场或需要节点权限属于只读命令之后的深入手段。四、常见断点与判断现象更可能的断点优先检查不能直接得出的结论Service无EndpointSelector筛不到PodSelector或Pod标签错Service selector与Pod labels不一定是网络问题Service无EndpointPod能筛到但未就绪Readiness未通过Readiness探针、应用启动不一定是Service配置错有Endpoint但连接被拒targetPort或监听端口不符targetPort与容器实际监听不一定是应用崩溃有Endpoint但连接超时NetworkPolicy或网络NetworkPolicy、CNI、kube-proxy不一定是应用无响应有响应但返回错误应用本身应用日志、依赖不一定是Service链路问题跨命名空间访问不通DNS名或策略FQDN、NetworkPolicy命名空间选择器不一定是Selector问题一个关键区分没有Endpoint时问题几乎一定在Service到Pod的关联Selector或就绪而不在更下层的网络有Endpoint但不通时才需要往端口、策略和网络查。先看端点能避免一开始就抓包走弯路。五、C级生产化重建案例改了标签后Service突然没有后端5.1 先说明哪些是真的哪些是重建的下面不是作者声称亲历的生产事故而是根据Kubernetes Service、Selector和EndpointSlice机制构造的生产化重建用于展示从访问不通走到可验证根因的取证过程。内容证据属性Service、Selector、EndpointSlice和就绪端点之间的机制Kubernetes官方机制改动标签后Service端点变空、访问返回无后端机制一致的重建场景Namespace、资源名、标签、相对时间和终端输出为讲解构造的说明性信息Deployment模板的Pod标签被改动模拟根因不是作者生产记录修正单一变量后验证端点恢复受控验证设计不声称已在当前集群执行所有输出按真实对象关系编排但没有连接实际集群采集读者不能把下面的时间、标签或输出引用为真实事故数据。5.2 现场卡片一次发布后某内部服务的调用方开始报连接失败。被调用的Deployment Pod看起来都在Running。团队最初怀疑是网络或kube-proxy问题。重建的相对时间线相对时间观察或动作当时能够得出的结论T00发布更新Deployment只能确认发生了配置变更T02调用方报连接失败Pod仍Running访问不通原因未知T04有人怀疑网络或kube-proxy待验证假设T06查到Service没有任何Endpoint断点在Service到Pod关联不在下层网络T09对比Selector与Pod标签发现不一致得到可验证的主假设T验证只修正标签观察端点是否恢复单变量验证相对时间只表示排查顺序不代表真实恢复时长。5.3 先确认有没有端点NSexample-prodSVCorders-internal kubectl get svc$SVC-n$NS-owide kubectl get endpointslices-n$NS-lkubernetes.io/service-name$SVC\-ocustom-columnsNAME:.metadata.name,ADDRESSES:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready机制一致的说明性输出NAME TYPE CLUSTER-IP PORT(S) SELECTOR orders-internal ClusterIP 10.96.12.34 80/TCP apporders,tierapi NAME ADDRESSES READY orders-internal-abcde none noneService存在、有ClusterIP但EndpointSlice没有任何地址。这把断点直接定位到Service与Pod的关联不是下层网络或kube-proxy。因此先不抓包。5.4 判断是Selector不匹配还是未就绪kubectl get svc$SVC-n$NS-ojsonpath{.spec.selector}{\n}kubectl get pods-n$NS-lapporders --show-labels kubectl get pods-n$NS-lapporders,tierapi-owide机制一致的说明性输出map[app:orders tier:api] NAME READY STATUS LABELS orders-api-newhash-a1 1/1 Running apporders,tierbackend orders-api-newhash-b2 1/1 Running apporders,tierbackend 使用 apporders,tierapi 精确筛选 No resources found in example-prod namespace.关键发现Pod都是Running且Ready不是就绪问题。Service的Selector要求tierapi但Pod标签是tierbackend。用Service的完整Selector精确筛选筛不到任何Pod。因此不是网络问题也不是Pod未就绪而是Selector与Pod标签不匹配导致EndpointSlice为空。5.5 对比新旧模板确认来源helm list-n$NShelm get valuesrelease-name-n$NSrelease-values.yamlgrep-n-A3labelsrelease-values.yamlgitdiffknown-good-ref..candidate-ref-- values-prod.yaml机制一致的说明性差异labels: app: orders - tier: api tier: backend证据链Service存在且有ClusterIP EndpointSlice为空 Pod都Running且Ready Service Selector要求tierapi 本次发布把Pod标签tier改成backend 用完整Selector筛不到Pod 强烈支持本次标签改动导致Service失去后端这仍是主假设验证前不写成根因已闭环。5.6 止损与单变量验证调用方正在报错最安全的止损通常是回滚到已知可用版本或在变更窗口修正标签。两者都属于变更操作执行前确认可用副本、PDB、maxUnavailable、maxSurge、兼容性和可回退版本。修正时只把Pod模板标签tier改回api不同时改Service Selector、端口和其他配置同时改两端会让人无法判断到底哪边错spec:template:metadata:labels:app:orderstier:api验证并保存修复后证据kubectl rollout status deployment/orders-api-n$NS--timeout5m kubectl get endpointslices-n$NS-lkubernetes.io/service-name$SVC\-ocustom-columnsNAME:.metadata.name,ADDRESSES:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready,PORTS:.ports[*].port机制一致的说明性输出deployment orders-api successfully rolled out NAME ADDRESSES READY PORTS orders-internal-abcde 10.244.1.7,10.244.2.9 true,true 8080端点恢复后从集群内做一次连通性确认kubectl run netcheck--rm-it--restartNever-n$NS\--imageapproved-debug-image--\sh-cwget -qO- --timeout3 http://orders-internal.example-prod.svc/healthz这条命令会临时创建一个调试Pod属于主动操作需使用经审批的调试镜像并在完成后清理。它用于确认链路已通不是必需步骤。这些输出分别证明不同范围的事实输出能够支持不能单独证明rollout成功Deployment滚动完成所有调用方立即恢复EndpointSlice有就绪地址Selector重新匹配到就绪Pod端口和策略一定都正确连通性探测成功该路径当前可达所有来源和端口都放行5.7 根因闭环条件修正版与失败版只有Pod标签这一项主要差异。修正后EndpointSlice重新出现就绪地址。Service Selector未改动说明是Pod侧标签错。调用方连接恢复。观察窗口内端点稳定没有再次变空。如果修正标签后仍无端点就要停止把标签当作唯一原因重新检查就绪探针、命名空间和Selector两端。六、修复方案要分六层层次本文场景中的动作关键边界应急止损回滚到已知可用版本或修正标签先查可用副本、PDB、兼容性和回退版本现场取证保存Service、EndpointSlice、Pod标签、端口和NetworkPolicy端点和标签随发布变化尽快留存根因验证只改一端的一个变量并观察端点恢复不同时改Pod标签和Service Selector永久修复修正Git或Helm源配置的标签或Selector防止下次发布再次改错监控预防监控Service端点数、就绪比例和连接失败端点为0应触发告警运行治理标签与Selector一致性校验、端口约定、发布校验标签契约纳入模板校验临时恢复不等于根因确认。端点恢复只说明变更与故障相关仍需配置差异、端点变化和单变量验证共同支撑。不要在没看端点前就抓包或重启kube-proxy。没有端点时问题在关联层重启网络组件无效还可能扩大影响。七、可直接使用的只读Service采集脚本脚本只读取对象不修改Service、不改标签、不重启组件、不创建调试Pod。#!/usr/bin/env bashset-uset-opipefailNS${1:?用法:$0 namespace service-name}SVC${2:?用法:$0 namespace service-name}STAMP$(date%Y%m%d-%H%M%S)OUTsvc-evidence-${NS}-${SVC}-${STAMP}mkdir-p$OUTumask077capture(){localfile$1shiftprintf采集 %s\n$fileif!$$OUT/$file2$OUT/$file.err;thenprintf失败: %s查看 %s.err\n$file$file2fi}capture context.txt kubectl config current-context capture version.txt kubectl version capture service.yaml kubectl get svc$SVC-n$NS-oyaml capture service-describe.txt kubectl describe svc$SVC-n$NScapture selector.txt kubectl get svc$SVC-n$NS\-ojsonpath{.spec.selector}{\n}capture ports.txt kubectl get svc$SVC-n$NS\-ojsonpath{range .spec.ports[*]}{.name}{ port}{.port}{ targetPort}{.targetPort}{ protocol}{.protocol}{\n}{end}capture endpointslices.txt kubectl get endpointslices-n$NS\-lkubernetes.io/service-name$SVC-owide capture endpointslices.yaml kubectl get endpointslices-n$NS\-lkubernetes.io/service-name$SVC-oyaml capture pods.txt kubectl get pods-n$NS--show-labels-owide capture networkpolicy.yaml kubectl get networkpolicy-n$NS-oyamlprintf采集完成: %s\n$OUTprintf如需连通性测试请另用经审批镜像的临时Pod属于主动操作\nprintf分享前请检查地址、标签、镜像和策略中的敏感信息\n使用方式bashcollect-svc-evidence.shnamespaceservice-name脚本边界只做只读采集连通性测试需另行创建临时Pod属于主动操作endpointslices受版本和权限影响旧集群可补充kubectl get endpointsNetworkPolicy是否生效取决于CNI采集到策略不代表一定被执行脚本用于保存首轮现场不能替代按端点结果选择下一步八、监控、就绪与治理8.1 监控什么每个Service的就绪端点数量端点为0应告警就绪Pod比例与Readiness探针失败服务间连接失败率和超时率NetworkPolicy变更与拒绝计数若CNI支持发布前后端点数量对比告警不能只监控Pod是否Running。Pod Running但未就绪、标签改错、端口不符都会让端点为空或不通需要以端点数量和连接成功率为准。8.2 发布前校验Pod模板标签与Service Selector保持一致Service的targetPort与容器实际监听端口一致命名空间内外访问用正确的Service名或FQDNNetworkPolicy放行必要的来源和端口变更标签或Selector时同时检查两端8.3 契约与治理把标签和端口作为服务契约的一部分纳入模板校验Selector和Pod标签由同一模板生成避免两端漂移关键服务配置端点数量告警快速发现失去后端建立Service排障Runbook先看端点再看网络九、常见误区误区1一访问不通就抓包或重启kube-proxy先看端点。没有端点时问题在关联层抓包和重启网络组件无效。误区2Pod是Running就以为一定是后端只有就绪的Pod才会成为端点。Running不等于Ready。误区3只改一端标签或Selector改错的一端和排查时改动的一端要一致同时改两端会掩盖真正问题。误区4忽略targetPort与实际监听端口端口对不上会连接被拒即使有端点也不通。误区5忘了NetworkPolicy有端点但超时可能是策略拦截尤其是默认拒绝的命名空间。误区6跨命名空间用短名跨命名空间要用带命名空间的名字或FQDN否则解析不到。误区7把连接被拒和连接超时混为一谈被拒是端口层面超时更多是策略或网络处理路径不同。误区8只看Service不看EndpointSliceService配置正确但端点为空时问题在Selector或就绪不看端点会漏判。十、面试怎么说60秒版本Service不通我不会先抓包。先确认要访问的Service和端口再看有没有Endpoint。没有端点几乎一定是Selector不匹配或Pod未就绪我用Service的Selector去筛Pod筛不到就是标签错筛得到但没就绪就查Readiness。有端点还不通才往targetPort、NetworkPolicy和kube-proxy查区分连接被拒和连接超时。修复只改一端一个变量并观察端点恢复最后补端点数量和连接成功率监控。3分钟场景版本假设发布后调用方连接失败被调Pod都Running。我先看这个Service的EndpointSlice发现没有任何地址这就把断点定位到Service与Pod的关联不用去抓包。我用Service的Selector精确筛Pod筛不到再看Pod标签发现这次发布把tier从api改成了backend而Service Selector还是tierapi所以端点变空。我确认Pod都Ready排除就绪问题然后回到Helm和Git确认是Pod模板标签改错。我只把Pod标签改回api不动Service Selector和端口滚动完成后EndpointSlice重新出现就绪地址调用恢复。这样我能区分是标签契约问题而不是网络故障也不会用重启kube-proxy这种无关动作去掩盖配置错误。十一、延伸问答1. Service没有Endpoint一定是Selector错吗不一定。也可能是匹配到的Pod未就绪或Pod不在同一命名空间。要先用Selector筛Pod再看就绪状态。2. Pod是Running为什么不在端点里只有通过Readiness的Pod才会作为可用端点。Running不等于Ready。3. 连接被拒和连接超时怎么区分处理被拒通常是端口层面查targetPort和监听端口超时更多是NetworkPolicy或网络查策略和CNI。4. 一个Service会有多个EndpointSlice吗会。端点较多时会分片需要按service-name标签合并看全部端点。5. 改了Selector后要注意什么Selector和Pod标签是两端契约改一端就要同步另一端否则端点会变空。6. NetworkPolicy会导致有端点但不通吗会。默认拒绝的命名空间里没有放行规则的流量会被拦截表现为超时。7. 跨命名空间访问要注意什么要用带命名空间的Service名或FQDN并确认NetworkPolicy放行了对方命名空间。8. 什么时候才需要抓包和查kube-proxy在确认有就绪端点、端口正确、策略放行之后仍不通时才深入节点网络、kube-proxy和CNI。小结Service只是抽象请求要经过DNS、ClusterIP、EndpointSlice、kube-proxy、端口和策略多段。排查先看有没有Endpoint能把范围直接减半。没有端点几乎一定在Selector或Pod就绪不在下层网络。有端点不通才查targetPort、NetworkPolicy和kube-proxy。连接被拒和连接超时断点不同处理不同。标签和Selector是两端契约改一端要同步另一端。修复只改一端一个变量并观察端点恢复。长期治理覆盖标签契约、端口约定、端点监控和排障Runbook。下一篇预告下一篇进入CoreDNS与域名解析故障。我们会沿着DNS链路、解析超时、缓存、上游DNS和ndots配置区分解析失败、解析慢和解析到错误地址并整理一份DNS排查清单。参考资料Kubernetes官方文档ServiceKubernetes官方文档EndpointSlicesKubernetes官方文档Debug ServicesKubernetes官方文档Connecting Applications with ServicesKubernetes官方文档Virtual IPs and Service ProxiesKubernetes官方文档Network PoliciesKubernetes官方文档Liveness, Readiness and Startup ProbesKubernetes官方文档DNS for Services and PodsKubernetes官方文档Service Internal Traffic PolicyKubernetes官方文档Debug Running Pods

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价