云原生存储与网络方案选型:从 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 方案的收益;第三步,逐步替换,每次只变更一个变量,确保问题可归因。避免一步到位引入全套复杂方案,否则故障排查时无法定位根因。

相关推荐
cspttty1 小时前
2027校招AI产品经理准备指南:数据科学专业如何从模型走向产品
人工智能·产品经理
倔强的石头1061 小时前
多模态大模型架构_视觉语言模型VLM原理
人工智能·语言模型·自然语言处理
MiYi124061 小时前
2026深度体验:智能体办公工具助力企业协同效率提升实测
大数据·人工智能
198******126341 小时前
2026年企业AI办公工具选型指南:如何匹配业务场景完成评估
大数据·运维·人工智能
是翎1 小时前
Cube Forms:让 AI agents 直接填表,人也能随时接手
人工智能
I Am a robert girl1 小时前
从路由信号到选择性复核:MoE 视觉语言模型的视觉重定位
人工智能·语言模型·自然语言处理·视觉语言模型·混合专家模型·路由信号·目标缺失接地
W***25921 小时前
2026年企业级Work Agent品类科普指南
人工智能
小黄人软件1 小时前
【智答宝】RAG本地问答助手,RAG 的技术原理
人工智能
CRMEB系统商城1 小时前
CRMEB开源商城系统(PHP)v8.0,打造全新AI二开商城底座!
开发语言·人工智能·小程序·开源·php
玫瑰互动GEO1 小时前
百度AI问答81.7%信源百度系:技术品牌GEO优化 3步自查工程化解读
人工智能·百度·ai·dubbo·ai搜索·geo优化