3. Kubernetes 网络策略 (NetworkPolicy) 基础

在构建多集群镜像拉取安全体系时,网络策略是控制 Pod 间通信、限制非法访问的核心手段。本章将深入解析 NetworkPolicy 的工作原理、选择器机制以及 Ingress/Egress 规则,为后续配置跨集群镜像仓库的访问控制奠定基础。

3.1 NetworkPolicy 的工作原理

NetworkPolicy 是 Kubernetes 集群内的一种资源对象,它通过标签选择器定义 Pod 组之间的通信规则。其核心工作原理基于以下几点:

  • 白名单模型:默认情况下,Pod 允许所有入站和出站流量。一旦应用了 NetworkPolicy,只有显式允许的流量才会通过。
  • 隔离作用域:策略作用于特定的 Pod 集合,由 podSelector 定义。未匹配到任何策略的 Pod 不受影响。
  • 规则匹配顺序:Kubernetes 对 NetworkPolicy 规则的评估是累加的,只要有一条规则允许流量,该流量即被放行。
  • 实现机制:NetworkPolicy 由 CNI 插件(如 Calico、Cilium、Flannel)在数据平面强制执行,Kubernetes API 仅负责存储和分发策略定义。
关键概念:NetworkPolicy 是 有状态 的吗?
不是。NetworkPolicy 本身不维护连接状态。但底层 CNI 插件(如 Calico 使用 iptables conntrack)通常会跟踪连接状态,允许回程流量。因此,在定义 Egress 规则时,通常不需要显式允许对应的 Ingress 回包。
NetworkPolicy 工作原理流程图 NetworkPolicy 工作原理流程图 Pod 默认行为 允许所有 Ingress/Egress 应用 NetworkPolicy 白名单规则生效 规则累加评估 允许则放行,否则丢弃 Pod 选择器 匹配标签:app: web 命名空间选择器 匹配 ns: production 说明:NetworkPolicy 通过标签选择器确定作用范围,规则累加评估,未显式允许的流量默认被拒绝。

3.2 Pod 选择器与命名空间选择器

NetworkPolicy 使用两种选择器来精确控制策略的作用范围:

选择器类型 字段 作用范围 匹配方式 典型场景
Pod 选择器 podSelector 当前命名空间内的 Pod 标签键值对匹配(AND 逻辑) 限制特定微服务的入站流量
命名空间选择器 namespaceSelector 跨命名空间的 Pod 命名空间标签匹配 允许监控系统访问所有命名空间
IP 块选择器 ipBlock 集群外部 IP 或 CIDR CIDR 范围匹配 允许镜像仓库 IP 段访问
最佳实践:在多集群镜像拉取场景中,建议组合使用 namespaceSelector 和 podSelector 来精确控制哪些命名空间下的哪些 Pod 可以访问镜像仓库。例如:namespaceSelector: { matchLabels: { purpose: production } } 配合 podSelector: { matchLabels: { app: image-puller } }。

3.3 Ingress 与 Egress 规则

NetworkPolicy 支持两种流量方向规则:

  • Ingress 规则:控制进入 Pod 的入站流量。定义允许哪些来源(通过 from 字段)访问目标 Pod 的指定端口。
  • Egress 规则:控制从 Pod 发出的出站流量。定义允许目标 Pod 访问哪些目的地(通过 to 字段)和端口。

一个完整的 NetworkPolicy 示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-image-registry-access
  namespace: app-ns
spec:
  podSelector:
    matchLabels:
      app: web-frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: monitoring
      podSelector:
        matchLabels:
          app: prometheus
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - ipBlock:
        cidr: 10.100.0.0/16
        except:
        - 10.100.1.0/24
    ports:
    - protocol: TCP
      port: 443
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
常见陷阱:
1. 定义 Egress 规则时,如果未包含 DNS 解析规则(UDP 53 端口),Pod 将无法解析域名,导致所有外部通信失败。
2. ipBlock 规则中的 except 字段用于排除特定子网,优先级高于允许规则。
3. 空 podSelector({})匹配命名空间内所有 Pod,谨慎使用。
Ingress 与 Egress 规则架构图 Ingress 与 Egress 规则架构图 目标 Pod app: web-frontend 端口: 8080 Ingress 来源 1 ns: monitoring, pod: prometheus Ingress 来源 2 ipBlock: 10.0.0.0/8 Egress 目标 1 ipBlock: 10.100.0.0/16:443 Egress 目标 2 ns: kube-system, pod: kube-dns:53 规则说明 Ingress 规则:允许来自 monitoring 命名空间的 prometheus Pod 和 10.0.0.0/8 网段的流量访问 8080 端口。 Egress 规则:允许 Pod 访问 10.100.0.0/16 的 443 端口和 kube-system 命名空间的 DNS 服务。 未显式允许的流量将被默认拒绝。

3.4 规则编写要点与调试方法

编写 NetworkPolicy 时需注意以下要点:

  • 明确 policyTypes:如果只定义 Ingress 规则但未在 policyTypes 中包含 Egress,则 Egress 流量不受影响。建议显式声明所有需要控制的流量方向。
  • 端口与协议:规则中的 ports 字段支持 TCP、UDP 和 SCTP 协议。不指定端口时,规则匹配所有端口。
  • 选择器组合:from 和 to 字段中的多个选择器是 OR 逻辑;同一选择器内的多个标签是 AND 逻辑。
调试命令:
kubectl describe networkpolicy <policy-name> -n <namespace> — 查看策略详情
kubectl get networkpolicy -A — 列出所有命名空间的网络策略
kubectl run test-pod --image=busybox --rm -it -- sh — 启动测试 Pod 验证连通性

通过掌握 NetworkPolicy 的基础原理和规则编写,你可以在多集群环境中精确控制镜像拉取流量的访问路径,确保只有授权的 Pod 和命名空间能够与镜像仓库通信,从而构建零信任网络模型。