4. Longhorn 存储类(StorageClass):自定义参数与默认设置
在 Kubernetes 中,StorageClass 是动态卷供给的核心抽象。Longhorn 通过 CSI 驱动注册了名为 longhorn 的默认 StorageClass,但生产环境往往需要根据工作负载特性(性能、容灾、成本)定制多个 StorageClass。本章深入解析 Longhorn StorageClass 的关键参数:副本数、数据局部性、磁盘选择器,以及如何设置默认 StorageClass。
4.1 Longhorn StorageClass 参数体系
Longhorn 的 StorageClass 通过 parameters 字段控制卷的行为。下表列出最常用的自定义参数:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
numberOfReplicas |
int | 3 | 卷的副本数,决定数据冗余级别 |
dataLocality |
string | disabled | 数据局部性策略:disabled / best-effort / strict-local |
diskSelector |
string | "" | 基于磁盘标签的调度过滤,逗号分隔 |
nodeSelector |
string | "" | 基于节点标签的调度过滤,逗号分隔 |
replicaAutoBalance |
string | disabled | 副本自动平衡:disabled / least-effort / best-effort |
staleReplicaTimeout |
int | 30 | 失效副本保留时间(分钟) |
fromBackup |
string | "" | 从指定备份创建卷的 BackupURL |
encrypted |
bool | false | 是否启用卷加密(需配置密钥) |
最佳实践: 建议为不同工作负载创建独立的 StorageClass。例如:
longhorn-ssd(高 IOPS,副本数=2,磁盘选择 SSD 标签)、longhorn-archive(副本数=1,数据局部性=strict-local,磁盘选择 HDD 标签)。
4.2 副本数(numberOfReplicas)
副本数决定卷的数据冗余级别。每个卷的引擎将数据同步写入所有副本,副本分布在不同的节点上(默认策略)。
- 副本数=1: 无冗余,单节点故障即丢失数据。仅用于测试或临时卷。
- 副本数=2: 容忍单副本故障,但无法保证数据一致性恢复(脑裂风险)。
- 副本数=3: 生产推荐值,容忍单节点故障,支持自动重建。
- 副本数>3: 用于跨 AZ 或跨数据中心场景,增加写入延迟。
注意: 副本数增加会线性消耗存储空间和网络带宽。例如 100Gi 卷,副本数=3 时实际占用 300Gi 裸容量(未计算快照和日志开销)。
4.3 数据局部性(dataLocality)
数据局部性控制副本与使用该卷的 Pod 之间的物理位置关系,直接影响读写延迟和故障域。
| 策略 | 行为 | 适用场景 |
|---|---|---|
disabled |
副本可调度到任意节点,不保证与 Pod 同节点 | 通用场景,平衡负载 |
best-effort |
优先将至少一个副本调度到 Pod 所在节点;若资源不足则回退到 disabled | 对延迟敏感但允许偶尔跨节点 |
strict-local |
强制所有副本与 Pod 在同一节点;若无法满足则卷创建失败 | 极致本地 IO 性能,如数据库本地日志 |
性能影响: strict-local 模式下,读写完全本地化,无网络开销;但节点故障会导致卷不可用,需配合 Pod 反亲和或节点故障转移策略。
4.4 磁盘选择器(diskSelector)
磁盘选择器允许基于磁盘标签(Disk Tags)过滤副本的放置目标。Longhorn 节点可以挂载多块磁盘,每块磁盘可设置多个标签(如 ssd、nvme、hdd、fast)。
配置示例:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-ssd
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "2"
dataLocality: "best-effort"
diskSelector: "ssd,fast"
nodeSelector: "storage-role=worker"
reclaimPolicy: Delete
volumeBindingMode: Immediate
上述配置要求:
- 副本仅放置到同时包含
ssd和fast标签的磁盘上。 - 节点必须具有
storage-role=worker标签。 - 若没有满足条件的磁盘,卷创建会进入
Degraded状态并等待资源。
4.5 默认 StorageClass 设置
Kubernetes 集群中只能有一个默认 StorageClass。Longhorn 安装后会自动将 longhorn 标记为默认。切换默认 StorageClass 的两种方式:
- 删除旧默认: 移除原默认 StorageClass 的
storageclass.kubernetes.io/is-default-class: "true"注解。 - 设置新默认: 为目标 StorageClass 添加注解
storageclass.kubernetes.io/is-default-class: "true"。
命令示例:
# 查看当前默认
kubectl get sc -o json | jq '.items[] | select(.metadata.annotations["storageclass.kubernetes.io/is-default-class"]=="true") | .metadata.name'
# 设置 longhorn-ssd 为默认
kubectl annotate sc longhorn-ssd storageclass.kubernetes.io/is-default-class=true --overwrite
# 移除原默认
kubectl annotate sc longhorn storageclass.kubernetes.io/is-default-class-
变更影响: 修改默认 StorageClass 不会影响已创建的 PVC。新创建的 PVC(未指定 storageClassName)将使用新的默认 StorageClass。建议在变更前确认所有工作负载的存储需求。
4.6 StorageClass 参数与卷调度流程
下图展示 Longhorn 根据 StorageClass 参数调度卷副本的完整流程:
4.7 多 StorageClass 管理策略
生产环境建议按以下维度划分 StorageClass:
| StorageClass 名称 | 副本数 | 数据局部性 | 磁盘选择器 | 典型用途 |
|---|---|---|---|---|
longhorn |
3 | disabled | 无 | 通用生产卷 |
longhorn-ssd |
2 | best-effort | ssd | 数据库、缓存 |
longhorn-local |
1 | strict-local | nvme | 本地日志、临时数据 |
longhorn-archive |
3 | disabled | hdd,archive | 冷数据、备份 |
变更门禁集成: 在 CI/CD 流水线中,可通过
kubectl diff 或 Longhorn API 对比 StorageClass 参数变更。建议在预发环境验证新 StorageClass 的副本调度是否符合预期,再推送到生产集群。