加了条 NetworkPolicy,消息队列直接断了——K8s 默认拒绝挨的第一刀
场景:给支付服务加了一条 NetworkPolicy——只允许订单服务访问 8080。支付接口正常了,但订单突然收不到支付回调——不是代码改了,是订单到支付的异步消息走的是 RabbitMQ(5672 端口),被 NetworkPolicy 一视同仁拦了 路径:坐标(现象:HTTP 正常、MQ 超时)→ 分层(Pod → Service → NetworkPolicy → 理解默认拒绝行为)→ 路径(3 条命令排查)→ 定位(查 MQ 配了两小时,根因在 NetPol)→ 标点(修复 + Check-list) K8s 版本:v1.28,Calico CNI
上篇讲跨 Namespace 调用时提到了一个关键认识——K8s 不是只拦跨 Namespace 的流量,同 Namespace 内,一条 NetworkPolicy 也能把自己人拦在门外。
给支付服务加了一条 NetworkPolicy——只允许订单服务访问 8080。支付接口正常了,但订单突然不发货了。不是代码改了,是订单到支付的异步消息走的是 RabbitMQ(5672 端口),被 NetworkPolicy 一视同仁拦了。
你不是多配了一个端口——是你忘了 NetworkPolicy 的默认原则:只允许显式声明的,拒绝其他所有。
【坐标】现象:HTTP 正常、MQ 超时
结论前置:服务在跑、端口不同、一个通一个不通
order-service 调用 payment-service——HTTP(8080)一切正常,但异步消息(RabbitMQ,5672)一直超时。

2026-07-10 14:32:18.123 ERROR [order-service] o.s.a.r.c.CachingConnectionFactory : Channel shutdown: connection error
2026-07-10 14:32:18.124 ERROR [order-service] c.o.order.service.PaymentGateway : Failed to send message to payment.queue: timeout after 30000ms
2026-07-10 14:32:18.125 WARN [order-service] c.o.order.service.PaymentGateway : Retrying... attempt 2/3
证据展开:看 Pod 状态、看 Service、看 Endpoints
Pod 确认 Running:
kubectl get pod -n production -l app=payment-service -o wide
# NAME READY STATUS RESTARTS AGE IP NODE
# payment-service-5d8f9c6b4-j2k9s 2/2 Running 0 12h 10.244.2.15 node-2
Service 正常、Endpoint 有 IP:
kubectl get svc -n production rabbitmq
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# rabbitmq ClusterIP 10.96.123.45 <none> 5672/TCP 30d
kubectl get endpoints -n production rabbitmq
# NAME ENDPOINTS AGE
# rabbitmq 10.244.1.15:5672 30d
开发的第一反应:"RabbitMQ 连不上了——连接字符串写错了?认证配错了?Vhost 不对?"
衔接:Service 有 IP,Pod 也正常——那问题在哪一层?
IP 能解析、Service 有 Endpoint、Pod 在 Running——问题不在应用层,在中间的流量控制层。
【分层】逐层排查:从 Pod 日志到 NetworkPolicy

排查顺序
| 层级 | 命令 | 关键输出 |
|---|---|---|
| ① Pod 层 | kubectl logs kubectl describe pod |
MQ 超时、无异常 Event |
| ② Service 层 | kubectl get svc / endpoints |
RabbitMQ 正常,Endpoint 有 IP |
| ③ 网络层 | kubectl get networkpolicy --all-namespaces |
一条 NetPol 只配了 8080 |
| ④ 深入 | kubectl describe networkpolicy |
PolicyTypes: Ingress,ports: [8080] |
第一层:Pod——日志明确说"连接被关"
kubectl logs payment-service-5d8f9c6b4-j2k9s -n production -c payment

2026-07-10 14:32:20.001 INFO [payment-service] o.s.a.r.l.SimpleMessageListenerContainer : Broke connection to rabbitmq.production.svc:5672
2026-07-10 14:32:20.002 ERROR [payment-service] o.s.a.r.l.SimpleMessageListenerContainer : Could not connect to RabbitMQ: connection timed out
Payment 连 RabbitMQ 也超时。这不是"order 发不出去"——是 order 发、payment 收,两边都连不上。
kubectl describe pod 看 Events:没有 OOM、没有 FailedScheduling、没有 CrashLoopBackOff。Events 干干净净。
第二层:Service——DNS 和 Endpoint 没问题
kubectl get svc -n production -o wide
# NAME TYPE CLUSTER-IP PORT(S) SELECTOR
# rabbitmq ClusterIP 10.96.123.45 5672/TCP app=rabbitmq
# order-service ClusterIP 10.96.100.1 8080/TCP app=order-service
# payment-service ClusterIP 10.96.100.2 8080/TCP app=payment-service
kubectl get endpoints -n production rabbitmq -o wide
# NAME ENDPOINTS AGE
# rabbitmq 10.244.1.15:5672 30d
DNS 能解析、Endpoint 有 Pod IP。Service 层没问题。
第三层:网络——发现 NetworkPolicy 只显式允许了 8080
kubectl get networkpolicy --all-namespaces
NAMESPACE NAME POD-SELECTOR AGE
production allow-order-to-payment app=payment 2h

