Kubernetes 集群如何配置 NetworkPolicy 限制 Pod 间通信?

文章导读
在 Kubernetes 中配置 NetworkPolicy 是限制 Pod 间通信的标准做法,但前提是集群使用的 CNI 插件必须支持该功能,否则策略不会生效。
📋 目录
  1. A 工作原理与前置检查
  2. B 核心配置示例
  3. C 配置实施步骤
  4. D 验证与测试
  5. E 策略管理:查看与删除
  6. F 常见问题与风险
  7. G 参考来源
A A

在 Kubernetes 中配置 NetworkPolicy 是限制 Pod 间通信的标准做法,但前提是集群使用的 CNI 插件必须支持该功能,否则策略不会生效。

先说结论:NetworkPolicy 依赖 CNI 插件支持,配置前需先确认网络插件兼容性,建议从默认拒绝策略开始逐步放通。

  • 适合:需要实现微服务间访问控制、隔离 Namespace 或限制外部访问的场景
  • 先准备:确认 CNI 插件(如 Calico、Cilium)支持 NetworkPolicy 资源
  • 验收:通过临时 Pod 测试连通性,确保策略按预期拦截或放行流量

工作原理与前置检查

Kubernetes 默认的网络行为是“允许所有”,即任何 Pod 都可以互相通信,也可以访问外部网络。NetworkPolicy 的作用机制是“白名单”:一旦某个 Pod 被至少一个 NetworkPolicy 选中,它就会进入默认拒绝状态,只有通过规则明确允许的流量才能通过。

重要提示:NetworkPolicy 只是一个 API 资源,实际的网络隔离效果由集群的 CNI(容器网络接口)插件实现。如果插件不支持(例如默认配置的 Flannel),即使创建了策略,流量也不会被拦截。

1. 确认 CNI 插件支持

查看集群使用的网络插件,常见支持 NetworkPolicy 的插件包括 Calico、Cilium、Weave Net 等。如果是云厂商托管集群,通常默认支持,但需查阅对应文档确认。可使用以下命令查看节点网络信息辅助判断:

kubectl get nodes -o wide

核心配置示例

以下是一个默认拒绝所有入站流量的策略示例,应用后该 Namespace 下的 Pod 将无法被外部访问,除非另有允许策略。

警告:请勿直接在生产环境 Namespace 应用默认拒绝策略,除非已确认业务流量规则并已配置放行策略,否则会导致业务中断。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress

若需允许特定 Pod 访问,可补充如下允许策略:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-specific
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend

应用命令:

kubectl apply -f policy.yaml

配置实施步骤

1. 编写默认拒绝策略

为了安全起见,建议先在测试 Namespace 应用默认拒绝策略。注意 podSelector: {} 表示选中该 Namespace 下所有 Pod。

2. 编写业务允许策略

Kubernetes 集群如何配置 NetworkPolicy 限制 Pod 间通信?

根据业务调用链,编写允许特定标签 Pod 访问的策略。可以使用 podSelector 限制源 Pod,也可以使用 namespaceSelector 允许跨 Namespace 通信。

3. 应用策略

使用 kubectl apply 提交配置。建议先在非生产环境验证,确认无误后再推广。

验证与测试

创建一个临时 Pod 尝试访问目标服务,观察连接是否被阻断。

查看当前策略:

在应用前后,可查看当前 Namespace 下的策略列表:

kubectl get networkpolicy -n <namespace>

测试被拒绝的访问:

kubectl run -it `--rm` `--image`=busybox `--restart`=Never test-pod -- wget `--timeout`=2 http://<target-service-ip>

如果策略生效,连接会超时或显示 Connection refused。如果仍能通,说明策略未生效(可能是 CNI 不支持或标签选择器写错)。

测试被允许的访问:

给测试 Pod 打上允许策略中指定的标签,再次运行上述命令,应能正常返回 HTTP 响应。

策略管理:查看与删除

查看策略详情:

Kubernetes 集群如何配置 NetworkPolicy 限制 Pod 间通信?
kubectl describe networkpolicy <policy-name> -n <namespace>

删除策略:

若策略配置错误导致网络中断,需立即删除策略恢复通信:

kubectl delete networkpolicy <policy-name> -n <namespace>

若需临时禁用所有策略,可删除该 Namespace 下所有 NetworkPolicy 资源。

常见问题与风险

1. CNI 插件不支持

这是最常见的问题。例如使用 Flannel 插件时,默认不开启 NetworkPolicy 支持,需要更换插件或启用特定后端。

2. 命名空间隔离

NetworkPolicy 是 Namespace scoped 的资源。如果在 default 命名空间创建策略,不会影响其他命名空间的 Pod。跨命名空间访问需显式配置 namespaceSelector

3. 标签选择器错误

策略中的 podSelector 必须与 Pod 实际标签完全匹配。如果标签写错,策略可能选中了错误的 Pod,导致意外断网。

4. 出站流量未限制

默认策略通常只限制入站(Ingress)。如果需要限制 Pod 访问外部网络,需显式声明 policyTypes: ["Egress"] 并配置相应规则。

参考来源

  • Kubernetes Documentation, "Network Policies", https://kubernetes.io/docs/concepts/services-networking/network-policies/