Kubernetes NetworkPolicy 实践与策略误区

Kubernetes 提供了 NetworkPolicy 用于定义 Pod 之间的网络访问控制。但很多人在使用过程中,要么设了等于没设,要么设置后服务直接"失联"。本文基于实践,深入讲解 NetworkPolicy 的语法、应用方式及常见误区,帮助你将其用得对、用得稳。


一、什么是 NetworkPolicy?为什么需要它?

Kubernetes 默认网络模型遵循"所有 Pod 默认可互相通信"。这对开发调试很友好,但在生产环境下却存在重大隐患:

  • 所有服务互相暴露,无访问边界
  • 一旦某个 Pod 被攻破,可横向攻击整个集群;
  • 多租户环境下,租户间数据易被非授权访问。

因此,引入网络策略非常有必要。Kubernetes 的 NetworkPolicy 提供一种声明式方式,定义:

  • 哪些 Pod 可以访问哪些目标 Pod;
  • 哪些端口、协议可以开放;
  • 是否允许从外部入站或出站通信。

⚠️ 需要特别强调的是 :NetworkPolicy 并不负责网络本身,它只是一个策略描述,需要网络插件(如 Calico、Cilium)实现支持


二、NetworkPolicy 的核心语法

一个最小的 NetworkPolicy 结构如下:

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-frontend
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend

这个策略的含义是:

只允许带有 app=frontend 标签的 Pod 访问 app=backend 的 Pod。其他所有访问都将被拒绝。

NetworkPolicy 支持以下几种类型:

规则方向 字段 说明
入站策略 ingress 控制谁可以访问目标 Pod
出站策略 egress 控制目标 Pod 可以访问谁
作用对象 podSelector 指定策略应用于哪些 Pod
匹配范围 namespaceSelectoripBlockport 精细化过滤条件

注意 :一旦某个 Pod 被选中并应用策略,则默认全部拒绝,除非显式允许。这也是误区出现的关键之一。


三、实战示例:三种常见场景

场景 1:允许某个命名空间访问指定服务

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-namespace
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              project: analytics

该策略只允许带有 project=analytics 标签的命名空间下的 Pod 访问当前 namespace 中标记为 role=db 的 Pod。

场景 2:禁止所有入站流量(默认拒绝)

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: default
spec:
  podSelector: {} # 匹配所有 Pod
  ingress: []     # 明确为空,即不允许任何流量

这是一个非常有效的"白名单策略起点",建议在生产环境作为默认策略启用,然后再逐个添加需要放行的规则。

场景 3:允许访问特定端口

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-metrics
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: metrics-server
  ingress:
    - ports:
        - protocol: TCP
          port: 443

此策略允许其他 Pod 访问 metrics-server 的 443 端口,但不允许访问其他端口。


四、常见误区与踩坑总结

误区 1:策略设置后,访问全部失效

原因:一旦为某个 Pod 设置了 NetworkPolicy,则默认全部拒绝所有流量,除非显式允许。

建议:配合默认允许策略一起使用,例如为 DNS 组件、监控组件等先配置放行规则。


误区 2:策略没生效,以为配置错误

排查重点

  • 你集群的 CNI 插件是否支持 NetworkPolicy?

    • Flannel 原生不支持;
    • Calico、Cilium 支持完整策略;
  • 是否为目标 Pod 打上了正确的标签?

  • 策略是否生效在正确的 namespace 上?


误区 3:只写了 ingress 忽略了 egress

许多用户只定义了 ingress,但实际通信失败,问题出在对端被拦了 egress。

建议:明确策略控制方向,必要时添加:

yaml 复制代码
policyTypes:
  - Ingress
  - Egress

误区 4:忘记放行核心服务(如 kube-dns)

DNS 无法解析 是 NetworkPolicy 配置最常见的问题之一,建议为所有命名空间添加 DNS 放行策略:

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: default
spec:
  podSelector: {}
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              k8s-app: kube-system
      ports:
        - protocol: UDP
          port: 53
  policyTypes:
    - Egress

五、从"能用"到"用好":我在实践中的思考

在实际项目中,我曾经遇到过这样一幕:

刚上线的安全策略导致线上服务大量超时,排查发现数据库无法连接。原来我们设定了 ingress 策略,但忘了放行 egress 到数据库。

这类事故暴露一个现实:NetworkPolicy 虽然语法简单,但逻辑上类似于"防火墙规则",需要慎之又慎

我的经验是:

  • 从默认拒绝 + 白名单放行开始;
  • 将 NetworkPolicy 与服务部署绑定,避免策略缺失;
  • 结合工具做策略审计与模拟测试(如 kubectl-debugnetwork-policy-editor);
  • 把 NetworkPolicy 纳入 DevSecOps 流程,版本化管理。

六、结语:让网络策略成为"默认安全防线"

NetworkPolicy 是 Kubernetes 提供的强大网络控制工具,但前提是你使用了支持它的 CNI,并理解它的工作模型。

它不是网络的替代,而是网络策略的扩展。在微服务时代,它是服务边界控制、横向攻击防护、数据访问隔离的重要组成部分。

别等安全事故之后才想着补策略,不如从现在开始,把 NetworkPolicy 变成你服务部署清单的一部分。

相关推荐
小十十11 分钟前
K8s+Nginx-ingress+Websocket基础知识理解
websocket·nginx·kubernetes
东风微鸣2 小时前
GitOps:云原生时代的革命性基础设施管理范式
docker·云原生·kubernetes·可观察性
GolangSpace2 小时前
YAML:Kubernetes世界里的标准工作语言
kubernetes
FJW0208143 小时前
Mysql集成技术
linux·mysql·云原生
孟婆来包棒棒糖~4 小时前
Docker快速入门
运维·spring boot·docker·容器·tomcat
Gold Steps.7 小时前
K8S周期性备份etcd数据实战案例
云原生·kubernetes·数据安全·etcd
G皮T7 小时前
【云计算】云主机的亲和性策略(四):云主机组
云原生·云计算·云服务器·云主机·亲和性·反亲和性·调度策略
❀͜͡傀儡师7 小时前
Kubernetes (K8s) 部署Doris
云原生·容器·kubernetes