导读:本期聚焦于胡建平创作的《Kubernetes 网络策略如何实现命名空间级别的流量隔离?》,敬请观看详情。集群里的 Pod 默认可以互相访问,这在多团队共用一个 Kubernetes 集群时往往带来安全隐患:一个服务被攻破,攻击者就能横向扫描整个集群。NetworkPolicy 正是解决这一问题的官方方案,它通过标签选择器定义流量白名单,允许精细控制 Pod 之间以及 Pod 与外部之间的进出流量。本文从网络策略的工作原理讲起,介绍 Ingress 与 Egress 规则的写法、命名空间选择器的配合使用,再到默认拒绝全量流量、按命名空间放行的完整实战配置,同时梳理 Calico 与 Flannel 等常见 CNI 插件对网络策略的支持差异,以及排查策略不生效问题的排查思路,帮助你把集群安全边界真正落地。

Kubernetes 集群在默认配置下有一个容易被忽视的安全特性:所有 Pod 之间的网络是全通的。哪怕两个 Pod 分属不同的命名空间、不同的业务团队,只要 IP 可达,就能直接通信。这种扁平化网络在测试环境很方便,但在生产环境中意味着任何一个 Pod 被入侵后,攻击者可以横向移动访问整个集群。网络策略(NetworkPolicy)就是 Kubernetes 提供的流量隔离手段,它允许管理员以命名空间或 Pod 为单位定义白名单规则,只有明确允许的流量才能通过。

Kubernetes 网络策略如何实现命名空间级别的流量隔离?

网络策略的工作原理与前置条件

NetworkPolicy 是 Kubernetes 的一种资源对象,它的作用对象是 Pod 而不是节点或服务。策略一旦被创建并选中了某个 Pod,该 Pod 的流量就会进入白名单模式:策略中没有明确允许的入站或出站流量都会被丢弃。这一点和很多防火墙的思维类似,但要注意一个关键细节——如果没有任何策略选中某个 Pod,那么这个 Pod 的流量是完全不受限制的。也就是说,网络策略是加法生效的,未覆盖到的 Pod 依然保持默认全通状态。

需要特别强调的是,NetworkPolicy 只是 API 层面的声明,真正执行隔离动作的是容器网络接口(CNI)插件。如果集群使用的是 Flannel 这类不支持网络策略的插件,那么即使你成功创建了 NetworkPolicy 资源,kubectl 也不会报错,但规则不会产生任何实际效果,这是新手最容易踩的坑。支持网络策略的常见插件包括 Calico、Cilium、Weave Net 以及 Kubernetes 自带的 kube-router。在生产环境中如果必须使用 Flannel,常见的替代做法是将 CNI 更换为 Calico,或者直接部署 Canl ico 的策略引擎与 Flannel 配合。

验证 CNI 是否支持网络策略,可以通过查看节点上的策略控制器日志,或者在测试命名空间里创建一个默认拒绝的策略后尝试跨命名空间访问。下面用一个简单的测试来确认隔离是否真的生效:

# 创建两个测试命名空间
kubectl create ns dev-team
kubectl create ns test-team

# 在两个命名空间中各启动一个 nginx
kubectl run nginx-dev --image=nginx -n dev-team
kubectl run nginx-test --image=nginx -n test-team

# 创建测试 Pod 并尝试访问
kubectl run curl-test --image=curlimages/curl -n test-team --rm -it -- sh
curl --connect-timeout 3 http://nginx-dev.dev-team.svc.cluster.local

Ingress 与 Egress 规则详解

一个完整的 NetworkPolicy 由四部分组成:podSelector 决定策略作用于哪些 Pod,policyTypes 声明策略包含的方向(Ingress、Egress 或两者),ingress 规则定义允许的入站流量,egress 规则定义允许的出站流量。每个方向的规则都是白名单语义,多条规则之间是或的关系,规则内部的多个条件是与的关系。

