云计算划分标准与Kubernetes NetworkPolicy深度解析

在云计算与容器编排领域,"资源交付模式"和"网络安全隔离"是两大核心议题。本文将先系统梳理云计算的三层划分标准(IaaS/PaaS/SaaS),再聚焦Kubernetes网络隔离的核心方案----NetworkPolicy,详解其原理、配置规则与实际应用,帮你理解容器网络"连通"之外的"隔离"逻辑。

一、云计算核心划分标准:IaaS、PaaS、SaaS

云计算的本质是"按需交付IT资源",根据交付的资源抽象层次,分为三大类服务模式。三者的核心区别在于"用户需要管理的资源范围"----层次越高,用户需要关心的底层细节越少。

服务模式 全称(中文) 核心交付内容 用户管理范围 典型案例
IaaS 基础设施即服务 虚拟化硬件资源(虚拟机、裸金属服务器、存储、网络) 需自行管理操作系统、中间件、应用程序(如在虚拟机上装 Linux+MySQL + 业务系统) AWS EC2、阿里云 ECS、腾讯云 CVM
PaaS 平台即服务 预置了运行环境的开发 / 部署平台(容器集群、数据库、消息队列、中间件) 无需管理硬件和操作系统,仅需关注应用代码和配置(如在 K8s 上部署 Java 应用) AWS EKS、阿里云 ACK、Google App Engine
SaaS 软件即服务 直接可用的应用软件(多租户模式,通过账号密码访问) 零底层管理成本,仅需使用软件功能(如用邮箱、财务系统) 阿里云企业邮箱、钉钉、 Salesforce

关键对比:用户责任边界

  • IaaS:用户=管理者+开发者(管OS到应用)
  • PaaS:用户=开发者(只管应用代码)
  • SaaS:用户=使用者(只管操作软件)

例如:同样是"部署一个电商网站"

  • IaaS模式:先买ECS虚拟机,装CentOS+Nginx+Mysql,再传代码;
  • PaaS模式:在ACK(阿里云K8s)上直接部署容器化的代码,数据库用阿里云RDS(托管服务);
  • SaaS模式:直接用Shopify等现成电商平台,注册账号即可开店。

二、Kubernetes 网络隔离:为什么需要 NetworkPolicy?

再前面讲解K8s容器网络方案时,核心关注"容器如何连通"(如Pod跨节点通信、Service负载均衡),但默认情况下,K8s的网络是"全通的"----所有Pod可以自由收发流量,没有任何隔离。

这种"全通模式"在生产环境存在严重安全隐患:

  • 多租户场景:租户A的Pod可能访问租户B的敏感服务(如数据库);
  • 微服务场景:非前端Pod直接访问数据库Pod(跳过权限校验);
  • 故障扩散:被入侵的Pod可能横向渗透其他服务。

Kubernetes解决网络隔离的方案,就是通过NetworkPolicy 这个API对象,定义**"流量白名单"**----明确哪些Pod可以和哪些Pod/IP通信,实现"按需隔离"。

注:什么是"流量白名单"什么是"流量黑名单"?

  • 流量白名单:默认拒绝所有流量,仅明确加入白名单的可信对象(如特定IP、用户)可通过的访问控制策略。
  • 流量黑名单:默认允许所用流量,仅明确加入黑名单的恶意对象(如攻击IP、违规用户)被拒绝的访问控制策略。

三、NetworkPolicy 核心概念与工作原理

NetworkPolicy是K8s中描述"网络访问规则"的资源,仅作用于特定Namespace下的Pod,核心是**"选中Pod+定义规则"。**

3.1 基础前提:NetworkPolicy 的生效条件

  1. **CNI插件支持:**并非所有K8s网络插件都支持NetworkPolicy,需使用Calico、Weave、Kube-router等(Flannel不支持,需额外部署Calico补充);
  2. **Namespace作用域:**NetworkPolicy是Namespace级资源,仅对所在Namespace的Pod生效;
  3. 默认行为:
  • 未被任何NetworkPolicy选中的Pod:允许所有流量(入站+出站);
  • 被NetworkPolicy选中的Pod:拒绝所有流量(入站+出站),仅放行规则中定义的白名单。

3.2 NetworkPolicy 核心字段解析

先看一个完整的 NetworkPolicy 示例,再逐个拆解字段含义:

复制代码
apiVersion: networking.k8s.io/v1  # 固定API版本(K8s 1.8+)
kind: NetworkPolicy
metadata:
  name: test-network-policy        # 资源名
  namespace: default               # 作用的Namespace(仅对default下的Pod生效)
