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

云原生存储与网络方案选型:从 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 混合存储方案

yaml 复制代码
# 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 训练的高性能存储选择

go 复制代码
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 网络策略配置

yaml 复制代码
# 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 RBD CephFS Local PV
IOPS 中等(网络开销) 低(元数据瓶颈) 极高(本地NVMe)
多节点共享 不支持 支持 不支持
数据持久性 副本冗余 副本冗余 单点(依赖节点可靠性)
运维复杂度 高(Ceph集群维护)
适用场景 数据库、消息队列 训练数据共享 AI训练临时数据

网络选型对比

维度 Calico iptables Calico eBPF Cilium 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 方案的收益;第三步,逐步替换,每次只变更一个变量,确保问题可归因。避免一步到位引入全套复杂方案,否则故障排查时无法定位根因。

相关推荐
m0_图灵灵1 小时前
吴恩达《深度学习》之深度剖析Batch Norm 作用机制的本质
人工智能·深度学习·batch
InsightCore1 小时前
iOS 27改了一个15年的手势,苹果决定让你的肌肉记忆失效
人工智能
柠檬味的Cat1 小时前
GEO优化系统是什么?具体做什么,有什么用?
大数据·人工智能·aigc
用户276247978501 小时前
上下文压缩,无脑调 LLM 总结是下策:我给 Agent 框架设计的三级压缩流水线
人工智能
2601_949499941 小时前
芯瑞科技800G硅光模块:为工业智能时代打造高速可靠的光互联底座
人工智能·科技·机器人
小博测试成长之路1 小时前
行业日报 | 2026年6月12日:Claude新模型、鸿蒙开发者大会与AI工程化加速
人工智能·harmonyos
snpgroupcn1 小时前
云转型过程中, 如何有效推进Rise with SAP项目实施
大数据·人工智能·云转型
小糖学代码1 小时前
机器学习:9.贝叶斯分类器
人工智能·机器学习
聆思科技AI芯片1 小时前
AI语音视觉开发板对接 OpenClaw 龙虾实现多模态交互
人工智能·学习·交互·语音识别·智能硬件