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 变成你服务部署清单的一部分。

相关推荐
我是谁??3 小时前
ubuntu22.04 通过docker部署vLLM(Qwen3-0.6B)大模型+New API+OpenWebUI
docker·容器·vllm
Patrick_Wilson3 小时前
K8s 探针避坑:Next.js 不同部署模式下的健康检查实践
kubernetes·node.js·next.js
运维瓦工3 小时前
DevOps 生态介绍(十):Docker Compose 核心 YAML 配置详解与常用命令大全
spring cloud·docker·容器
Plastic garden4 小时前
K8s(10)NFS 的动态 PV 创建数据库给k8s的mysql和redis
docker·容器·kubernetes
Plastic garden4 小时前
k8s(11) Pod 控制器,服务发现与存储管理
kubernetes
与海boy4 小时前
docker compose minio
docker·容器·eureka
星辰徐哥5 小时前
云原生核心特性:容器化、微服务与DevOps的通俗解读
微服务·云原生·devops
武子康5 小时前
调查研究-167 Docker Compose 详解:从单容器到多服务编排的工程化入口
运维·docker·云原生·容器·kubernetes·k8s·docker-compose
heimeiyingwang6 小时前
【架构实战】分布式会话:从Session到JWT的演进
微服务·云原生·架构