云计算划分标准与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 的生效条件
- CNI插件支持:并非所有K8s网络插件都支持NetworkPolicy,需使用Calico、Weave、Kube-router等(Flannel不支持,需额外部署Calico补充);
- Namespace作用域:NetworkPolicy是Namespace级资源,仅对所在Namespace的Pod生效;
- 默认行为:
- 未被任何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的PodpolicyTypes: # 2. 规则类型(Ingress=入站流量,Egress=出站流量)- Ingress- Egressingress: # 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的Podports: # 3.2 允许入站的端口(仅放行6379端口)- protocol: TCPport: 6379egress: # 4. 出站流量规则(允许哪些流量出去)- to: # 4.1 出站白名单(目的地)- ipBlock:cidr: 10.0.0.0/24 # 仅允许访问10.0.0.0/24网段ports: # 4.2 允许出站的端口(仅放行5978端口)- protocol: TCPport: 5978
关键字段拆解
podSelector:“隔离目标” 的筛选器
- 作用:指定当前 NetworkPolicy 对哪些 Pod 生效(通过标签匹配);
- 特殊情况:若
podSelector: {}
(空),则对当前 Namespace 下所有 Pod生效; - 示例中:仅隔离
default
Namespace 下标签为role=db
的 Pod(如数据库 Pod)。
policyTypes:规则类型声明
- 取值:
Ingress
(入站,别人访问 Pod)、Egress
(出站,Pod 访问别人),可同时声明; - 注意:若未声明
policyTypes
,K8s 会自动推断 —— 有ingress
字段则加Ingress
,有egress
字段则加Egress
。
- 取值:
ingress:入站流量规则(“谁能访问我”)
- 核心由
from
(来源白名单)和ports
(端口白名单)组成,需同时满足才放行; from
支持三种来源:ipBlock
:指定 IP 网段(如172.17.0.0/16
),可通过except
排除部分网段;namespaceSelector
:指定符合标签的 Namespace(如project=myproject
,该 Namespace 下所有 Pod 均可访问);podSelector
:指定符合标签的 Pod(仅当前 Namespace 下的 Pod)。
- 核心由
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=myprojectmatchLabels:project: myproject- podSelector: # 条件B:Pod标签为role=frontendmatchLabels:role: frontend
- 逻辑:满足条件 A 或 条件 B 即可放行;
- 示例:来自
project=myproject
Namespace 的 Pod,或default
Namespace 下role=frontend
的 Pod,都能访问隔离 Pod。
情况 2:“与” 关系(单个 from 条目下的多个条件)
ingress:
- from:- namespaceSelector: # 条件A:Namespace标签为project=myprojectmatchLabels:project: myprojectpodSelector: # 条件B:Pod标签为role=frontendmatchLabels: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-isolationnamespace: default
spec:podSelector:matchLabels:role: db # 隔离目标:数据库PodpolicyTypes:- Ingress # 仅控制入站流量(出站不限制,数据库可正常访问其他服务)ingress:- from:- podSelector: # 仅允许前端Pod访问matchLabels:role: frontendports:- protocol: TCPport: 6379 # 仅放行数据库端口
- 效果:
- 前端 Pod(
role=frontend
)可访问数据库 6379 端口; - 其他 Pod(如
role=backend
)无法访问数据库; - 数据库 Pod 的出站流量不受限(可正常连接存储、日志服务)。
- 前端 Pod(
案例 2:多租户隔离(仅允许本租户 Namespace 访问)
场景:租户 A 的服务部署在tenant-a
Namespace(标签tenant=A
),租户 B 的服务在tenant-b
Namespace(标签tenant=B
),要求租户 A 的 Pod 只能被tenant-a
Namespace 下的 Pod 访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: tenant-a-isolationnamespace: tenant-a # 作用于租户A的Namespace
spec:podSelector: {} # 隔离目标:租户A下所有PodpolicyTypes:- Ingressingress:- from:- namespaceSelector: # 仅允许租户A的Namespace访问matchLabels:tenant: A
- 效果:
tenant-a
下的 Pod 可互相访问;tenant-b
或其他 Namespace 的 Pod 无法访问tenant-a
的 Pod;- 若需开放部分服务给其他租户,可在
from
中追加其他namespaceSelector
。
案例 3:限制 Pod 出站流量(仅允许访问特定 IP)
场景:prod
Namespace 下的应用 Pod(标签env=prod
),仅允许访问公司内网192.168.0.0/16
网段,禁止访问公网,避免数据泄露。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: prod-egress-controlnamespace: prod
spec:podSelector:matchLabels:env: prod # 隔离目标:生产环境PodpolicyTypes:- 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 的流量。
实现流程
- CNI插件的NetworkPolicy控制器监听K8s API,实时获取NetworkPolicy的增删改查事件;
- 对于被NetworkPolicy选中的Pod,控制器根据规则生成对应的iptables链(如KUBE-NWPLCY-XXX);
- 将iptables规则挂载到宿主机的INPUT/OUTPUT链或Pod的网络命名空间中,实现流量过滤
- 当流量到达Pod时,iptables会检查是否匹配白名单规则,匹配则放行,否则拒绝。
查看宿主机 iptables 规则(示例)
在运行role=db
Pod 的宿主机上,可通过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 关键要点
- 默认行为反转:被 NetworkPolicy 选中的 Pod,默认 “拒绝所有流量”,仅放行白名单;未被选中的 Pod,默认 “允许所有流量”;
- 规则是白名单:NetworkPolicy 只定义 “允许什么”,不定义 “拒绝什么”(拒绝是默认行为);
- Namespace 作用域:NetworkPolicy 无法跨 Namespace 生效,需在每个 Namespace 单独配置(或用 Helm 批量部署);
- CNI 支持是前提:Flannel 不支持 NetworkPolicy,需搭配 Calico 等插件;生产环境推荐直接使用 Calico(兼顾网络连通与隔离)。
通过 NetworkPolicy,K8s 实现了 “细粒度的网络隔离”,满足多租户、微服务安全、合规等生产需求,是容器网络从 “能通” 到 “安全通” 的关键组件。
点赞+收藏+关注,下期我们接着唠嗑。