云原生存储与网络方案选型:从 CSI 到 CNI 的架构决策与落地实践
2026/6/12 20:44:42 网站建设 项目流程

云原生存储与网络方案选型:从 CSI 到 CNI 的架构决策与落地实践

一、存储与网络——云原生架构中"看不见的承重墙"

在 Kubernetes 集群中,存储和网络是最容易被忽视的底层基础设施。应用开发者关注 Pod 能不能跑起来、服务能不能访问,却很少追问:PV 挂载的 IOPS 够不够、CNI 的网络策略是否把跨命名空间流量堵死了、存储卷的快照恢复能不能满足 RTO 要求。直到生产环境出现训练任务 I/O 等待、跨节点 Pod 通信延迟飙升、数据卷迁移导致服务中断,这些"承重墙"的问题才会暴露。

存储和网络选型不是"选一个能用的就行"——不同的工作负载对 IOPS、吞吐、延迟、一致性有着截然不同的要求。AI 训练需要高吞吐的并行文件系统,数据库需要低延迟的块存储,日志采集需要弹性扩展的对象存储。网络层面,Service Mesh 的 Sidecar 代理会引入额外延迟,eBPF 方案绕过内核协议栈但调试困难,选择哪个方案直接影响服务间通信的性能上限。

二、存储与网络的底层机制剖析

2.1 CSI 存储架构

graph LR subgraph "Kubernetes 存储架构" PVC[PVC 声明] -->|绑定| PV[PV 持久卷] PV -->|动态供给| SC[StorageClass] SC -->|调用| CSIDriver[CSI Driver] subgraph "CSI Driver 内部" CSIC[CSI Controller] CSIN[CSI Node Plugin] end CSIDriver --> CSIC CSIDriver --> CSIN CSIC -->|CreateVolume| Backend1[Ceph RBD] CSIC -->|CreateVolume| Backend2[Local PV] CSIN -->|Mount| NodeFS[节点文件系统] end

CSI(Container Storage Interface)将存储供给拆分为两个阶段:

Controller 阶段:CSI Controller 负责卷的创建/删除/快照。以 Ceph RBD 为例,Controller 调用 Ceph MON 创建 RBD Image,映射为 Kubernetes PV。这个阶段只处理元数据操作,不涉及数据读写。

Node 阶段:CSI Node Plugin 运行在每个节点上,负责将卷挂载到 Pod 的文件系统命名空间。对于块存储,Node Plugin 执行rbd map将 RBD Image 映射为本地块设备,再mount到 Pod 目录。对于文件存储,Node Plugin 直接mount -t ceph挂载 CephFS 路径。

关键差异在于:块存储(RBD)经过内核块设备层,支持fsync保证数据持久性,但单卷只能被单节点挂载;文件存储(CephFS)支持多节点同时读写,但元数据服务可能成为瓶颈。

2.2 CNI 网络架构

graph TB subgraph "节点网络栈" PodA[Pod A] -->|veth pair| BR[网桥 cni0] PodB[Pod B] -->|veth pair| BR BR -->|路由| ETH[eth0] subgraph "数据包路径" direction LR App[应用程序] -->|syscall| TCP[TCP/IP 栈] TCP -->|iptables| Filter[Netfilter] Filter -->|veth| BR2[网桥] end end subgraph "eBPF 优化路径" PodC[Pod C] -->|BPF 程序| BPFMap[eBPF Map] BPFMap -->|直达| ETH2[eth0] end

传统 CNI(如 Calico iptables 模式)的数据包路径:Pod → veth pair → 网桥 → iptables 规则匹配 → 路由 → 物理网卡。每次跨 Pod 通信都要经过完整的内核协议栈和 iptables 链式匹配,当集群规模超过 1000 节点时,iptables 规则数量膨胀导致匹配延迟显著增加。

eBPF 方案(如 Cilium)绕过 iptables,在 socket 层直接将数据包从源 Pod 的 socket 重定向到目标 Pod 的 socket,跳过中间的协议栈处理。这在同节点 Pod 通信场景下,延迟可降低 30-50%。

三、生产级存储与网络方案实现

3.1 Ceph RBD + CephFS 混合存储方案

# StorageClass:块存储(数据库、消息队列等低延迟场景) apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-rbd-sc provisioner: rbd.csi.ceph.com parameters: clusterID: ceph-cluster-01 pool: kubernetes-rbd imageFormat: "2" imageFeatures: layering csi.storage.k8s.io/provisioner-secret-name: ceph-secret csi.storage.k8s.io/node-stage-secret-name: ceph-secret reclaimPolicy: Retain # 生产环境禁止动态删除,防止误操作 allowVolumeExpansion: true # 支持在线扩容 mountOptions: - discard # 支持 TRIM,自动回收已删除数据的存储空间 --- # StorageClass:文件存储(AI 训练数据共享、日志汇聚等高吞吐场景) apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cephfs-sc provisioner: cephfs.csi.ceph.com parameters: clusterID: ceph-cluster-01 fsName: kubernetes-cephfs pool: cephfs-data csi.storage.k8s.io/provisioner-secret-name: ceph-secret csi.storage.k8s.io/node-stage-secret-name: ceph-secret reclaimPolicy: Retain

3.2 本地 PV 方案:AI 训练的高性能存储选择

