K8s 核心接口:CNI、CSI、CRI、LB 一篇讲透

K8s 之所以能成为云原生的「操作系统」,靠的就是这套可插拔的接口设计。搞懂 CNI、CSI、CRI、LB,你对 K8s 架构的理解会上一个台阶。


一、K8s 的四大核心接口是什么

CNI、CSI、CRI 是 Kubernetes 的三大核心扩展接口,分别定义了网络、存储、运行时的标准。它们的设计哲学一致:K8s 只定义接口,具体实现交给插件。

LB(Load Balancer)则不同------它不是 K8s 的内部接口,而是 Service 的一种对外暴露方式,通常依赖云厂商的负载均衡器或软件实现(如 MetalLB)。

1. 为什么需要这些接口

K8s 作为一个容器编排平台,面临三个必须解决的底层问题:

  1. 网络:Pod 怎么分配 IP?Pod 之间怎么通信?跨节点怎么路由?
  2. 存储:Pod 重启后数据怎么保留?怎么对接外部存储系统?
  3. 运行时:容器由谁来创建、启停、销毁?

如果 K8s 把这些能力硬编码进内核,就会跟特定实现绑死。通过定义标准接口,任何符合规范的插件都能接入------这就是「可插拔架构」的核心价值。

复制代码
┌─────────────────────────────────────────────────────┐
│                   Kubernetes API                     │
├──────────────┬──────────────┬────────────────────────┤
│     CNI      │     CSI      │         CRI            │
│  (网络接口)   │  (存储接口)   │     (运行时接口)        │
├──────────────┼──────────────┼────────────────────────┤
│ Calico       │ Ceph CSI     │ containerd             │
│ Flannel      │ NFS CSI      │ CRI-O                  │
│ Cilium       │ 云盘 CSI      │ Docker (已废弃)         │
└──────────────┴──────────────┴────────────────────────┘

二、CNI --- 容器网络接口

1. 什么是 CNI

CNI(Container Network Interface)定义的是容器网络的标准。它的核心职责:

  • 为每个 Pod 分配独立的 IP 地址
  • 让同一集群内任意两个 Pod 能够直接通信(无需 NAT)
  • 让节点上的 kubelet 能够调用 CNI 插件完成网络配置

没有 CNI,Pod 就只能跟同一节点上的 Pod 通信,跨节点完全不通。

2. 主流 CNI 插件对比

插件 特点 适用场景
Flannel 架构简单,支持 VXLAN/host-gw,性能中等;VXLAN 模式下每次转发都要额外封包/解包 测试/小规模集群
Calico BGP 路由协议实现纯三层路由转发,支持 NetworkPolicy(Pod 级别防火墙),性能优秀 生产环境首选
Cilium 基于 eBPF,高性能,L7 可见性,支持 Service Mesh 高性能/安全要求高
Weave 支持加密,配置简单 中小型集群
Kube-OVN 基于 OVN/OVS,企业级 SDN 架构,VPC 多租户、Underlay 能力强,功能最全 OpenShift / 大型集群

各插件一句话总结:

  • Flannel:最简单、最轻量,只做网络连通,啥高级功能都没有
  • Calico:纯三层路由 + BGP,性能强,NetworkPolicy 强,通用云原生首选
  • Cilium:eBPF 加持,性能天花板最高,适合对网络性能和可观测性有极致要求的场景
  • Kube-OVN:企业级 SDN 架构,VPC 多租户、Underlay 强、功能最全,灵雀云自家核心 CNI

3. 选型建议

场景 推荐
个人实验 / 最小集群 Flannel
通用生产环境 Calico
高安全 / 高性能要求 Cilium
大型企业 / 多租户 / OpenShift Kube-OVN

大多数中小团队的生产集群,Calico 是最稳妥的选择------功能完备、社区活跃、排坑资料多。


三、CSI --- 容器存储接口

1. 什么是 CSI

CSI(Container Storage Interface)是 K8s 与外部存储系统之间的标准接口。容器本身是无状态的------Pod 一删,数据就没了。CSI 让 Pod 能以标准化的方式挂载外部持久化存储,保障数据不丢失。

通过 CSI 接口对接第三方存储插件(如 NFS、CephFS、各云厂商云盘),实现存储卷的创建、挂载、卸载、删除。典型场景:数据库 Pod 的数据留存、日志持久化、共享文件存储。

2. 存储流程

一条完整的存储生命周期,涉及四个步骤:

2.1 用户创建 PVC

用户声明存储需求:大小(如 10Gi)、访问模式(ReadWriteOnce / ReadWriteMany)、指定 StorageClass。

2.2 PV Controller 创建 PV 并绑定

PV Controller 通过 StorageClass 调用 CSI 插件创建实际的存储资源(PV),并完成 PVC 与 PV 的绑定。

2.3 kubelet 挂载存储

Pod 被调度后,kubelet 调用 CSI 插件,将存储卷挂载到容器的指定路径。

2.4 Pod 删除时卸载

Pod 删除时,CSI 插件依次执行存储卸载、解绑操作。根据 PV 的回收策略(Retain / Delete / Recycle),决定底层存储是保留还是删除。

复制代码
用户创建 PVC  →  PV Controller 调用 CSI 创建 PV  →  kubelet 挂载到 Pod  →  Pod 删除时 CSI 卸载

3. PV / PVC / StorageClass 详解

这是 K8s 存储体系里最容易搞混的三个概念,用一句话说清楚:

