当前位置: 首页 > 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.jsqmd.com/news/958168/

相关文章:

  • 实战演练:基于快马平台从零构建一个迷你版每日编程竞赛系统
  • 时光胶囊:GetQzonehistory一键备份你的QQ空间青春记忆
  • 第12篇:表单基础控件
  • AI写论文推荐!4款AI论文写作工具,助你快速通过论文审核
  • Kali365 驱动下 Microsoft365 OAuth 钓鱼攻击机理与全链路防御技术研究
  • Anthropic语义压缩层消失:大模型可解释性与可控性的范式迁移
  • GEO优化是什么业务?2026年专业靠谱服务好的GEO优化服务商/公司TOP10深度对比评测+FAQ - 互联网科技品牌测评
  • Python 中的 `object` 类扮演什么角色?从万物皆对象到面向对象底层机制
  • 5G NR PDSCH调度实战:手把手教你从MCS查表到TBSize计算的完整流程(含Python代码示例)
  • 3步掌握BG3ModManager:彻底解决博德之门3模组管理难题的终极指南
  • 实战应用:集成visio式绘图功能到你的系统,快马一键生成部署
  • 第 44篇 k8s之实战:将 Web 应用迁移到 Kubernetes(上)
  • GEO主流概念解析!2026年 GEO 优化服务商价格一般多少?有哪些公司比较靠谱 ——5 家geo公司供参考 - 互联网科技品牌测评
  • 上海在职MBA院校排名及学费:安泰领衔第一梯队,20万档仍有优质选择
  • 南宁家政钟点工怎么找靠谱的?别只图便宜忽略这三点 - 教育信息速递
  • 从‘玄学’到可控:拆解CUT论文中对比学习如何让AI理解‘风格’与‘内容’
  • 【金融AI工具配置黄金法则】:20年风控专家亲授7大避坑指南与实时合规校验清单
  • 终极Windows实时屏幕翻译工具:Translumo完全指南
  • 用74HC00与非门做个会叫的电子门铃:从电路图到焊板子的保姆级教程
  • MOSFET双向电平转换电路:原理、设计与实战调试指南
  • AI工具产品路线预测实战指南(2024决策者必读版):基于172家SaaS厂商真实演进路径建模
  • 4步解锁旧Mac潜能:让2012款设备流畅运行最新macOS
  • QQ号群组探测工具:验证账号有效性并导出全部加入群信息
  • 计算机小程序毕设实战-基于springboot+微信小程序的在线预约挂号系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 南宁购宠避坑攻略|江南区明轩猫犬舍全国连锁老店,靠谱买猫狗首选 - 萌宠俱乐部
  • MySQL 8.0连接JDBC老报错?可能是驱动和URL没配对!保姆级排查教程(含Educoder环境适配)
  • 实战应用:基于快马生成的Node.js后端框架打造jvid核心API服务
  • 我用AI“团队”3天干完了外包2个月的活:零代码开发,真的杀疯了
  • Python 元对象模型深度解析:`type` 和 `object` 之间到底是什么关系?
  • GEO服务商怎么选?哪家效果和服务和口碑好?2026年6月TOP10靠谱GEO公司对比盘点 - 互联网科技品牌测评