Kubernetes Goat 场景 20 实战:用 NetworkPolicy 为集群构建网络边界
2026/9/17 20:34:24 网站建设 项目流程

Kubernetes Goat 场景 20 实战:用 NetworkPolicy 为集群构建网络边界

【免费下载链接】kubernetes-goatKubernetes Goat is a "Vulnerable by Design" cluster environment to learn and practice Kubernetes security using an interactive hands-on playground 🚀项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-goat

Kubernetes 默认是"扁平网络",集群内所有 Pod 之间默认互相可达。本文围绕 Kubernetes Goat 的 Scenario 20,完整演示如何编写并应用一条最小化的NetworkPolicy,把默认放行的入站流量改为默认拒绝,从而在集群内为指定工作负载(website服务)建立真正的网络安全边界。读完并动手演练后,你将掌握podSelectoringress: []等关键字段的语义,以及"先验证连通 → 施加策略 → 复验阻断"的标准排障流程。

场景背景:扁平网络与 NSP 的关系

如本仓库 场景首页 所述,Scenario 20 的目标是"deploy a simple network security policy for kubernetes resources to create security boundaries",即部署一条简单的网络策略为集群资源建立安全边界。完整的操作指南位于 场景文档,并在 README 的场景清单中列为第 20 项"Secure network boundaries using NSP"。

从文档描述可以确认两个关键前提:

  1. Kubernetes 原生不提供默认网络隔离。集群内部默认是 flat network schema——任何 Pod 都可以访问任何其他 Pod 的端口,除非你显式声明策略。
  2. NetworkPolicy 需要 CNI 支持才会生效。文档明确要求:"ensure you must be using a networking solution which supports NetworkPolicy"。换言之,NetworkPolicy资源只是声明式 API,真正在数据面拦截流量的是 CNI 插件。如果你的集群 CNI 不支持该功能,策略资源可以正常创建但不会产生任何隔离效果——这一点在演练前必须确认。

场景目标

文档给出的目标非常聚焦:

Create a Network Policy to drop the access to thewebsiteservice to complete this scenario.

即:创建一条 NetworkPolicy,阻断(drop)对website服务的全部访问,以此验证边界确实建立。

完整实操步骤

以下所有命令均继承自 场景指南,可在任意支持 NetworkPolicy 的集群上直接复制执行。

第 1 步:部署 website 工作负载

启动一个带app=website标签的 Nginx Pod,并通过--expose同时创建 Service:

kubectl run --image=nginx website --labels app=website --expose --port 80

这条命令做了三件事:

  • 创建名为website的 Pod,运行nginx镜像;
  • 打上app=website标签——这是后面 NetworkPolicy 中podSelector的匹配依据;
  • 通过--expose --port 80创建一个名为website的 Service,将集群内流量映射到 80 端口,这样集群内其他 Pod 可以直接用http://website访问。

第 2 步:用临时 Pod 验证连通性

启动一个临时 Alpine Pod 作为"探针",模拟集群内其他工作负载发起请求:

kubectl run --rm -it --image=alpine temp -- sh

--rm参数表示该 Pod 退出后自动清理,-it进入交互式 shell。进入 shell 后,用wget向 website 服务发起一次简单 HTTP 请求:

wget -qO- http://website

此时应能看到 Nginx 的默认欢迎页 HTML 内容,说明扁平网络下流量完全畅通:

第 3 步:编写并应用拒绝策略

在本地创建策略清单(文档中命名为website-deny.yaml),内容如下:

kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: website-deny spec: podSelector: matchLabels: app: website ingress: []

关键点解析:

  • podSelector.matchLabels: app: website:策略作用于所有匹配该标签的 Pod,即第 1 步中创建的websitePod。注意选择的是 Pod 而非 Service,这是 NetworkPolicy 的标准行为——策略永远绑定到 Pod 集合。
  • ingress: []:这是整条策略的灵魂。空数组表示"没有任何入站流量规则被允许",即对该 Pod 施加默认拒绝(default-deny)入站流量的语义。只要ingress字段一旦出现(哪怕为空),该 Pod 的入站就从"默认放行"切换为"白名单模式",而空白名单意味着全部拒绝。若省略ingress字段、只写podSelector,策略则不会阻断任何流量,这是初学者最常踩的坑。
  • 本策略未声明policyTypes字段,按 API 默认值,ingressegress类型都会生效——即该 Pod 的出站流量同样会被默认拒绝。本场景只需阻断入站访问,因此空策略同时拒绝了出方向,演练效果不受影响。

应用策略:

kubectl apply -f website-deny.yaml

第 4 步:复验流量已被阻断

再次启动临时 Pod(或直接沿用未退出的 temp Pod),重复请求并加上 2 秒超时,避免长时间挂起:

kubectl run --rm -it --image=alpine temp -- sh
wget -qO- --timeout=2 http://website

这次请求不再返回 HTML,而是因超时/连接失败而报错,证明 NetworkPolicy 正在数据面丢弃发往website的入站流量:

第 5 步:清理资源

按文档给出的顺序删除本次演练创建的全部资源:

kubectl delete pod website kubectl delete service website kubectl delete networkpolicy website-deny

先删工作负载与 Service,再删策略,避免残留的拒绝策略影响集群中其他同标签资源。

结合仓库源码的实现佐证

  • 场景内容的组织方式:本仓库将场景拆成两层——场景桩文件(即 goat-home Hugo 站点内的场景入口,仅保留 frontmatter 与一句话说明,并提示"refer to the Guide")与 完整指南(Docusaurus 站点中的分步 Walkthrough,包含上文全部命令、策略清单与截图)。阅读本场景时应以指南文档为准。
  • 策略清单的来源:从仓库目录结构看,scenarios/目录下存放的是各基础设施服务的 Deployment/Job 清单(如scenarios/health-check/deployment.yaml),Scenario 20 的website-deny.yaml并未提交到仓库,而是作为演练过程产物由读者在本地创建——这与该场景"教学式演示"的定位一致:重点在于理解字段语义,而非固化一份清单。
  • 与仓库其他策略机制的对照:仓库中还存在另一类"策略"示例——Kyverno 命名空间 exec 阻断策略,它通过准入控制(admission control)在控制面拦截违规操作;而本场景的 NetworkPolicy 作用于数据面的流量转发。两者分别对应 Kubernetes 安全边界中"操作层面"与"通信层面"的两种典型手段。

关键要点复盘

  1. 默认放行是风险:不写任何 NetworkPolicy 的集群里,所有 Pod 两两互通,单个工作负载被攻破就等于整张内部网络暴露。
  2. ingress: []= 默认拒绝入站:策略"存在且声明了 ingress"才触发白名单语义,空白名单即全拒。
  3. 策略绑定 Pod 标签podSelector决定作用域,标签设计(如app=website)因此成为网络边界规划的一部分。
  4. CNI 是生效前提:NetworkPolicy 只是 API 声明,最终由 CNI 在数据面实施;演练前需确认所用网络方案支持该特性。
  5. 验证方法论:本场景演示的"基线连通 → 施加策略 → 带超时复验 → 按序清理"四步法,是排查任何 NetworkPolicy 是否生效的标准流程。

掌握以上要点后,你可以在此基础上进一步扩展:按namespaceSelector限制"仅某个命名空间可访问"、按ipBlock放行特定网段、或对 egress 方向做同等约束——这些都属于同一条 NetworkPolicy API 的白名单规则组合,语义与本场景完全一致。

【免费下载链接】kubernetes-goatKubernetes Goat is a "Vulnerable by Design" cluster environment to learn and practice Kubernetes security using an interactive hands-on playground 🚀项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-goat

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询