尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【架构实战】Kubernetes存储实战:从EmptyDir到Ceph CSI的持久化存储选型指南

【架构实战】Kubernetes存储实战:从EmptyDir到Ceph CSI的持久化存储选型指南 【架构实战】Kubernetes存储实战从EmptyDir到Ceph CSI的持久化存储选型指南上篇聊了K8s故障排查这篇接上存储——这是K8s里最容易踩坑、也最容易被低估的部分。很多人以为挂个PV就行了结果生产环境遇到数据库被调度到新节点数据丢失、读写分离应用连不到同一个PVC、存储性能瓶颈拖垮整个集群……存储选型不对轻则发布抖动重则数据永失。这篇把K8s存储从原理到选型讲透帮你避开那些文档里没写但踩了就炸的坑。一、先理解PV/PVC的抽象价值很多人觉得PV/PVC是多此一举直接挂路径不就行了不对。PV/PVC解决的核心问题是存储供给与消费解耦PVPersistent Volume存储管理员视角描述我有块存储100GB性能XX类型是NFS/Ceph/iSCSI不关心谁用PVCPersistent Volume Claim应用开发者视角声明我要100GB读写模式RWO存储类SSD不关心底层是谁提供的StorageClass存储类定义这类存储怎么动态创建PV把管理员从手动创建PV的苦海中解放出来。三者的关系PVC绑定PVPV由StorageClass动态创建或管理员手动创建Pod通过PVC使用存储。一层抽象一层自由——应用开发者不用关心底层是NFS还是Ceph存储管理员不用关心哪个应用用哪块盘。二、临时存储EmptyDir与HostPath2.1 EmptyDirPod内的临时共享空间EmptyDir在Pod创建时分配Pod删除时数据随之消失。典型场景缓存目录不需要持久化临时计算结果MapReduce中间文件InitContainer与主容器共享数据配置生成、代码拉取。volumes:-name:cache-volumeemptyDir:{}# 默认用节点磁盘# 也可以用内存更快但大小受Pod内存限制volumes:-name:tmp-volumeemptyDir:medium:MemorysizeLimit:512Mi注意EmptyDir的生命周期绑死Pod不是容器。Pod里所有容器共享同一个EmptyDir容器重启数据不丢Pod删除数据才消失。2.2 HostPath挂节点路径慎用HostPath把节点上的路径挂到Pod里常见于节点监控Agent访问/proc、/sys日志采集访问/var/log单机测试环境绕过网络存储。volumes:-name:node-logshostPath:path:/var/logtype:Directory致命风险HostPath绕过了K8s的存储抽象数据与节点绑定Pod被调度到新节点就找不到原数据。生产环境慎用甚至禁用通过PodSecurityPolicy限制。我见过多次事故数据库用HostPath节点故障迁移后数据消失实际还在旧节点上。三、网络存储NFS、Ceph、GlusterFS3.1 NFS最简单但也最脆弱NFS是K8s里最常见的共享存储配置简单一个PV多个Pod同时读写。volumes:-name:nfs-volumenfs:server:192.168.1.100path:/data/sharedreadOnly:false优点部署简单一台NFS服务器即可支持ReadWriteMany多Pod同时读写数据不在节点上Pod迁移不影响数据。缺点单点故障NFS服务器挂了所有依赖它的Pod全废性能瓶颈NFS协议本身开销大高并发写容易卡顿文件锁不可靠某些应用如SQLite依赖文件锁NFS的锁机制在Pod跨节点时有坑。适用场景配置中心、静态资源、日志归档、对性能要求不高的共享数据。数据库、消息队列这种高IO应用别用NFS。3.2 Ceph RBD高性能块存储Ceph是分布式存储系统RBDRADOS Block Device是其块存储接口在K8s里用StorageClass动态创建PV。apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:ceph-rbdprovisioner:rbd.csi.ceph.comparameters:pool:rbdclusterID:ceph-clustercsi.storage.k8s.io/provisioner-secret-name:ceph-secretcsi.storage.k8s.io/node-stage-secret-name:ceph-secretreclaimPolicy:DeleteallowVolumeExpansion:true优点高性能块设备直接映射到Pod接近本地盘性能高可用Ceph多副本节点故障数据不丢动态扩容PVC扩容后Ceph自动扩展RBD镜像。缺点ReadWriteOnce一个PVC只能被一个Pod挂载块存储特性多Pod共享需要用CephFS部署复杂Ceph集群本身要搭、要运维门槛不低脑裂风险网络抖动时可能触发OSD切换IO短暂中断。适用场景数据库MySQL、PostgreSQL、消息队列Kafka、RocketMQ、单实例有状态应用。3.3 CephFS共享文件系统CephFS是Ceph的文件系统接口支持ReadWriteMany多Pod共享数据。apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:cephfsprovisioner:cephfs.csi.ceph.comparameters:clusterID:ceph-clusterfsName:myfspool:cephfs-data优点兼具NFS的共享能力和Ceph的高可用。缺点性能略逊于RBDMDS元数据服务器是瓶颈。四、云厂商存储AWS EBS、阿里云盘、腾讯CBS4.1 云盘的本质云厂商的块存储AWS EBS、阿里云盘、腾讯CBS本质是远程块设备通过StorageClass自动创建。# 阿里云盘示例apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:alicloud-disk-ssdprovisioner:diskplugin.csi.alibabacloud.comparameters:type:cloud_ssdregionId:cn-hangzhoureclaimPolicy:DeleteallowVolumeExpansion:true优点免运维云厂商负责底层高可用性能分层SSD、高效云盘、普通云盘可选快照备份云盘快照一键备份恢复。缺点ReadWriteOnce一个PVC只能挂一个节点节点间迁移有短暂IO中断跨可用区受限云盘绑可用区Pod跨AZ迁移要额外配置。适用场景云上生产环境数据库、中间件等有状态应用对性能有要求。4.2 云盘的多挂特性部分云厂商支持多挂盘Multi-Attach一个云盘同时挂到多个节点但只读。适合只读数据共享场景如机器学习模型文件。五、本地存储Local PV与TopoLVM5.1 Local PV极高性能但绑定节点Local PV是节点本地的磁盘或SSD性能最高无网络开销但Pod被调度到其他节点就找不到数据。apiVersion:v1kind:PersistentVolumemetadata:name:local-pv-ssdspec:capacity:storage:500GivolumeMode:FilesystemaccessModes:-ReadWriteOncepersistentVolumeReclaimPolicy:DeletestorageClassName:local-storagelocal:path:/mnt/ssdnodeAffinity:required:nodeSelectorTerms:-matchExpressions:-key:kubernetes.io/hostnameoperator:Invalues:-node-1关键点Local PV必须配nodeAffinity绑死节点。调度器看到PVC绑定这个PV后会自动把Pod调度到对应节点。适用场景高性能数据库TiDB、Cassandra、对IO延迟极度敏感的应用。前提应用自己处理跨节点数据同步Replica。5.2 TopoLVM动态本地存储Local PV的痛点是手动创建PV、手动绑定节点。TopoLVM是开源方案自动在节点上创建LVM卷、动态分配PV支持扩容。apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:topolvm-provisionerprovisioner:topolvm.ioparameters:csi.storage.k8s.io/fstype:xfsvolumeBindingMode:WaitForFirstConsumerallowedTopologies:-matchLabelExpressions:-key:topology.kubernetes.io/zonevalues:-zone-1volumeBindingMode: WaitForFirstConsumer是关键等Pod调度到节点后再在那个节点上创建PV避免提前创建结果Pod调度不到的尴尬。六、CSI插件K8s存储的统一接口CSIContainer Storage Interface是K8s存储的标准接口所有存储厂商实现CSI插件K8s通过统一API调用。6.1 CSI核心组件Node Plugin运行在每个节点上负责挂载/卸载卷Controller Plugin负责创建/删除卷、快照、扩容External Provisioner监听PVC创建事件调用Controller Plugin创建卷External Attacher监听卷附加事件调用Controller Plugin挂载卷到节点。6.2 CSI插件的选型依据选择存储方案时评估CSI插件成熟度维度检查点功能完整性是否支持快照、扩容、克隆高可用Controller是否支持多副本故障切换时间性能延迟、吞吐、IOPS是否满足应用需求运维复杂度部署、升级、监控、故障排查难度社区活跃度Issue响应速度、Release频率、文档质量七、数据安全快照、备份、容灾7.1 VolumeSnapshotCSI标准支持快照一键备份PVC状态。apiVersion:snapshot.storage.k8s.io/v1kind:VolumeSnapshotmetadata:name:mysql-snapshot-20260814spec:volumeSnapshotClassName:csi-snapclasssource:persistentVolumeClaimName:mysql-pvc应用场景发布前快照出问题秒回滚数据库定期快照替代脚本导出开发测试环境克隆生产数据。7.2 备份方案Velero与StashVelero是K8s备份开源方案支持PV备份到对象存储S3、OSS、COS。# 备份整个命名空间velero backup create myapp-backup --include-namespaces myapp# 恢复velero restore create --from-backup myapp-backupStash是另一款工具支持应用感知备份MySQL逻辑备份、MongoDB导出等。7.3 容灾跨集群/跨云关键应用要做跨集群容灾方案有存储层复制Ceph的RBD Mirror、GlusterFS的Geo-Replication应用层复制MySQL主从、MongoDB ReplicaSet、TiDB多AZ部署K8s层迁移Velero跨集群恢复但PV要重新挂载。八、常见故障排查8.1 PVC一直Pendingkubectl describe pvcpvc-name常见原因StorageClass不存在或provisioner错误存储后端资源不足Ceph OSD满、云盘配额用光VolumeBindingMode是WaitForFirstConsumer但没有Pod使用这个PVC。8.2 Pod挂载失败kubectl describe podpod-name常见错误FailedMount节点上CSI插件异常、存储后端不可达Volume is already exclusively attached块存储被其他节点占用ReadWriteOnce限制。8.3 性能抖动NFS网络延迟、NFS服务器负载高CephOSD抖动、PG分布不均云盘底层共享资源竞争邻居效应。排查工具# 在Pod里测IO性能kubectlexec-itpod-- fio--namerandwrite--ioenginelibaio--direct1--bs4k--size1G--rwrandwrite# 在节点上测磁盘ddif/dev/zeroof/mnt/testbs1Mcount1000oflagdirect九、选型决策树最后给一个简化版选型决策树需要持久化吗 ├─ 否 → EmptyDir └─ 是 └─ 需要跨Pod共享吗 ├─ 是 │ └─ 性能要求高吗 │ ├─ 高 → CephFS │ └─ 低 → NFS └─ 否单Pod独占 └─ 性能要求极高吗 ├─ 极高 → Local PV / TopoLVM应用自己处理副本 └─ 高 → Ceph RBD / 云盘SSD记住三句话共享数据用文件存储NFS/CephFS独占数据用块存储RBD/云盘极致性能用本地盘但自己管副本。十、小结K8s存储的复杂性在于抽象层虽好但底层物理世界的限制无法回避。ReadWriteOnce是块存储的物理约束网络延迟是NFS的天花板Local PV的高性能换来的是节点绑定。选型时先想清楚应用的需求共享还是独占、性能还是成本、单AZ还是跨AZ再选对应方案别被一个PV走天下的幻觉坑了。存储选对了数据库迁移不丢数据、发布抖动不抖、性能监控不爆表。选错了轻则天天排查IO慢、重则关键时刻数据永失。把存储当核心架构决策而不是顺带挂个盘。下篇预告Kubernetes安全实战——从RBAC到PodSecurityPolicy的权限控制体系。
返回列表