Skip to content

NetworkPolicy 网络策略

概述

NetworkPolicy 是 Kubernetes 原生的网络隔离机制,通过标签选择器定义 Pod 间的流量规则。需要 CNI 插件支持(Calico、Cilium、Weave 等)。

默认行为

  • 没有 NetworkPolicy 时:所有 Pod 间流量都允许
  • 有 NetworkPolicy 选中 Pod 时:只允许策略中明确允许的流量

完整示例

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-server-policy
  namespace: production
spec:
  # 选中哪些 Pod 应用此策略
  podSelector:
    matchLabels:
      app: api-server

  policyTypes:
  - Ingress
  - Egress

  ingress:
  # 规则 1:允许来自同命名空间 frontend Pod 的 HTTP 流量
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

  # 规则 2:允许来自 monitoring 命名空间的 Prometheus 抓取
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
      podSelector:
        matchLabels:
          app: prometheus
    ports:
    - protocol: TCP
      port: 9090

  # 规则 3:允许来自特定 IP 段
  - from:
    - ipBlock:
        cidr: 10.0.0.0/8
        except:
        - 10.0.0.0/24  # 排除特定子网

  egress:
  # 允许访问数据库
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432

  # 允许 DNS 解析
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

  # 允许访问外部 HTTPS
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
    ports:
    - protocol: TCP
      port: 443

常用策略模板

默认拒绝所有入站

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

默认拒绝所有出站

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

允许同命名空间通信

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

微服务三层架构策略

bash
# 前端只能被外部访问,只能访问后端
# 后端只能被前端访问,只能访问数据库
# 数据库只能被后端访问

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-policy
spec:
  podSelector:
    matchLabels:
      tier: frontend
  ingress:
  - {}  # 允许所有入站
  egress:
  - to:
    - podSelector:
        matchLabels:
          tier: backend
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-policy
spec:
  podSelector:
    matchLabels:
      tier: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: frontend
  egress:
  - to:
    - podSelector:
        matchLabels:
          tier: database
  - to:
    - namespaceSelector: {}
    ports:
    - port: 53
      protocol: UDP
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database-policy
spec:
  podSelector:
    matchLabels:
      tier: database
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: backend
EOF

注意事项

  • NetworkPolicy 是加法:多个策略的规则取并集
  • from/to 中多个条件是 OR 关系
  • 同一条件内的多个字段是 AND 关系
  • 空的 podSelector: {} 选中命名空间内所有 Pod
  • 空的 namespaceSelector: {} 选中所有命名空间

本站内容由 褚成志 整理编写,仅供学习参考