package storage import ( "context" "fmt" "os" "path/filepath" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // LocalPVManager 管理本地持久卷的创建与清理 // 核心思路:AI训练需要NVMe级别的IOPS,网络存储无法满足 type LocalPVManager struct { basePath string // 本地存储根目录,如 /mnt/nvme nodeName string // 当前节点名称 storageCap resource.Quantity // 节点可用存储容量 } // CreateLocalPV 为指定训练任务创建本地PV // 使用Kubernetes Local Persistent Volume机制,保证卷与节点绑定 func (m *LocalPVManager) CreateLocalPV(ctx context.Context, taskID string, size resource.Quantity) (*corev1.PersistentVolume, error) { volPath := filepath.Join(m.basePath, taskID) // 创建存储目录,设置权限 if err := os.MkdirAll(volPath, 0755); err != nil { return nil, fmt.Errorf("创建存储目录失败: %w", err) } pv := &corev1.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("local-pv-%s", taskID), }, Spec: corev1.PersistentVolumeSpec{ Capacity: corev1.ResourceList{ corev1.ResourceStorage: size, }, // Local PV必须指定nodeAffinity,确保Pod调度到正确的节点 NodeAffinity: &corev1.VolumeNodeAffinity{ Required: &corev1.NodeSelector{ NodeSelectorTerms: []corev1.NodeSelectorTerm{ { MatchExpressions: []corev1.NodeSelectorRequirement{ { Key: "kubernetes.io/hostname", Operator: corev1.NodeSelectorOpIn, Values: []string{m.nodeName}, }, }, }, }, }, }, AccessModes: []corev1.PersistentVolumeAccessMode{ corev1.ReadWriteOnce, // 本地存储仅支持单节点读写 }, PersistentVolumeReclaimPolicy: corev1.Retain, StorageClassName: "local-nvme-sc", PersistentVolumeSource: corev1.PersistentVolumeSource{ Local: &corev1.LocalVolumeSource{ Path: volPath, FSType: ptrToString("ext4"), }, }, }, } return pv, nil } func ptrToString(s string) *string { return &s }

3.3 Cilium eBPF 网络策略配置

# CiliumNetworkPolicy:基于身份的细粒度网络隔离 # 相比传统NetworkPolicy,支持L7层规则(HTTP方法、DNS查询等) apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: ai-training-egress namespace: ai-platform spec: endpointSelector: matchLabels: app: training-job egress: # 允许访问Ceph MON节点(存储IO) - toEndpoints: matchLabels: app: ceph-mon toPorts: - ports: - port: "6789" protocol: TCP # 允许访问外部模型仓库,但限制HTTP方法为GET - toFQDNs: - matchName: "huggingface.co" toPorts: - ports: - port: "443" protocol: TCP rules: http: - method: GET # 允许DNS解析 - toEndpoints: matchLabels: k8s:io.kubernetes.pod.namespace: kube-system k8s-app: kube-dns toPorts: - ports: - port: "53" protocol: UDP

四、方案选型的 Trade-offs 分析

存储选型对比

维度Ceph RBDCephFSLocal PV
IOPS中等(网络开销)低(元数据瓶颈)极高(本地NVMe)
多节点共享不支持支持不支持
数据持久性副本冗余副本冗余单点(依赖节点可靠性)
运维复杂度高(Ceph集群维护)
适用场景数据库、消息队列训练数据共享AI训练临时数据

网络选型对比

维度Calico iptablesCalico eBPFCilium eBPF
规则匹配延迟高(O(n)链式匹配)低(eBPF Map查找)低(eBPF Map查找)
L7 策略支持不支持不支持支持(HTTP/gRPC/DNS)
可观测性依赖 tcpdump基础指标Hubble 全景可观测
内核版本要求无特殊要求≥ 4.18≥ 4.19(部分特性需 5.x)
运维复杂度

关键边界条件

  • Local PV 的 Pod 调度被绑定到特定节点,当该节点故障时数据不可恢复。因此 Local PV 仅适用于可重建的临时数据(如训练 checkpoint),不适用于持久化业务数据
  • Ceph 集群的 PG(Placement Group)数量直接影响 IOPS 分布。PG 数量过少导致数据倾斜,过多增加 MON 负载。经验公式:每个 OSD 约 100-200 个 PG
  • Cilium 的 eBPF 程序在内核态执行,调试困难。当网络策略导致流量异常时,缺乏传统 iptables 的--log机制,需要依赖 Hubble 可观测平台排查

五、总结

云原生存储与网络的选型,本质上是在性能、可靠性和运维成本之间做权衡。存储层面,核心决策路径是:需要多节点共享选 CephFS,需要低延迟选 Ceph RBD,需要极致 IOPS 选 Local PV。网络层面,小规模集群用 Calico iptables 足够,大规模集群或需要 L7 策略时切换到 Cilium eBPF。

落地建议分三步推进:第一步,先用最简方案(Calico + Ceph RBD)跑通业务;第二步,根据监控数据定位瓶颈——如果是存储 I/O 瓶颈,评估是否需要 Local PV 加速;如果是网络延迟瓶颈,评估 eBPF 方案的收益;第三步,逐步替换,每次只变更一个变量,确保问题可归因。避免一步到位引入全套复杂方案,否则故障排查时无法定位根因。

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

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

立即咨询