Kubernetes 网络策略:NetworkPolicy 实战指南

默认情况下 K8s 中所有 Pod 可以互相通信,这在生产环境是个安全隐患。NetworkPolicy 是实现网络隔离的核心机制。

前提条件

NetworkPolicy 需要 CNI 插件支持,常见支持的插件:

  • Calico(推荐,功能最完整)
  • Cilium(eBPF 加速,性能最好)
  • Weave Net

Flannel 不支持 NetworkPolicy。

基本概念

NetworkPolicy 通过标签选择器定义:

  • podSelector:策略应用到哪些 Pod
  • ingress:允许哪些入站流量
  • egress:允许哪些出站流量

默认拒绝所有流量

# 拒绝命名空间内所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}   # 匹配所有 Pod
  policyTypes:
  - Ingress
# 同时拒绝入站和出站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

常用场景配置

只允许同命名空间访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: production
spec:
  podSelector: {}
  ingress:
  - from:
    - podSelector: {}   # 同 namespace 所有 Pod

允许特定服务访问数据库

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: mysql
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api-server
    ports:
    - protocol: TCP
      port: 3306

允许 Ingress Controller 访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-controller
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ingress-nginx
    ports:
    - protocol: TCP
      port: 8080

允许 DNS 解析(重要!)

拒绝所有出站后,DNS 也会被阻断,需要单独放行:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

调试技巧

# 查看当前命名空间的所有网络策略
kubectl get networkpolicy -n production

# 查看策略详情
kubectl describe networkpolicy <name> -n production

# 测试连通性(临时启动一个 debug Pod)
kubectl run test --image=nicolaka/netshoot -it --rm -- bash
# 在容器内测试
curl -v http://mysql:3306
nc -zv mysql 3306

最佳实践

  1. 先默认拒绝,再按需放行 — 零信任原则
  2. 别忘了 DNS 出站规则 — 最常见的坑
  3. 用命名空间隔离环境 — dev/staging/production 互不干扰
  4. 配合 RBAC — 网络层 + 权限层双重防护

NetworkPolicy 是 K8s 安全加固的必选项,建议在生产环境全面启用。

← 返回文章列表