面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。
一、遭遇情况:能解析 Service,HTTP 却一直超时
应用名称可以解析,后端也 Ready,但客户端发起 HTTP 请求没有响应。一次网络策略变更后才开始出现,其他命名空间的某些客户端却仍能访问。
本篇案例是目标 Web Pod 被一份 ingress 隔离策略选中,但没有允许当前客户端访问。需要核对来源、目标、方向和端口,而不只是搜索策略里有没有“80”。
二、原因分析:策略对象存在,不代表当前网络实现会执行
NetworkPolicy 的执行依赖支持它的网络插件。API 允许创建该对象,不自动证明集群 CNI 已实施隔离。实验前应确认网络实现支持相应策略。

标准策略是允许规则叠加:多份选中相同 Pod 的策略,其允许流量会合并,不是后写的规则覆盖前一份。某方向未被选入隔离时,与被隔离后需要许可是不同状态。
客户端 egress 与服务端 ingress 都进入隔离时,流量通常需要双方各自允许。只在服务端放行,并不自动替客户端增加出口许可。
三、排查思路:看标签与实际方向
kubectl get networkpolicy -n 目标命名空间
kubectl get networkpolicy -n 目标命名空间 -o yaml
kubectl get pods -n 目标命名空间 --show-labels
kubectl get namespaces --show-labels
结合客户端和服务端两侧的命名空间检查,不要只读目标服务那一侧。podSelector 写在 policy 顶层时选择被保护的 Pod,写在 peer 中时选择相应来源或目标,语义位置不同。
同一个 peer 内的 namespaceSelector 与 podSelector 组合,和分成两个 peer 的允许范围也不同。缩进合法不代表逻辑正确,要把它翻译成“哪些命名空间里的哪些 Pod”。
四、实践:只隔离实验 Web 的入口
保存 kt11-networkpolicy.yaml。前提是集群支持并启用了 NetworkPolicy,且没有其他集群级规则干扰本实验。
apiVersion: v1
kind: Namespace
metadata:
name: kt11
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: kt11
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:stable-alpine
readinessProbe:
httpGet:
path: /
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: kt11
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-web-ingress
namespace: kt11
spec:
podSelector:
matchLabels:
app: web
policyTypes: [Ingress]
ingress: []
kubectl apply -f kt11-networkpolicy.yaml
kubectl rollout status deployment/web -n kt11 --timeout=120s
kubectl run client -n kt11 --image=busybox:1.37 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/client -n kt11 --timeout=120s
kubectl exec client -n kt11 -- nslookup web
kubectl exec client -n kt11 -- wget -T 3 -qO- http://web:80/
预期 DNS 正常、HTTP 被入口隔离阻止。若 HTTP 仍成功,先确认 CNI 执行能力、现有允许策略和测试流量路径,不应把成功解释为“NetworkPolicy 没用”。
五、修复实践:只允许带特定标签的本命名空间客户端
保存 kt11-allow.yaml:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-approved-clients
namespace: kt11
spec:
podSelector:
matchLabels:
app: web
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
access: approved
ports:
- protocol: TCP
port: 80
kubectl apply -f kt11-allow.yaml
kubectl label pod client -n kt11 access=approved
kubectl exec client -n kt11 -- wget -T 3 -qO- http://web:80/
预期允许该客户端访问。这里 peer 的 podSelector 没有 namespaceSelector,因此选择同一命名空间内匹配标签的 Pod,不是全群所有带该标签的 Pod。
六、验证:允许目标成功,不该放开的仍失败
再创建一个不带 access 标签的独立客户端,执行同样请求,应仍被阻止。然后核对 DNS 和其他必要依赖是否受影响。不要通过删除所有 NetworkPolicy 来证明应用能通,删规则会同时改变太多变量。
NetworkPolicy 通常不负责 HTTP 路径、用户身份和 TLS 内容授权;来源地址还可能受 NAT、控制器和网络实现影响。真实流量穿过 Ingress 控制器时,要按实际来源条件设计,而不是照搬终端客户端标签。
七、总结
排查顺序是:DNS 与端点是否正常 → 源和目标是谁 → 哪个方向被隔离 → 哪些允许规则适用 → 做最小放行 → 正反验证。最小修复不是“开放所有方向”,而是把必要业务路径表达准确。