Kubernetes新手求助:如何阻止不同命名空间间的Pod与Service通信?
嘿,刚接触Kubernetes网络是吧?这个跨命名空间隔离的需求其实用Kubernetes自带的NetworkPolicy就能完美解决,这是管控Pod间流量的标准方式,我给你一步步讲清楚怎么做。
前提条件
首先得确认你的Kubernetes集群使用的CNI插件支持NetworkPolicy,比如Calico、Cilium,或者开启了NetworkPolicy支持的Flannel。如果用的是默认的基础CNI配置,可能需要先切换或配置支持的插件,否则NetworkPolicy不会生效。
核心思路
Kubernetes默认允许所有Pod互相通信,所以我们需要给每个要隔离的命名空间创建NetworkPolicy:
- 明确允许同一命名空间内的所有Pod双向通信(入站+出站)
- 拒绝所有跨命名空间的流量(没有匹配规则的流量会被默认拒绝)
步骤1:创建命名空间隔离的NetworkPolicy
针对namespace-a的配置
创建一个名为networkpolicy-namespace-a.yaml的文件,内容如下:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: restrict-cross-namespace namespace: namespace-a spec: podSelector: {} # 匹配namespace-a下的所有Pod policyTypes: - Ingress # 管控入站流量 - Egress # 管控出站流量 ingress: - from: - podSelector: {} # 允许来自同一命名空间的任意Pod的入站流量 egress: - to: - podSelector: {} # 允许发往同一命名空间的任意Pod的出站流量
针对namespace-b的配置
复制上面的yaml,把metadata.namespace改成namespace-b,保存为networkpolicy-namespace-b.yaml即可。
步骤2:添加DNS访问例外(可选但推荐)
上面的配置会阻止Pod访问kube-system命名空间的DNS服务,导致Pod无法解析my-svc.namespace-x.svc.cluster.local这类域名。如果需要保留DNS功能,修改NetworkPolicy添加DNS访问规则:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: restrict-cross-namespace-with-dns namespace: namespace-a spec: podSelector: {} policyTypes: - Ingress - Egress ingress: - from: - podSelector: {} egress: # 允许同命名空间通信 - to: - podSelector: {} # 允许访问kube-system的DNS服务 - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53
同样给namespace-b应用这个带DNS规则的配置。
步骤3:应用NetworkPolicy
执行以下命令把配置应用到集群:
kubectl apply -f networkpolicy-namespace-a.yaml kubectl apply -f networkpolicy-namespace-b.yaml
验证配置是否生效:
# 查看namespace-a的NetworkPolicy kubectl get networkpolicies -n namespace-a # 查看详细规则 kubectl describe networkpolicy restrict-cross-namespace -n namespace-a
测试隔离效果
在namespace-a的某个Pod里尝试访问namespace-b的Service:
kubectl exec -it <pod-name-in-namespace-a> -n namespace-a -- curl my-svc.namespace-b.svc.cluster.local正常情况下应该会超时或连接失败。
访问同命名空间的Service:
kubectl exec -it <pod-name-in-namespace-a> -n namespace-a -- curl my-svc.namespace-a.svc.cluster.local应该能正常访问。
注意事项
- 如果后续需要允许某些特定的跨命名空间通信(比如某个Pod需要访问另一个命名空间的数据库),可以在NetworkPolicy的
ingress或egress规则里添加对应的podSelector或namespaceSelector来例外放行。 - 不同CNI插件对NetworkPolicy的支持细节可能略有差异,如果遇到问题可以查看对应插件的文档调整规则。
内容的提问来源于stack exchange,提问作者mitchkman




