当前位置: 首页 > news >正文

第 43 篇 k8s之集群网络策略:NetworkPolicy 入门

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


在第 38 篇中,我们用 RBAC 解决了“谁能操作什么资源”的授权问题。但安全防护还有另一条战线:网络层。默认情况下,Kubernetes 集群内的所有 Pod 之间可以自由通信。这带来了一个风险:一旦某个 Pod 被攻破,攻击者就能以它为跳板,访问集群内的所有其他服务。

在 Docker Compose 时代,这种风险相对可控——所有容器都在一台宿主机上,你可以通过绑定特定 IP、配置自定义网络来实现基本隔离。但在 K8s 集群中,Pod 可能分布在多台节点上,你需要的是以应用为粒度的网络防火墙。这就是 NetworkPolicy 的使命。

今天这篇,我们从“零信任”的安全理念讲起,拆解 NetworkPolicy 的核心三要素,然后把它应用到贯穿案例的 Flask + Redis 应用中——让 Redis 只接受 Flask 的访问,拒绝一切其他来源的流量。

一、从“全通”到“零信任”:为什么需要 NetworkPolicy?

1.1 K8s 的默认网络模型:扁平全通

K8s 的网络模型有一条基本原则:所有 Pod 之间可以不经过 NAT 直接通信,无论它们是否在同一节点上。这极大简化了微服务间的通信——你不用配置任何路由规则,Flask 就能直接访问 Redis 的 Pod IP。

但这种“全通”模式也带来了安全隐患。假如你的集群中运行着以下 Pod:

  • Flask 应用(处理用户请求,暴露在 Ingress 之后)

  • Redis(存储缓存数据,仅应被 Flask 访问)

  • 后台批处理任务(连接外部 API,不应访问 Redis)

默认情况下,这三个 Pod 之间可以任意互通。如果 Flask 应用存在安全漏洞(比如 RCE 远程代码执行),攻击者就能通过 Flask Pod 直接连接到 Redis,读取或删除所有缓存数据。

1.2 Docker 网络隔离 vs K8s NetworkPolicy

回顾第 8 篇 Docker 网络入门,我们通过自定义 bridge 网络实现了容器间的隔离——不在同一网络的容器无法互相访问。但这种隔离粒度太粗了:它基于“网络”而非“应用标签”。

NetworkPolicy 提供了更精细的控制:你可以基于 Pod 的标签(Label)和命名空间(Namespace),精确控制哪些 Pod 可以访问哪些 Pod,以及允许哪些端口和协议。这就是“零信任”安全模型在 K8s 中的实现——默认拒绝一切流量,只显式允许必要的通信。

1.3 NetworkPolicy 的前置条件

重要提醒:NetworkPolicy 只是“规则定义”,它需要**网络插件(CNI)**来实际执行。不是所有 CNI 插件都支持 NetworkPolicy:

Minikube 默认使用 Flannel,不支持 NetworkPolicy。要让本篇的配置生效,你需要先启用 Calico:

# 删除旧集群并重建(Calico 需要从集群创建时配置)minikube delete minikube start--cni=calico--driver=docker

二、NetworkPolicy 的核心三要素

NetworkPolicy 通过三个核心字段定义规则:

2.1 podSelector:规则应用给谁?

podSelector通过标签选择一组 Pod,作为规则的目标。例如podSelector: matchLabels: app: redis表示“对带有app=redis标签的 Pod 应用此规则”。

2.2 policyTypes:控制哪个方向的流量?

如果只写policyTypes: [Ingress],则只控制入站流量,不限制出站流量(出站全放通)。

2.3 ingress/egress:具体规则

规则的from字段定义流量来源(入站),to字段定义流量目的(出站),每个来源/目的可以通过三种方式指定:

规则生效逻辑from中的多个选择器是OR 关系(任一匹配即放行),但选择器内部的多个条件(如podSelectornamespaceSelector同时出现)是AND 关系(必须同时满足)。

三、实战:为 Flask + Redis 配置 NetworkPolicy

现在我们为贯穿案例的 Flask + Redis 应用配置网络隔离策略。核心目标是:

  1. Redis 只能被 Flask Pod 访问(拒绝其他所有 Pod)。

  2. Flask 只能被 Ingress Controller 访问(拒绝直接的 Pod-to-Pod 请求)。

  3. 禁止所有未声明的流量(默认拒绝)。

