K8s 零信任实战:如何用 NetworkPolicy 拦截集群内的“非法访问”?

在很多人的潜意识里,Kubernetes 内部是一个绝对安全的“乌托邦”:只要把服务部署到了集群里,不暴露 NodePort 或者 Ingress,外部黑客就打不进来,内部服务也是绝对安全的。

但现实往往很骨感。Kubernetes 的默认网络模型是“扁平且全开放”的。

这意味着什么?这意味着如果你的集群里运行着一个电商系统和一个内部财务系统,只要它们在同一个集群网络下,电商系统里的任意一个微服务,都可以畅通无阻地 ping 通财务系统里的核心数据库!一旦某个边缘微服务存在漏洞被拿下,攻击者就能以此为跳板,在集群内部横向移动(Lateral Movement)。

今天,我们就来实战演练一把:如何打破这种“全连通”的默认状态,用 NetworkPolicy(网络策略) 给核心服务穿上防弹衣。

🔪 场景重现:合法的 API 与非法的“黑客”

假设我们在 auth-space 命名空间下,运行着一个极其重要的数据库服务 mysql(带有标签 db=mysql)。

现在,集群里潜伏着两个访客:

  1. 合法的业务服务:名叫 api-server
  2. 模拟的恶意服务:名叫 hacker

我们在终端里敲下这两行命令,把它们跑起来:

1. 模拟合法的访问者 (贴上身份标签 role=api-server)

kubectl run api-server --image=busybox --labels=role=api-server -n auth-space -- sleep 3600

2. 模拟非法的访问者 (贴上可疑标签 role=hacker)

kubectl run hacker --image=busybox --labels=role=hacker -n auth-space -- sleep 3600

💡 小知识: 结尾的 -- sleep 3600 是为了让没有常驻进程的 busybox 容器持续运行,方便我们接下来“钻”进容器里做测试。

在没有安全策略的情况下,如果我们分别进入这两个容器去访问 mysql,你会发现:两者都能瞬间秒连。K8s 根本不在乎你是谁,只要网络通,一律放行。

🛡️ 破局:部署 NetworkPolicy 建立白名单

在云原生时代,我们不再基于 IP 去做防火墙策略(因为 Pod 的 IP 随时会变),而是基于 Label(标签)

我们需要写一张“安保规则”告诉 Kubernetes:

“去守住带有 db=mysql 标签的 Pod,只允许带有 role=api-server 标签的家伙进来,其他人一律拉黑!”

将这个逻辑翻译成 K8s 听得懂的 YAML 配置,长这样:

mysql-policy.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mysql-security-policy
namespace: auth-space
spec:

1. 保护谁?保护带有 db=mysql 标签的 Pod

podSelector:
matchLabels:
db: mysql

2. 限制什么方向的流量?入站 (Ingress)

policyTypes:

  • Ingress

3. 白名单里有谁?只允许带有 role=api-server 标签的 Pod

ingress:

  • from:
    • podSelector:
      matchLabels:
      role: api-server

保存文件并应用策略:

kubectl apply -f mysql-policy.yaml

🎯 见证奇迹:微隔离生效了吗?

规则下发后,底层网络插件(如 Calico 或 Cilium)会瞬间更新节点上的 iptables/eBPF 规则。让我们重新测试一下访问权限。

第一步:合法访问者测试 我们让 api-server 再次尝试呼叫 mysql,并设置 2 秒超时:

kubectl exec -n auth-space api-server -- wget -qO- --timeout=2 mysql

太棒了!这个选题非常契合当下云原生安全(DevSecOps)的热点,既有理论深度,又有可以直接“抄作业”的代码,非常容易受到技术读者的欢迎。

以下为你精心撰写的博客正文。你可以直接复制发布到掘金、CSDN、知乎或你个人的独立博客中。


K8s 零信任实战:如何用 NetworkPolicy 拦截集群内的“非法访问”?

标签: Kubernetes / 云原生安全 / NetworkPolicy / 实战教程 字数: 约 1500 字 阅读时长: 5 分钟


在很多人的潜意识里,Kubernetes 内部是一个绝对安全的“乌托邦”:只要把服务部署到了集群里,不暴露 NodePort 或者 Ingress,外部黑客就打不进来,内部服务也是绝对安全的。

但现实往往很骨感。Kubernetes 的默认网络模型是“扁平且全开放”的。

这意味着什么?这意味着如果你的集群里运行着一个电商系统和一个内部财务系统,只要它们在同一个集群网络下,电商系统里的任意一个微服务,都可以畅通无阻地 ping 通财务系统里的核心数据库!一旦某个边缘微服务存在漏洞被拿下,攻击者就能以此为跳板,在集群内部横向移动(Lateral Movement)。

今天,我们就来实战演练一把:如何打破这种“全连通”的默认状态,用 NetworkPolicy(网络策略) 给核心服务穿上防弹衣。

🔪 场景重现:合法的 API 与非法的“黑客”

假设我们在 auth-space 命名空间下,运行着一个极其重要的数据库服务 mysql(带有标签 db=mysql)。

现在,集群里潜伏着两个访客:

  1. 合法的业务服务:名叫 api-server
  2. 模拟的恶意服务:名叫 hacker

我们在终端里敲下这两行命令,把它们跑起来:

Bash

# 1. 模拟合法的访问者 (贴上身份标签 role=api-server)
kubectl run api-server --image=busybox --labels=role=api-server -n auth-space -- sleep 3600