spec:
  podSelector:                     # 1. 选中要隔离的Pod(核心:通过标签匹配)
    matchLabels:
      role: db                     # 仅隔离default下标签为role=db的Pod
  policyTypes:                     # 2. 规则类型(Ingress=入站流量,Egress=出站流量)
  - Ingress
  - Egress
  ingress:                         # 3. 入站流量规则(允许哪些流量进来)
  - from:                          # 3.1 入站白名单(来源)
    - ipBlock:                     # 来源1:IP段
        cidr: 172.17.0.0/16        # 允许172.17.0.0/16网段的流量
        except:                    # 排除该网段下的172.17.1.0/24(黑名单中的白名单)
        - 172.17.1.0/24
    - namespaceSelector:           # 来源2:Namespace标签
        matchLabels:
          project: myproject       # 允许所有标签为project=myproject的Namespace下的Pod
    - podSelector:                 # 来源3:Pod标签
        matchLabels:
          role: frontend           # 允许default下标签为role=frontend的Pod
    ports:                         # 3.2 允许入站的端口(仅放行6379端口)
    - protocol: TCP
      port: 6379
  egress:                          # 4. 出站流量规则(允许哪些流量出去)
  - to:                            # 4.1 出站白名单(目的地)
    - ipBlock:
        cidr: 10.0.0.0/24          # 仅允许访问10.0.0.0/24网段
    ports:                         # 4.2 允许出站的端口(仅放行5978端口)
    - protocol: TCP
      port: 5978

关键字段拆解

  1. podSelector:"隔离目标" 的筛选器

    • 作用:指定当前 NetworkPolicy 对哪些 Pod 生效(通过标签匹配);
    • 特殊情况:若 podSelector: {}(空),则对当前 Namespace 下所有 Pod生效;
    • 示例中:仅隔离defaultNamespace 下标签为role=db的 Pod(如数据库 Pod)。
  2. policyTypes:规则类型声明

    • 取值:Ingress(入站,别人访问 Pod)、Egress(出站,Pod 访问别人),可同时声明;
    • 注意:若未声明policyTypes,K8s 会自动推断 ------ 有ingress字段则加Ingress,有egress字段则加Egress
  3. ingress:入站流量规则("谁能访问我")

    • 核心由from(来源白名单)和ports(端口白名单)组成,需同时满足才放行;
    • from支持三种来源:
      • ipBlock:指定 IP 网段(如172.17.0.0/16),可通过except排除部分网段;
      • namespaceSelector:指定符合标签的 Namespace(如project=myproject,该 Namespace 下所有 Pod 均可访问);
      • podSelector:指定符合标签的 Pod(仅当前 Namespace 下的 Pod)。
  4. egress:出站流量规则("我能访问谁")

    • 核心由to(目的地白名单)和ports(端口白名单)组成;
    • to的取值与from一致(ipBlock/namespaceSelector/podSelector);
    • 示例中:仅允许role=db的 Pod 访问10.0.0.0/24网段的 5978 端口(如某个中间件服务)。

3.3 易混淆点:from/to 中的 "与 / 或" 关系

在定义from(入站来源)或to(出站目的地)时,多个条件的组合关系(与/或)是最容易出错的地方,需重点区分:

情况 1:"或" 关系(多个独立的 from 条目)
复制代码
ingress:
- from:
  - namespaceSelector:  # 条件A:Namespace标签为project=myproject
      matchLabels:
        project: myproject
  - podSelector:        # 条件B:Pod标签为role=frontend
      matchLabels:
        role: frontend
  • 逻辑:满足条件 A 或 条件 B 即可放行;
  • 示例:来自project=myprojectNamespace 的 Pod, defaultNamespace 下role=frontend的 Pod,都能访问隔离 Pod。
情况 2:"与" 关系(单个 from 条目下的多个条件)
复制代码
ingress:
- from:
  - namespaceSelector:  # 条件A:Namespace标签为project=myproject
      matchLabels:
        project: myproject
    podSelector:        # 条件B:Pod标签为role=frontend
      matchLabels:
        role: frontend

四、NetworkPolicy 实际应用案例

结合生产场景,通过几个典型案例理解 NetworkPolicy 的配置逻辑。

案例 1:数据库Pod隔离(仅允许前端Pod访问)

场景:default Namespace下有role=db的数据库Pod(端口6379),仅允许同Namespace下 role=frontend的前端Pod访问,拒绝其他流量。

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-isolation
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db  # 隔离目标:数据库Pod
  policyTypes:
  - Ingress    # 仅控制入站流量(出站不限制,数据库可正常访问其他服务)
  ingress:
  - from:
    - podSelector:  # 仅允许前端Pod访问
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379  # 仅放行数据库端口
  • 效果:
    • 前端 Pod(role=frontend)可访问数据库 6379 端口;
    • 其他 Pod(如role=backend)无法访问数据库;
    • 数据库 Pod 的出站流量不受限(可正常连接存储、日志服务)。

案例 2:多租户隔离(仅允许本租户 Namespace 访问)

场景:租户 A 的服务部署在tenant-aNamespace(标签tenant=A),租户 B 的服务在tenant-bNamespace(标签tenant=B),要求租户 A 的 Pod 只能被tenant-aNamespace 下的 Pod 访问。

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tenant-a-isolation
  namespace: tenant-a  # 作用于租户A的Namespace
spec:
  podSelector: {}  # 隔离目标:租户A下所有Pod
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:  # 仅允许租户A的Namespace访问
        matchLabels:
          tenant: A
  • 效果:
    • tenant-a下的 Pod 可互相访问;
    • tenant-b或其他 Namespace 的 Pod 无法访问tenant-a的 Pod;
    • 若需开放部分服务给其他租户,可在from中追加其他namespaceSelector