3.1 场景:只允许 Flask 访问 Redis

先配置 Redis 的安全策略:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: redis-allow-flask-only namespace: default spec: podSelector: matchLabels: app: redis policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: flask-counter ports: - protocol: TCP port:6379

规则解读:

  • podSelector: app: redis:本规则应用于 Redis Pod。

  • policyTypes: [Ingress]:控制入站流量。

  • from: podSelector: app: flask-counter:只放行来自app=flask-counter标签的 Pod 的流量。

  • ports: 6379:进一步限制只能访问 Redis 的默认端口。

效果:部署此规则后,任何没有app=flask-counter标签的 Pod 都无法连接 Redis。

3.2 验证隔离效果

部署一个测试 Pod 来验证规则是否生效:

# 启动一个 alpine 测试 Podkubectl run test-pod--image=alpine--rm-it--sh# 在测试 Pod 内安装 curl 和 redisapkaddcurlredis# 测试 1:直接访问 Redis(应该被拒绝)redis-cli-hredis-service-p6379PING# 如果规则生效,连接会超时或拒绝# 测试 2:访问 Flask(Flask 没有 Ingress 规则,应被拒绝)curlhttp://flask-service:5000/health# 连接超时或拒绝

现在从 Flask Pod 内部访问 Redis(应该成功):

kubectlexecdeploy/flask-deployment -- redis-cli-hredis-service PING# PONG

3.3 默认拒绝所有流量

NetworkPolicy 的规则是累加的——多条规则的效果合并,任一规则的from匹配即可放行。如果没有匹配任何 NetworkPolicy,流量默认被放行。要实现“默认拒绝”,需要创建一条“拒绝所有”的兜底规则:

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

podSelector: {}表示选择命名空间中所有 Pod,而空的ingress规则意味着没有任何来源被允许。这条规则与redis-allow-flask-only等显式规则共同作用——显式规则打开特定通道,兜底规则关闭其他所有入口。

3.4 允许 Ingress Controller 访问 Flask

默认拒绝后,外部的 Ingress Controller 也无法访问 Flask。需要显式放行:

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

这里使用namespaceSelector选择了ingress-nginx命名空间中的所有 Pod,允许它们访问 Flask 的 5000 端口。

3.5 完整的安全策略

现在我们的应用安全策略包括:

应用所有策略:

kubectl apply-fredis-networkpolicy.yaml kubectl apply-fflask-networkpolicy.yaml kubectl apply-fdefault-deny.yaml kubectl get networkpolicy# NAME POD-SELECTOR AGE# default-deny-all <none> 30s# flask-allow-ingress app=flask-counter 20s# redis-allow-flask-only app=redis 10s

四、Egress 规则:控制 Pod 的出站流量

除了入站流量,NetworkPolicy 还可以限制 Pod 的出站流量——Pod 可以访问哪些外部服务。

例如,只允许 Flask Pod 访问 Redis 和 CoreDNS(否则 Pod 无法解析域名):

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: flask-egress namespace: default spec: podSelector: matchLabels: app: flask-counter 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

规则解读:

  • 允许 Flask 访问 Redis 的 6379 端口(TCP)

  • 允许 Flask 访问kube-system命名空间中的 CoreDNS(UDP 53),确保 DNS 解析正常工作

  • 其他所有出站流量(如访问外部 API)将被拒绝

五、NetworkPolicy 排错指南

NetworkPolicy 排错的核心是隔离问题范围——确认是 CNI 不支持、标签选择器写错了、还是端口/协议不对:

# 1. 检查 CNI 插件是否支持 NetworkPolicykubectl get pods-nkube-system|grep-E"calico|cilium|weave"# 如果有输出,说明支持;如果只看到 flannel,需要更换 CNI# 2. 查看 NetworkPolicy 规则kubectl describe networkpolicy<策略名># 3. 检查 Pod 标签是否匹配kubectl get pods --show-labels|grep<关键词># 如果 Pod 的实际标签与 NetworkPolicy 的 podSelector 不匹配,规则不会生效# 4. 用测试 Pod 验证连通性kubectl runtest--image=alpine--rm-it--shapkaddcurlcurlhttp://<service-name>:<port>/health --connect-timeout3# 根据超时或被拒判断策略是否生效

六、对比 Docker Compose 的网络隔离