# 2. 模拟非法的访问者 (贴上可疑标签 role=hacker)
kubectl run hacker --image=busybox --labels=role=hacker -n auth-space -- sleep 3600
💡 小知识: 结尾的 -- sleep 3600 是为了让没有常驻进程的 busybox 容器持续运行,方便我们接下来“钻”进容器里做测试。

在没有安全策略的情况下,如果我们分别进入这两个容器去访问 mysql,你会发现:两者都能瞬间秒连。K8s 根本不在乎你是谁,只要网络通,一律放行。

🛡️ 破局:部署 NetworkPolicy 建立白名单

在云原生时代,我们不再基于 IP 去做防火墙策略(因为 Pod 的 IP 随时会变),而是基于 Label(标签)

我们需要写一张“安保规则”告诉 Kubernetes:

“去守住带有 db=mysql 标签的 Pod,只允许带有 role=api-server 标签的家伙进来,其他人一律拉黑!”

将这个逻辑翻译成 K8s 听得懂的 YAML 配置,长这样:

YAML

# mysql-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: mysql-security-policy
  namespace: auth-space
spec:
  # 1. 保护谁?保护带有 db=mysql 标签的 Pod
  podSelector:
    matchLabels:
      db: mysql
  
  # 2. 限制什么方向的流量?入站 (Ingress)
  policyTypes:
  - Ingress
  
  # 3. 白名单里有谁?只允许带有 role=api-server 标签的 Pod
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: api-server

保存文件并应用策略:

Bash

kubectl apply -f mysql-policy.yaml

🎯 见证奇迹:微隔离生效了吗?

规则下发后,底层网络插件(如 Calico 或 Cilium)会瞬间更新节点上的 iptables/eBPF 规则。让我们重新测试一下访问权限。

第一步:合法访问者测试 我们让 api-server 再次尝试呼叫 mysql,并设置 2 秒超时:

Bash

kubectl exec -n auth-space api-server -- wget -qO- --timeout=2 mysql

结果: 成功获取到响应数据。因为它的标签完美命中了白名单规则,保安微微一笑,予以放行。

第二步:非法访问者测试 现在,轮到 hacker 出场了:

kubectl exec -n auth-space hacker -- wget -qO- --timeout=2 mysql

结果: 终端卡住,过了 2 秒后弹出残酷的报错:wget: download timed out。 网络层直接把它的请求丢弃了(Drop),它连 mysql 的大门在哪都摸不到。

💡 核心总结 (Takeaways)

通过这个小实验,我们需要将以下三个概念刻在脑子里:

  1. 默认全开,显式拒绝:K8s 默认网络是不设防的。但一旦你针对某个 Pod 绑定了哪怕一条 NetworkPolicy,它就会瞬间变成“默认拒绝(Default Deny)”状态,只有规则里写明的才放行。
  2. 认签不认人:K8s 的网络防火墙不看你的 Pod 叫什么名字,也不看你的 IP 是多少,唯一查验的凭证就是 Label。身份管理即标签管理。
  3. 零信任的基石:这种将防御边界缩小到单个容器级别的方法,被称为“微隔离(Micro-segmentation)”。这是构建云原生零信任架构的第一步。

下次在部署高优核心业务时,别忘了给它写一份 NetworkPolicy,别让你的服务在集群里“裸奔”!

阅读更多

Service 到底把流量发给了谁?解密 K8s 隐藏的功臣:Endpoint

在 Kubernetes 的日常操作中,你一定遇到过这样令人抓狂的场景: 你部署了一个 Nginx 的 Pod,状态是 Running;你又为它创建了一个 Service,IP 也分配了。一切看起来都很完美,但是当你用 curl 去访问这个 Service 时,得到的却是无尽的等待(Timeout)或者连接拒绝(Connection Refused)。 “我的 Pod 活得好好的,Service 也建了,流量到底死在哪个环节了?” 今天,我们就来揭开 K8s 网络中这个最容易被忽视的隐藏功臣——Endpoint 的神秘面纱。弄懂了它,你将掌握 K8s 内部网络排错的终极密码。 ☎️ 通俗类比:客服热线与接线员 在传统的认知里,很多人以为 K8s 的网络拓扑是这样的: 外部流量 ->

By GFrank

再也不为底层发愁:用“租房模型”秒懂 Kubernetes 的 PV 与 PVC

如果你刚接触 Kubernetes,在搞定了 Pod 和 Deployment 后,往往会一头撞死在“持久化存储”的墙上。 在传统的单机时代,我们要存数据,直接把宿主机的目录挂载(Volume 映射)进容器就行了。但在 K8s 这种到处漂移的分布式集群里,如果 Pod 挂了,被重新调度到另一台机器上,它原本写在本地硬盘上的数据就全丢了。 为了解决这个问题,K8s 引入了网络存储(如 NFS、Ceph、阿里云云盘等)。但是,如果让写业务代码的程序员去关心底层挂载的是 Ceph 还是阿里云盘,还要写一堆复杂的连接配置,这就太反人类了。 于是,K8s 架构师们大笔一挥,发明了两个伟大的抽象概念:PV 和 PVC。 今天,我们不扯枯燥的官方文档,直接用“租房模型”让你秒懂这套机制。 🏠 角色一:

By GFrank
鄂ICP备2026019394号-1