看到问题了吗——Ports 只列了 8080/TCP,没有 5672。但 Service 的 HTTP(8080)能通,说明"不是全不通,是部分不通"。关键区别就在这里。
第四层:理解 NetworkPolicy 的默认拒绝
Pod 匹配了 NetworkPolicy 的 podSelector 之后,只允许 Policy 中显式声明的入站流量,其他所有入站流量都被拒绝。
NetworkPolicy — K8s 的网络访问控制资源。当一个 Pod 被 NetworkPolicy 选中(匹配 podSelector),该 Pod 的入站/出站流量就受 Policy 约束——只允许规则中显式声明的流量,其他全拒绝。
payment-service 的 Pod 被 allow-order-to-payment 选中了(app=payment-service),所以它的入站流量只允许:
- 来自 app=order-service 的 Pod
- 目标端口 8080
5672 不在允许列表中 → 被 K8s 网络插件(这里是 Calico)默默丢弃。
这解释了为什么: - HTTP 8080 能通 ✅ — 在规则中 - MQ 5672 不通 ❌ — 不在规则中
【路径】🔍 排查 NetworkPolicy 的 3 条命令
结论前置:三板斧测到底

衔接:命令链即排查思路
<< 排查口诀 >> HTTP 通 + MQ 不通 + 同一 Service → 中间层在过滤端口
以上三条命令按顺序执行:先发现有哪些 NetPol → 再看具体规则 → 最后验证标签匹配。任何 NetworkPolicy 问题都能在 2 分钟内定位到原因。
【定位】最常误判:查 MQ 配了两小时,根因在 NetPol
❌ 错误排查方向:RabbitMQ 配置错了
小张是订单服务的 Owner,看到 MQ 超时的第一时间就去翻代码——"连接字符串没配错啊"。然后查 RabbitMQ 管理界面——"认证通过了啊"。然后查 Vhost——"也对啊"。然后看日志——"channel shutdown——
看代码 → 连接字符串配对了?
看配置 → Vhost 配对了?
看认证 → 用户名密码对了?
看日志 → "channel shutdown"(连接关闭)
→ 再查一遍连接字符串 → 再看一遍认证
循环了 2 个小时,什么都没改。
✅ 正确排查方向:流量被 NetworkPolicy 拦了
关键问题是:HTTP 能通,MQ 不通——同一个 Pod、不同的端口。
把问题反过来想:如果 MQ 配置真的错了,应该 HTTP 也不通(或至少不是这个现象)。HTTP 通 + MQ 不通 + 同一条 Service 链路 = 中间层在过滤端口。
敲这个命令直接验证:
kubectl describe networkpolicy -n production allow-order-to-payment
看到 Ports: [8080] 的那一刻,根因就清楚了——不是 MQ 连不上,是流量到不了 MQ。
【标点】修复 + Check-list
修复:在 NetworkPolicy 中添加 MQ 端口

记住:一个 YAML 字段没配,不是 K8s 会帮你兜底——是它会按默认值运行,而默认值往往不适合你的场景。
NetworkPolicy 排查 Check-list
□ kubectl get networkpolicy --all-namespaces
→ 列出所有 NetPol,确认目标 Pod 是否被任何 Policy 选中
□ kubectl describe networkpolicy <name> -n <ns>
→ 查看 Policy 的 ports 列表、podSelector、namespaceSelector
→ 检查是否覆盖了所有需要的端口
□ kubectl get pod -n <ns> --show-labels
→ 确认 Pod 标签是否与 podSelector 匹配
→ 不匹配 = Pod 不受此 Policy 管理
□ 反向验证:kubectl exec -it <pod> -n <ns> -- curl -v <target-ip>:<port>
→ 直接到 Pod 网络命名空间里验证连通性
→ 通 = NetworkPolicy 以外的原因;不通 = 大概率 NetPol
附:完整命令清单
# NetworkPolicy 排查三板斧
kubectl get networkpolicy --all-namespaces
kubectl describe networkpolicy <name> -n <namespace>
kubectl get pod -n <namespace> --show-labels
# 容器内连通验证
kubectl exec -it <pod> -n <namespace> -- curl -v <target-ip>:<port> -m 5
# 目标 Pod 日志(看是否有入站连接)
kubectl logs -n <namespace> -l app=<target-app> --tail=50
# 查看 K8s 网络插件是否正常工作(Calico 示例)
kubectl get pods -n kube-system -l k8s-app=calico-node
下篇我们聊 NodePort 端口冲突——同一个端口被多个 Service 映射,谁也起不来。
🔗 个人博客:https://opencao.cn
📺 公众号:Ai拆代码的曹操
🌟 知识星球:Ai拆代码的曹操