案例 3:限制 Pod 出站流量(仅允许访问特定 IP)

场景:prodNamespace 下的应用 Pod(标签env=prod),仅允许访问公司内网192.168.0.0/16网段,禁止访问公网,避免数据泄露。

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: prod-egress-control
  namespace: prod
spec:
  podSelector:
    matchLabels:
      env: prod  # 隔离目标:生产环境Pod
  policyTypes:
  - Egress  # 仅控制出站流量(入站不限制)
  egress:
  - to:
    - ipBlock:
        cidr: 192.168.0.0/16  # 仅允许访问内网网段
    - ipBlock:
        cidr: 10.96.0.0/12    # 允许访问K8s Service网段(如访问CoreDNS、内部Service)
  • 效果:
    • 生产 Pod 可访问内网服务和 K8s 内部 Service;
    • 生产 Pod 无法访问公网 IP(如8.8.8.8);
    • 若需临时开放某个公网服务,可在to中追加对应ipBlock

注:什么是ipBlock?

ipBlock 是 Kubernetes 网络策略(NetworkPolicy)等场景中,用于指定一组 IP 地址或 IP 地址段(如 192.168.1.0/24),以定义允许或拒绝该 IP 范围流量通行的配置规则。

五、NetworkPolicy 底层实现:iptables 规则

NetworkPolicy 本身只是 "规则描述",真正实现流量隔离的是CNI 插件的 NetworkPolicy 控制器 (如 Calico 的 Felix 组件)。其核心原理是:在 Pod 所在宿主机上生成 iptables 规则,过滤进出 Pod 的流量

实现流程

  1. CNI插件的NetworkPolicy控制器监听K8s API,实时获取NetworkPolicy的增删改查事件;
  2. 对于被NetworkPolicy选中的Pod,控制器根据规则生成对应的iptables链(如KUBE-NWPLCY-XXX);
  3. 将iptables规则挂载到宿主机的INPUT/OUTPUT链或Pod的网络命名空间中,实现流量过滤
  4. 当流量到达Pod时,iptables会检查是否匹配白名单规则,匹配则放行,否则拒绝。

查看宿主机 iptables 规则(示例)

在运行role=dbPod 的宿主机上,可通过iptables-save | grep KUBE-NWPLCY查看生成的规则,例如:

复制代码
# 允许来自role=frontend的Pod访问db Pod的6379端口
-A KUBE-NWPLCY-DEFAULT-DB-ISOLATION -s 10.244.1.5/32 -p tcp --dport 6379 -j ACCEPT
# 拒绝其他所有入站流量
-A KUBE-NWPLCY-DEFAULT-DB-ISOLATION -j REJECT --reject-with icmp-port-unreachable

六、总结:NetworkPolicy 关键要点

  1. 默认行为反转:被 NetworkPolicy 选中的 Pod,默认 "拒绝所有流量",仅放行白名单;未被选中的 Pod,默认 "允许所有流量";
  2. 规则是白名单:NetworkPolicy 只定义 "允许什么",不定义 "拒绝什么"(拒绝是默认行为);
  3. Namespace 作用域:NetworkPolicy 无法跨 Namespace 生效,需在每个 Namespace 单独配置(或用 Helm 批量部署);
  4. CNI 支持是前提:Flannel 不支持 NetworkPolicy,需搭配 Calico 等插件;生产环境推荐直接使用 Calico(兼顾网络连通与隔离)。

通过 NetworkPolicy,K8s 实现了 "细粒度的网络隔离",满足多租户、微服务安全、合规等生产需求,是容器网络从 "能通" 到 "安全通" 的关键组件。

点赞+收藏+关注,下期我们接着唠嗑。

相关推荐
问简8 小时前
docker 镜像相关
运维·docker·容器
Benszen9 小时前
Docker容器化技术实战指南
运维·docker·容器
Hommy889 小时前
【开源剪映小助手】Docker 部署
docker·容器·开源·github·aigc
斯普信云原生组11 小时前
Prometheus 环境监控虚机 Redis 方案(生产实操版)
运维·docker·容器
喵了几个咪11 小时前
如何在 Superset Docker 容器中安装 MySQL 驱动
mysql·docker·容器·superset
工具罗某人11 小时前
docker compose部署kafka集群搭建
docker·容器·kafka
刘~浪地球12 小时前
架构设计--事件驱动架构设计与实现(05)
云原生·系统架构·云计算
Luke~12 小时前
阿里云计算巢已上架!3分钟部署 Loki AI 事故分析引擎,SRE 复盘时间直接砍掉 80%
人工智能·阿里云·云计算·loki·devops·aiops·sre
Database_Cool_12 小时前
基于PolarDB Mem0 为 OpenClaw 构建高效记忆系统(阿里云开发者)
阿里云·云计算
❀͜͡傀儡师12 小时前
k8s部署的Nexus 3 数据库损坏恢复指南:从删除损坏数据库到完整数据重建
数据库·kubernetes·nexus3