NetworkPolicy 默认仅在定义它的命名空间内生效,跨命名空间隔离需在目标命名空间部署策略并使用namespaceSelector匹配来源命名空间标签;空namespaceSelector或误用系统标签将导致策略失效。

NetworkPolicy 本身不能直接“跨命名空间”生效,它只作用于定义它的命名空间内;要实现跨命名空间隔离,必须在目标命名空间(即被访问方所在命名空间)部署策略,并用 namespaceSelector 或显式拒绝逻辑来控制来源。
为什么 NetworkPolicy 不会自动跨命名空间生效
NetworkPolicy 是命名空间作用域资源,Kubernetes 控制面只将策略应用于 metadata.namespace 字段指定的命名空间中的 Pod。即使你在 default 命名空间写了一条 “拒绝所有来自 prod 命名空间的流量” 的规则,它对 prod 中的 Pod 完全无效——因为那些 Pod 不在 default 里,也不被该策略的 podSelector 匹配。
真正起作用的,是部署在 prod 命名空间里的策略,它通过 from.namespaceSelector 限制谁可以连进来。
- 策略只影响它所在的命名空间内被
podSelector选中的 Pod -
from.namespaceSelector是用来“识别来源命名空间”的唯一标准方式,不是靠策略所在位置 - 没有网络插件支持,
NetworkPolicy资源只是 YAML,不会产生任何 iptables 或 eBPF 规则
如何用 namespaceSelector 实现跨命名空间白名单
假设你希望 app-ns 中的 Pod 只接受来自 frontend-ns 的 HTTP 流量,其他所有命名空间(包括 default)一律拒绝。
你需要在 app-ns 中创建如下策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: app-ns
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend-ns
ports:
- protocol: TCP
port: 80
注意关键点:
-
namespaceSelector.matchLabels必须匹配目标命名空间自身的labels,不是名称。所以先给frontend-ns打标:kubectl label ns frontend-ns name=frontend-ns - 这条策略没写任何
except或兜底拒绝规则,但效果已是“仅允许”,因为默认 ingress 是非隔离的,一旦加了任意 ingress 规则,就变成隔离模式,未匹配的流量自动被拒 - 如果还想允许本命名空间内通信,需额外加一条
from.podSelector: {}规则(空 selector 表示同 ns 所有 Pod)
常见错误:误用 empty namespaceSelector 或写错标签键
以下写法看似合理,实际完全失效:
from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: frontend-ns # ❌ 错误:metadata.name 不是用户可设 label
或更隐蔽的陷阱:
from:
- namespaceSelector: {} # ❌ 空 selector 匹配所有命名空间,等于没隔离
正确做法始终是:
- 确保目标命名空间已打上明确、唯一的 label(如
env=prod),且 label key 不含系统保留前缀 - 在 NetworkPolicy 中严格复用该 label key 和 value
- 用
kubectl get ns -L env验证 label 是否真实存在并拼写一致 - 避免依赖
name字段做匹配——NetworkPolicy 不读取命名空间的 name 字段,只读 label
拒绝所有跨命名空间流量的最简写法
如果你的目标就是“只允许本命名空间内通信,其他一概不通”,不需要逐个写 namespaceSelector,而是利用默认隔离行为:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: app-ns
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
这个策略的含义是:“只允许来自同一命名空间(即被 podSelector: {} 选中的 Pod)的流量”。它不涉及任何 namespaceSelector,却天然达成跨命名空间拒绝——因为其他命名空间的 Pod 不可能被当前命名空间的 podSelector 选中。
容易被忽略的一点是:podSelector: {} 在 from 中表示“同命名空间”,但在 spec.podSelector 中表示“本策略适用的所有 Pod”。二者语义不同,但都依赖命名空间边界。