ingress 规则中的 from 字段有三种匹配方式:ipBlock 直接指定 CIDR 网段,适合放行集群外的固定 IP 或节点网段;namespaceSelector 通过标签选择命名空间,实现命名空间级别的整体放行;podSelector 则在策略所在命名空间内选择特定 Pod。namespaceSelector 和 podSelector 可以写在同一个 from 条目里表示同时满足,也可以分开写表示满足其一,这个语义差异在配置复杂规则时非常重要,写错位置会导致放行范围远超预期。

下面这个例子展示了典型的命名空间隔离策略:允许带有 team=backend 标签的命名空间中的所有 Pod 访问当前命名空间里 role=api 的 Pod,且只开放 8080 端口:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-namespace
  namespace: prod-app
spec:
  podSelector:
    matchLabels:
      role: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              team: backend
      ports:
        - protocol: TCP
          port: 8080

egress 规则的写法与之对称,to 字段同样支持 ipBlock、namespaceSelector 和 podSelector 三种方式。需要注意的是,一旦为 Pod 配置了 egress 策略,DNS 解析也会被拦截,如果不放行 kube-system 命名空间中 kube-dns 的 53 端口,服务发现会立即失效,表现为所有基于域名的请求全部超时报错,这是配置 egress 后最常见的事故。放行 DNS 的写法如下:

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

命名空间级整体隔离的实战配置

要实现命名空间级别的严格隔离,推荐的做法分两步:第一步是给每个命名空间打上团队标签作为隔离依据,第二步是创建一组基础策略实现默认拒绝加定向放行。给命名空间打标签可以使用 kubectl label 命令,kubernetes.io/metadata.name 是集群自动注入的标签,值就是命名空间名本身,可以直接用于选择,不需要手动维护。

# 为业务命名空间打上团队标签
kubectl label namespace dev-team team=backend
kubectl label namespace bigdata team=data

# 查看命名空间标签
kubectl get ns --show-labels

第二步先在目标命名空间部署默认全拒绝策略。podSelector 使用空的大括号表示选中命名空间内所有 Pod,policyTypes 同时声明入站和出站,且不写任何规则,效果就是该命名空间内所有 Pod 的双向流量全部被切断:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: dev-team
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

默认拒绝之后,再按业务需要逐条追加放行策略。比如允许 dev-team 访问数据库命名空间的 5432 端口,允许 ingress-nginx 所在命名空间访问 web 服务的 80 端口。这种先收紧再逐步放开的方式虽然前期配置量大,但安全边界清晰,出问题时也能快速定位是哪条规则导致的。建议把每个命名空间的策略用 Git 管理,配合 CI 流水线统一下发,避免手工修改造成环境漂移。

策略不生效的排查思路

排查网络策略问题可以从三个层面入手。第一层确认 CNI 是否支持网络策略,查看 kube-system 中 CNI 组件的版本和配置,Calico 可以通过 calicoctl 工具查看节点状态。第二层确认策略是否真的选中了目标 Pod,可以用 kubectl describe networkpolicy 查看 endpoints 列表,如果显示为空说明标签没有匹配上。第三层才是抓包分析,在目标 Pod 所在节点上使用 tcpdump 观察流量是否被丢弃。

另一个高频问题是误用了 ipBlock 放行 Pod 网段。ipBlock 匹配的是原始 IP,如果放行的来源 IP 经过 SNAT 转换,实际匹配到的可能是节点 IP 而不是 Pod IP。跨节点访问时,部分 CNI 的实现会导致 ipBlock 行为与预期不符,稳妥的做法是尽量用 namespaceSelector 配合 podSelector 来表达来源,而不是依赖具体网段。

最后建议在上线网络策略前先在预发环境做全量演练,重点验证 DNS 解析、健康检查探针、对外部依赖(数据库、消息队列、第三方 API)的访问是否正常。就绪探针和存活探针的流量来自 kubelet,通常不受命名空间内策略影响,但如果策略中有针对节点网段的 ipBlock 限制,可能会误伤探针导致 Pod 反复重启。把探针端口纳入放行清单,是隔离上线前必须检查的一项。

Kubernetes网络策略NetworkPolicy修改时间:2026-09-14 03:12:46

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260914/56424.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。