概念 角色 类比
PV(PersistentVolume) 集群中的实际存储资源 停车场的车位
PVC(PersistentVolumeClaim) 用户对存储的需求声明 停车券(我要一个车位)
StorageClass 动态存储分配策略 自动泊车系统(按需分配)

三种模式:

  • 静态供给:管理员手动创建 PV,用户创建 PVC 后自动绑定匹配的 PV
  • 动态供给:用户只创建 PVC + StorageClass,系统自动创建 PV 并绑定------这是大规模生产环境的标准做法
  • StorageClass 的关键参数:provisioner(用哪个 CSI 插件)、reclaimPolicy(删除策略)、parameters(存储类型、IOPS 等)
yaml 复制代码
# 一个典型的 StorageClass 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: disk.csi.azure.com  # ← CSI 插件
parameters:
  skuName: Premium_LRS           # ← 高性能 SSD
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

四、CRI --- 容器运行时接口

1. 什么是 CRI

CRI(Container Runtime Interface)是 K8s 与容器运行时之间的接口。控制平面(kubelet)通过 CRI 接口向容器运行时发送指令:创建容器、启动容器、停止容器、删除容器。

CNCF 推动了 CRI 的标准化,让 K8s 不再绑死某一种容器运行时。只要实现了 CRI 规范的运行时(containerd、CRI-O 等),都能无缝接入。

2. Docker 与 Containerd 区别

这是很多人搞混的点。K8s 1.20 起正式废弃 dockershim,1.24 起彻底移除。背后发生了什么?

对比维度 Docker Containerd
定位 完整的容器工具链(构建、运行、编排) 专注容器运行时
组件 dockerd + containerd + runc containerd + runc
冗余 自带构建、compose、swarm 等 K8s 用不到的功能 只有 K8s 需要的运行能力
与 K8s 对接 需要 dockershim 适配层(已废弃) 直接实现 CRI 接口
资源占用 较高 较低
OCI 标准 通过 containerd 间接实现 原生支持

简单说:Docker 是个瑞士军刀,containerd 是那把刀。K8s 只需要刀,不需要军刀上那些开瓶器、剪刀。

生产环境推荐 containerd,理由有三:

  • 稳定性更好(少一层 dockerd,少一个故障点)
  • 资源占用更低(精简组件、少一个守护进程)
  • 集群兼容性更好(所有主流 K8s 发行版默认 containerd)

五、LB --- 负载均衡器

1. 什么是 LB

LB(Load Balancer)不是 K8s 的内部接口,而是 Service 的一种对外暴露方式。它的作用:将外部流量分发到后端的多个 Pod 上,实现高可用和负载均衡。

2. Service 类型对比

K8s 的 Service 有四种类型,分别对应不同的流量暴露方式:

类型 访问范围 IP 类型 典型场景
ClusterIP 集群内部 虚拟 IP 微服务间调用
NodePort 节点 IP + 固定端口 节点 IP:30000-32767 测试/临时暴露
LoadBalancer 外部,通过云 LB 云厂商分配公网/内网 IP 生产环境对外服务
ExternalName DNS CNAME 映射 无独立 IP 外部服务映射

3. LoadBalancer 的工作原理

LoadBalancer 类型的 Service 创建后,K8s 会调用云厂商的 Cloud Controller Manager(CCM),向云平台申请一个负载均衡器实例。云 LB 将流量转发到各节点的 NodePort 端口,再分发到 Pod。

自建集群怎么办?

如果集群不在公有云上(比如裸金属或自己搭的集群),没有云 LB 可用,就需要部署软件 LB:

  • MetalLB:最常用的开源方案,支持 Layer2 和 BGP 模式
  • OpenELB:青云开源的替代方案
  • Traefik / Nginx Ingress:七层负载,适合 HTTP/HTTPS 流量
yaml 复制代码
# 云环境下的 LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer       # ← 云厂商会自动创建 LB
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080

六、总结

把四者的关系放在一起看:

接口 解决什么问题 如果没有它
CNI Pod 网络:IP 分配、跨节点通信 Pod 孤立,只能同节点通信
CSI 持久化存储:数据不随 Pod 销毁而丢失 数据库 Pod 重启数据全丢
CRI 容器管理:创建、启停、销毁容器 K8s 不知道上哪跑容器
LB 流量入口:把外部流量均匀分给 Pod 外面的人根本访问不到你的服务

一句话总结:

CNI 管网络,CSI 管存储,CRI 管容器,LB 管入口。搞懂这四个,K8s 的底层架构你就摸清了七成。

相关推荐
香气袭人知骤暖1 小时前
人大金仓(KingbaseES)Docker 容器自动备份方案
运维·docker·容器
Devin~Y2 小时前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
大熊程序猿2 小时前
MarkItDown Docker安装
运维·docker·容器
IT策士2 小时前
第25篇 k8s之Deployment 基础:声明式管理与副本控制
云原生·容器·kubernetes
IT策士3 小时前
第 26 篇 k8s之Deployment 进阶:滚动更新、回滚与暂停
云原生·容器·kubernetes
老毛肚3 小时前
Docker Desktop 介绍
运维·docker·容器
张忠琳3 小时前
【kubernetes v1.21】(kubelet 2)容器运行时与CRI
云原生·架构·kubernetes·kubelet
张忠琳3 小时前
【kubernetes v1.21】(kubelet 3)PLEG、健康检查、Eviction 与状态管理
云原生·架构·kubernetes·kubelet
秋漓4 小时前
Kubernetes了解与应用
云原生·容器·kubernetes