Docker Compose 通过不同网络实现粗粒度隔离,而 NetworkPolicy 提供了更灵活、更细粒度的网络防火墙。在 Compose 中要限制某个容器只能被特定容器访问,需要精细规划网络拓扑;在 K8s 中,只需要用标签和选择器声明规则即可。

七、命令速查表

八、本篇总结

  • NetworkPolicy 的定位:K8s 原生的网络防火墙,通过标签和选择器精确控制 Pod 间的流量,实现“零信任”网络模型。但它只是规则定义,实际执行依赖 CNI 插件(Calico、Cilium 等)。

  • 核心三要素podSelector(目标 Pod)、policyTypes(Ingress/Egress)、ingress/egress(具体规则),规则中通过 podSelector、namespaceSelector、ipBlock 三种方式指定流量来源或目的。

  • 实战成果:为 Flask + Redis 应用配置了最小权限的网络策略——Redis 只接受 Flask 的连接,Flask 只接受 Ingress Controller 的流量,并设置默认拒绝兜底规则。

  • 安全最佳实践:生产环境应为每个命名空间配置默认拒绝策略,然后逐项放行必要的流量。这对应了 RBAC 中的“最小权限原则”,两者共同构成 K8s 安全的两道防线。

下一篇——第 44 篇:实战:将 Web 应用迁移到 Kubernetes(上),我们将把贯穿案例的 Flask + Redis 计数器应用从 Compose 彻底迁移到 K8s 集群,用 Deployment、Service、ConfigMap、Secret、PVC 等核心对象完成完整的应用部署。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

http://www.rkmt.cn/news/1469841.html

相关文章:

  • 实战应用:集成visio式绘图功能到你的系统,快马一键生成部署
  • 上海在职MBA院校排名及学费:安泰领衔第一梯队,20万档仍有优质选择
  • MOSFET双向电平转换电路:原理、设计与实战调试指南
  • MySQL 8.0连接JDBC老报错?可能是驱动和URL没配对!保姆级排查教程(含Educoder环境适配)
  • 实战应用:基于快马生成的Node.js后端框架打造jvid核心API服务
  • Python 元对象模型深度解析:`type` 和 `object` 之间到底是什么关系?
  • AI Native应用用户体验:Agent交互界面设计的原则与反模式
  • GEO服务商怎么选?哪家效果和服务和口碑好?2026年6月TOP10靠谱GEO公司对比盘点 - 互联网科技品牌测评
  • 委托、多态、继承接口
  • 计算机毕业设计之C5.0决策树算法在学生成绩预测中应用
  • 解锁上班新姿势[特殊字符]
  • 无需下载matlab,用快马ai平台5分钟搭建在线矩阵计算与绘图原型
  • SMUDebugTool:AMD Ryzen处理器深度调试与性能调优完整指南
  • 3步掌握APK安装器:Windows上运行安卓应用的终极指南
  • 安卓虚拟摄像头技术深度解析:3大核心原理与5个实战应用场景
  • 景区旅游小程序源码(含微信前端页面+Node/PHP后端服务)
  • 【高届数计算机方向会议】第七届计算机视觉与数据挖掘国际学术会议(ICCVDM 2026)
  • AI工具竞品分析怎么做?3类致命误区正在拖垮你的产品决策(附可落地的5维评估矩阵)
  • 终极暗黑2存档编辑器指南:5分钟打造完美游戏体验
  • 高速PCB设计中过孔的寄生效应与信号完整性优化实战
  • 2026云南美术培训行业深度测评:3家综合实力突出画室的核心能力解析 - 云南美术头条
  • 影刀RPA店群自动化性能调优实战:Python异步执行剖析与资源利用率优化
  • Miro 做白板,Picdoc 做图表,我的分工选择
  • 2026年6月四川靠谱型钢厂汇总|最新钢管吨价+本地放心采购指南 - 四川盛世钢联营销中心
  • AI辅助数据库设计:快马智能对话解析需求,自动生成并优化ER图方案
  • 新手福音,在快马平台免安装jdk17直接上手编写第一个java程序
  • 零基础小白实践vibe coding:用AI生成一个可玩的数独游戏全记录
  • 【Redis】面试知识点一点就会!
  • 2026桂林防水补漏哪家好?住建实地测评权威榜单TOP5|卫生间免砸砖/阳台屋顶/厨卫漏水维修(6月桂林专项调研) - 苏易修缮
  • 关于ST-Link安装驱动之后电脑还是无法识别的问题