一、背景认知
1.1 云原生存储的核心意义
云原生存储是容器化应用数据持久化的基础,解决了容器 "无状态" 特性带来的数据丢失问题。与传统存储相比,它具有以下特点:
- 生命周期独立:存储卷与 Pod 生命周期解耦,Pod 销毁重建后数据依然存在
- 按需弹性扩展:支持动态创建和扩容存储卷,无需提前规划所有容量
- 多类型支持:同时提供块、文件、对象三种存储模式,满足不同业务需求
- 自动化管理:通过 Kubernetes API 统一管理存储资源,减少人工干预
1.2 三大存储类型对比与选型
这是云原生存储最基础也最重要的概念,必须先搞清楚:
| 特性 | 块存储 | 文件存储 | 对象存储 |
|---|---|---|---|
| 核心比喻 | 空白硬盘 | 共享文件夹 | 无限网盘 / 仓库 |
| 数据组织 | 固定大小 "块" | 文件 + 目录树 | 对象 (数据 + 元数据 + 唯一 ID) |
| 访问接口 | 磁盘扇区读写 (iSCSI) | 文件路径 (NFS/SMB) | HTTP API(GET/PUT) |
| 性能特点 | 延迟极低 (微秒级),IOPS 高 | 延迟中等 (毫秒级) | 高吞吐,适合顺序访问 |
| 扩展性 | 纵向扩展为主 | 横向扩展有上限 | 近乎无限水平扩展 |
| 成本 | 高 | 中 | 极低 |
| 云原生典型场景 | 数据库 (MySQL/PostgreSQL)、消息队列 (Kafka) | 日志收集、配置文件共享、静态网站 | 图片视频存储、备份归档、大数据分析 |
初学者必记口诀:
- 数据库用块存储(性能第一)
- 多 Pod 共享用文件存储(易用性第一)
- 海量非结构化数据用对象存储(成本第一)
二、核心配置
2.1 物理磁盘选型标准
2.1.1 三种磁盘类型对比
| 磁盘类型 | 接口 | 典型 IOPS | 延迟 | 容量范围 | 成本 | 适用场景 |
|---|---|---|---|---|---|---|
| HDD (机械硬盘) | SATA(6Gbps)/SAS(12Gbps) | 100-200 | 5-10ms | 1-20TB | 最低 | 备份、归档、冷数据存储 |
| SATA SSD | SATA(6Gbps) | 3000-10000 | 0.1-0.5ms | 120GB-8TB | 中等 | 开发测试环境、轻量应用 |
| NVMe SSD | PCIe 3.0/4.0 | 10 万 - 100 万 + | 0.01-0.1ms | 256GB-16TB | 最高 | 生产环境核心数据库、高性能计算 |
避坑提醒:绝对不要用 HDD 运行数据库!IOPS 不足会导致查询延迟超过 100ms,业务直接不可用
2.1.2 磁盘关键指标解读
- IOPS:每秒读写操作次数,数据库、消息队列等随机读写密集型应用的核心指标
- 吞吐量:每秒传输的数据量,视频、备份等顺序读写密集型应用的核心指标
- 延迟:单次读写操作的响应时间,对用户体验影响最大
- TBW:总写入字节数,衡量 SSD 寿命的关键指标,数值越大寿命越长
2.2 容量规划方法
通用公式:
总容量 = (当前数据量 × 1.3) + 快照备份空间 + 临时文件空间
- 1.3 倍冗余:预留 30% 的缓冲空间,避免磁盘满导致系统崩溃
- 快照备份:建议预留当前数据量的 20% 作为快照空间
- 临时文件:日志、缓存等临时文件建议额外预留 30% 空间
不同业务类型参考:
- 企业官网 / 个人博客:50-200GB SSD
- 小型电商 / CRM 系统:500GB-2TB SSD
- 视频 / 图片平台:10TB+ HDD 集群
- 核心数据库:按每月 10-20% 的增长率预估 3 年需求
2.3 文件系统选择
云原生环境中最常用的两种文件系统:
| 文件系统 | 特点 | 适用场景 |
|---|---|---|
| XFS | RHEL/CentOS 默认,支持大文件,性能稳定,适合高并发 | 生产环境数据盘、数据库存储 |
| ext4 | 兼容性好,工具丰富,适合小文件多的场景 | 开发测试环境、日志存储 |
不推荐:NTFS、FAT32 等 Windows 文件系统,在 Linux 环境下性能和稳定性都较差
2.4 Kubernetes 存储核心概念
Kubernetes 通过三层抽象来管理存储资源:
- PV(PersistentVolume):集群中的一块持久化存储资源,由管理员预先创建
- PVC(PersistentVolumeClaim):Pod 对存储资源的 "申请单",描述需要的存储大小和访问模式
- StorageClass:定义存储的 "供货模板",支持动态创建 PV,无需管理员手动预分配
工作流程:
- 管理员创建 PV 或定义 StorageClass
- 用户创建 PVC 申请存储
- Kubernetes 自动匹配符合条件的 PV 或通过 StorageClass 动态创建 PV
- Pod 引用 PVC,将存储卷挂载到容器内
三、基础实操
3.1 Linux 服务器磁盘初始化(必学)
这是所有云原生存储的基础,无论使用哪种存储方案,都需要先掌握物理磁盘的基本操作。
3.1.1 步骤 1:查看系统磁盘信息
# 查看所有磁盘和分区
lsblk
# 查看详细信息(包括文件系统)
lsblk -f
# 查看挂载情况
df -TH
输出解读:
/dev/vda:通常是系统盘(虚拟机环境)/dev/vdb、/dev/vdc等:通常是数据盘/dev/nvme0n1:NVMe SSD 的命名方式
3.1.2 步骤 2:创建分区
注意 :2TB 以下磁盘可以用fdisk,2TB 以上必须用parted(GPT 分区表)
方法一:fdisk(适用于 2TB 以下磁盘)
# 进入fdisk工具,操作/dev/vdb磁盘
fdisk /dev/vdb
# 交互式操作:
Command (m for help): n # 创建新分区
Partition type: p # 主分区(默认)
Partition number: 1 # 分区号(默认1)
First sector: 回车(默认)
Last sector: 回车(使用全部空间)
Command (m for help): w # 写入分区表并退出
方法二:parted(适用于所有磁盘,推荐)
# 进入parted工具
parted /dev/vdb
# 交互式操作:
(parted) print # 查看当前分区表
(parted) mklabel gpt # 创建GPT分区表(新磁盘必须执行)
(parted) mkpart primary xfs 0% 100% # 创建一个使用全部空间的分区
(parted) print # 验证分区是否创建成功
(parted) quit # 退出
3.1.3 步骤 3:格式化分区
# 格式化为XFS(推荐生产环境使用)
mkfs.xfs /dev/vdb1
# 格式化为ext4
# mkfs.ext4 /dev/vdb1
高级格式化选项:
# XFS带卷标格式化
mkfs.xfs -L "DATA_DISK" /dev/vdb1
# ext4减少保留空间(默认保留5%,数据盘可以设为1%)
mkfs.ext4 -m 1 /dev/vdb1
3.1.4 步骤 4:挂载分区
# 创建挂载点目录
mkdir -p /mnt/data
# 临时挂载(重启后失效)
mount /dev/vdb1 /mnt/data
# 验证挂载
df -TH
3.1.5 步骤 5:配置开机自动挂载
# 备份fstab文件(重要!)
cp /etc/fstab /etc/fstab.bak
# 获取分区UUID(推荐使用UUID挂载,比设备名更稳定)
blkid /dev/vdb1
# 编辑fstab文件
vim /etc/fstab
# 添加以下内容(替换为你的UUID)
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/data xfs defaults 0 0
# 验证fstab配置是否正确(非常重要!错误会导致系统无法启动)
mount -a
# 如果没有报错,说明配置正确
挂载选项说明:
defaults:默认选项,包含 rw、suid、dev、exec、auto、nouser、asyncnoatime:不更新文件访问时间,提升性能nofail:如果磁盘不存在,系统启动时不报错
3.2 Kubernetes 静态 PV/PVC 配置与使用
静态 PV 是最基础的 Kubernetes 存储方式,适合初学者理解存储工作原理。
3.2.1 准备工作
确保你有一个运行中的 Kubernetes 集群,并且已经在节点上完成了磁盘初始化(如上面的步骤)。
3.2.2 步骤 1:创建 HostPath 类型的 PV
HostPath 类型的 PV 将节点上的本地目录作为存储卷,适合单节点集群测试使用。
创建文件hostpath-pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: hostpath-pv-10gi
spec:
capacity:
storage: 10Gi # PV容量
accessModes:
- ReadWriteOnce # 只能被一个节点读写挂载
persistentVolumeReclaimPolicy: Retain # PVC释放后保留PV数据
hostPath:
path: /mnt/data/pv1 # 节点上的目录路径
type: DirectoryOrCreate # 如果目录不存在则创建
应用配置:
kubectl apply -f hostpath-pv.yaml
# 查看PV状态
kubectl get pv
输出应该显示 PV 状态为Available
3.2.3 步骤 2:创建 PVC 申请存储
创建文件hostpath-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hostpath-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi # 申请5Gi存储
# 不指定storageClassName,使用静态PV
应用配置:
kubectl apply -f hostpath-pvc.yaml
# 查看PVC状态
kubectl get pvc
输出应该显示 PVC 状态为Bound,表示已经成功绑定到 PV
3.2.4 步骤 3:在 Pod 中使用 PVC
创建文件nginx-with-pvc.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-with-pvc
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: data-volume
mountPath: /usr/share/nginx/html # 容器内挂载路径
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: hostpath-pvc # 引用上面创建的PVC
应用配置:
kubectl apply -f nginx-with-pvc.yaml
# 查看Pod状态
kubectl get pods
3.2.5 步骤 4:验证数据持久化
# 进入Pod,创建一个测试文件
kubectl exec -it $(kubectl get pods -l app=nginx -o name) -- sh
echo "Hello Kubernetes Storage!" > /usr/share/nginx/html/test.html
exit
# 删除Pod,Kubernetes会自动重建
kubectl delete pod $(kubectl get pods -l app=nginx -o name)
# 等待Pod重建完成后,再次进入查看文件是否存在
kubectl exec -it $(kubectl get pods -l app=nginx -o name) -- cat /usr/share/nginx/html/test.html
如果能看到 "Hello Kubernetes Storage!",说明数据持久化成功!
四、高阶用法
4.1 动态存储供应(StorageClass)
静态 PV 需要管理员手动创建,效率低下。StorageClass 实现了 PV 的动态创建,是生产环境的标准用法。
4.1.1 本地路径动态供应(Local Path Provisioner)
这是最简单的动态存储方案,适合单节点或小型集群使用。
安装步骤:
# 安装Local Path Provisioner
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.26/deploy/local-path-storage.yaml
# 查看StorageClass
kubectl get storageclass
设置为默认 StorageClass:
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
使用示例 :创建文件dynamic-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
# 会自动使用默认的StorageClass
应用后,Kubernetes 会自动创建对应的 PV:
kubectl apply -f dynamic-pvc.yaml
kubectl get pv,pvc
4.2 本地持久卷(LocalVolume)
LocalVolume 直接使用节点上的本地磁盘,性能接近裸盘,适合高性能数据库等对 IO 要求极高的应用。
创建 LocalVolume PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-1
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/nvme01 # 节点上的NVMe磁盘挂载点
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-01 # 指定只能在node-01节点上使用
4.3 存储卷扩容
Kubernetes 支持在线扩容存储卷,无需停机。
前提条件:
- StorageClass 必须开启
allowVolumeExpansion: true - 底层存储支持扩容
扩容步骤:
# 编辑PVC,修改storage字段
kubectl patch pvc dynamic-pvc -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'
# 查看扩容状态
kubectl get pvc
4.4 存储快照与备份
存储快照可以快速创建存储卷的时间点备份,用于数据恢复和克隆。
创建快照:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: my-snapshot
spec:
volumeSnapshotClassName: local-path-snapshot
source:
persistentVolumeClaimName: dynamic-pvc
从快照恢复:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restored-pvc
spec:
dataSource:
name: my-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
五、拓展建议
5.1 性能调优最佳实践
-
磁盘层面:
- 数据库等高性能应用优先使用 NVMe SSD
- 开启磁盘写入缓存(注意断电保护)
- 使用
noatime挂载选项,减少不必要的 IO
-
Kubernetes 层面:
- 使用 LocalVolume 替代 HostPath,性能更好且更安全
- 为不同性能需求的应用创建不同的 StorageClass
- 避免在同一个节点上运行过多的 IO 密集型应用
-
应用层面:
- 合理设置数据库连接池大小
- 定期清理日志和临时文件
- 将热点数据缓存到内存中
5.2 安全最佳实践
-
数据加密:
- 开启存储卷静态加密
- 敏感数据使用 Kubernetes Secrets 管理
- 传输过程中使用 TLS 加密
-
访问控制:
- 使用 RBAC 限制对存储资源的访问
- 不要以 root 用户运行容器
- 设置合适的文件权限
5.3 常见问题排查
-
PVC 一直处于 Pending 状态:
- 检查是否有匹配的 PV
- 检查 StorageClass 是否存在且配置正确
- 检查节点上是否有足够的存储空间
-
Pod 无法挂载存储卷:
- 检查节点上的目录是否存在且权限正确
- 检查存储驱动是否正常运行
- 查看 Pod 事件:
kubectl describe pod <pod-name>
-
磁盘 IO 性能差:
- 使用
iostat、iotop等工具分析 IO 瓶颈 - 检查是否有进程占用大量 IO
- 考虑升级磁盘类型
- 使用
5.4 学习资源推荐
-
官方文档:
- Kubernetes 存储官方文档:https://kubernetes.io/docs/concepts/storage/
- Ceph 官方文档:https://docs.ceph.com/
-
书籍:
- 《Kubernetes 权威指南》
- 《Ceph 分布式存储实战》
-
开源项目:
- Rook:Kubernetes 上的云原生存储编排器
- Longhorn:轻量级分布式块存储
- MinIO:高性能对象存储