导读:本期聚焦于Ada创作的《Kubernetes NetworkPolicy 网络策略怎么配置?从入门到实战详解》,敬请观看详情。Pod 之间默认是可以随意互访的,这在生产环境里是个不小的安全隐患。想让数据库 Pod 只允许应用层访问、让某个命名空间的流量彻底隔离出来,就得靠 Kubernetes 的 NetworkPolicy。这篇文章会讲清楚 NetworkPolicy 的工作原理、依赖的网络插件要求,再配合 yaml 配置示例演示默认拒绝、白名单放行、命名空间级隔离、Egress 出站控制等常见玩法,最后整理排查策略不生效的思路,帮你真正把集群网络管起来。

在 Kubernetes 集群里,只要 Pod 有了 IP,理论上它就能访问集群内任何其他 Pod,外部来的流量也不受限制。这种默认全通的网络模型在测试环境很方便,但放到生产环境就是裸奔:一旦某个应用被入侵,攻击者可以横向移动到数据库、消息队列等敏感服务。Kubernetes 提供的 NetworkPolicy(网络策略)就是解决这个问题的官方方案,它允许你以声明式的方式定义哪些流量可以进、哪些流量可以出。本文将从原理讲起,逐步展开各种实战配置。

Kubernetes NetworkPolicy 网络策略怎么配置?从入门到实战详解

一、NetworkPolicy 的工作原理与前置条件

首先要理解一点:NetworkPolicy 本身只是一个 API 对象、一份声明,Kubernetes 自身的 kube-proxy 组件并不会执行它。真正干活的是 CNI 网络插件(Container Network Interface)。这意味着没有支持策略的 CNI 插件,你写的任何 NetworkPolicy 都只是摆设,Pod 之间照样全通,而且不会报错。

目前主流的支持 NetworkPolicy 的 CNI 插件包括 Calico、Cilium、Weave Net、Antrea 等,而 Flannel、较老版本的某些网络方案则不支持。所以在动手配置之前,先确认集群用的是哪个 CNI。查看方法很简单:

kubectl get pods -n kube-system | grep -E 'calico|cilium|weave|flannel'

如果输出里能看到 calico-node 或 cilium 这类 Pod,说明策略大概率能生效。另外要注意,NetworkPolicy 是命名空间级别的资源,它只影响所选中的 Pod,不会影响 Service、节点本身。策略的生效逻辑可以概括为两条:一是 Pod 之间的流量是允许还是拒绝,取决于 Pod 是否被某个策略选中;二是只要 Pod 被任意一个策略选中,那么没有被任何规则明确允许的流量就全部拒绝。

还有一个新手容易忽略的细节:NetworkPolicy 是叠加关系,不是覆盖关系。如果 Pod A 同时被两个策略选中,那么两个策略允许的流量加在一起才是它的白名单,不会出现后面的策略覆盖前面的情况。

二、基础配置:默认拒绝与白名单放行

最常见的用法是先做一个默认拒绝全部的策略,再逐条放行需要的流量,这是安全上推荐的最小权限模式。下面是一个默认拒绝所有入站流量的策略:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: prod
spec:
  podSelector: {}   # 空的选择器,选中命名空间内所有 Pod
  policyTypes:
    - Ingress
  # 没有 ingress 字段,意味着拒绝所有入站流量

这个策略的关键在于 podSelector: {},空的花括号表示选中 prod 命名空间下的全部 Pod,而 policyTypes 声明了 Ingress 但没有定义任何 ingress 规则,效果就是一刀切拒绝。同理,把 policyTypes 换成 Egress 就是默认拒绝所有出站流量。

在默认拒绝的基础上,再针对具体应用放行。比如一个 Web 应用只允许接收来自 nginx ingress 控制器的 80 端口流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-from-ingress
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
          podSelector:
            matchLabels:
              app.kubernetes.io/name: ingress-nginx
      ports:
        - protocol: TCP
          port: 80

这里有个重点:当 namespaceSelectorpodSelector 写在同一个列表项里时,是并且关系,即流量来源必须同时满足命名空间和 Pod 两个条件。如果分成两个列表项写,就变成了或者关系,范围会大很多,这是实践中最常见的配置错误之一。

另外,Kubernetes 从 1.22 开始会自动为每个命名空间打上 kubernetes.io/metadata.name 标签,所以可以直接用它来匹配命名空间,不需要自己手动维护标签,稳定且省事。

三、进阶实战:出站控制与 IP 段限制

只管入站往往不够,出站同样重要。比如应用 Pod 需要访问同一命名空间的 Redis 和外部 DNS,其他出站一律禁止,可以有效减少数据外泄的风险。示例如下:

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

注意这里专门放行了 kube-dns 的 53 端口。很多人配完默认拒绝出站后发现服务解析不了域名,就是因为忘了 DNS 流量也被挡住了,这是排障时的高频问题。

除了标签选择器,还可以用 ipBlock 按 CIDR 限制来源或目标。比如允许访问某个固定网段的数据库集群:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-to-db-cidr
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.8.0/24
            except:
              - 10.0.8.5/32
      ports:
        - protocol: TCP
          port: 3306

需要提醒的是,ipBlock 匹配的是 Pod 出栈时的 IP。由于很多 CNI 插件(比如开启了 NAT 或者使用了 overlay 网络)在数据包离开 Pod 后会做地址转换,ipBlock 的行为在不同插件下可能有差异,生产使用前建议先在测试环境验证,或者优先使用 Calico 的 GlobalNetworkPolicy 等扩展资源来处理复杂的 IP 需求。

四、策略不生效的排查思路

配置完成后如果发现策略没起作用,可以按下面的顺序逐层排查。

第一步确认 CNI 插件是否支持 NetworkPolicy。用 Flannel 这类不支持策略的插件时,yaml 能正常 apply,kubectl 也不报错,但策略完全不生效,这是最隐蔽的坑。第二步检查标签是否匹配。可以用 kubectl get pods -n prod --show-labels 查看 Pod 的真实标签,确认 podSelector 和 namespaceSelector 写的标签确实存在,大小写和拼写错误很常见。

第三步分析策略叠加的影响。前面提过策略是叠加的,可能你只想放行 80 端口,但另一个旧策略放行了全部端口,叠加后等于没限制。可以用下面的命令列出某个命名空间下所有策略,逐一核对:

kubectl get networkpolicy -n prod
kubectl describe networkpolicy allow-web-from-ingress -n prod

第四步在 Pod 内做连通性验证,常用工具是 netshoot 或 busybox:

kubectl run test --rm -it --image=nicolaka/netshoot -n prod -- /bin/bash
# 在容器内测试连通性
curl -m 3 http://web.prod.svc.cluster.local
nc -zv -w 3 10.244.1.12 6379

如果测试 Pod 自身也在默认拒绝策略的范围内,注意先给它放行测试通道,否则测什么都是不通,容易误判。

总的来说,NetworkPolicy 的配置思路遵循三步:先默认拒绝,再按业务最小化放行,最后持续验证。把网络策略纳入应用发布的标准流程,配合 GitOps 管理策略文件,集群的横向安全边界才算真正建立起来。

KubernetesNetworkPolicy网络策略修改时间:2026-09-12 02:28:34

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