目录
Please enable Javascript to view the contents

K8s存储-高级特性详解

 ·  ☕ 3 分钟

系列导航

本系列从 K8s 存储模型入手,逐步展开到 CSI 插件实现与云原生存储全景。

① 概念 → ② Volume 生命周期 → ③ CSI 架构 → ④ FlexVolume 演进 → ⑤ 对比 → ⑥ 排障 ‖ ⑦ 开发 → ⑧ 高级特性 → ⑨ 演进展望

顺序文章定位
概念与入门基础——K8s 存储模型、PV/PVC/StorageClass
Volume 生命周期全解析全貌——两阶段处理、动态/静态供应
CSI 架构详解标准——gRPC 三服务、Sidecar 模式
FlexVolume 与 CSI 演进演进——FlexVolume 原理、CSI 设计思想
存储方案对比与选型选型——主流 CSI 插件横向对比
排障思路与常用命令运维——工具链 + 场景排查
核心路径 ↑扩展展望 ↓
CSI 插件开发指南扩展——从零开发一个 CSI 插件
本篇 - 高级特性详解进阶——快照、克隆、扩容、拓扑感知
云原生存储演进与展望展望——容器原生存储、DPU 卸载

重要

CSI 的高级特性(快照、克隆、扩容、拓扑感知)都建立在 CSI Spec v1.1+ 基础上,通过额外的 CRD 和 Sidecar 实现。这些特性使 K8s 存储具备生产级数据管理能力。


1. Volume Snapshot(卷快照)

1.1 概念

快照是 Volume 在某一时间点的只读副本,用于备份和恢复。

CRD说明
VolumeSnapshotClass定义快照的参数(类似 StorageClass)
VolumeSnapshot用户创建的快照请求
VolumeSnapshotContent实际快照资源(类似 PV)

1.2 流程

创建 VolumeSnapshot(引用 VolumeSnapshotClass + PVC)
  ↓
external-snapshotter 监听 → 调 CSI CreateSnapshot
  ↓
CSI 插件在存储后端创建快照 → 返回 Snapshot ID
  ↓
external-snapshotter 创建 VolumeSnapshotContent
  ↓
快照 Ready,可用于恢复

1.3 使用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1. 创建快照
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: data-snapshot
spec:
  volumeSnapshotClassName: csi-snapshot
  source:
    persistentVolumeClaimName: data-pvc
---
# 2. 从快照恢复
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restored-pvc
spec:
  storageClassName: fast
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 100Gi
  dataSource:
    name: data-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io

2. Volume Clone(卷克隆)

2.1 概念

克隆是从现有 PVC 创建一个相同大小和内容的新 Volume。

维度快照克隆
依赖需要 VolumeSnapshot CRD直接引用 PVC
用途定期备份复制数据用于测试/分析
中间产物VolumeSnapshotContent无(直接创建新 PV)

2.2 使用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cloned-pvc
spec:
  storageClassName: fast
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 100Gi    # 必须 ≥ 源 PVC
  dataSource:
    name: source-pvc    # 源 PVC 名
    kind: PersistentVolumeClaim

3. Volume Expansion(卷扩容)

3.1 两阶段扩容

阶段执行者CSI 接口说明
ControllerExpandexternal-resizer → CSI 插件ControllerExpandVolume扩容底层存储容量
NodeExpandkubelet → CSI 插件NodeExpandVolume扩容文件系统

3.2 使用方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 修改 PVC 的 storage 请求即可触发扩容
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  storageClassName: fast   # StorageClass 必须设置 allowVolumeExpansion: true
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 200Gi   # 从 100Gi 扩到 200Gi
1
2
3
4
5
6
7
# StorageClass 需要允许扩容
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: csi.example.com/volume
allowVolumeExpansion: true   # 关键
扩容是"在线操作"——Pod 不需要重启。但只能扩容不能缩容。文件系统类型不同,NodeExpand 的行为不同:ext4/xfs 在线扩容,raw block 不需要文件系统扩容。

4. Topology(拓扑感知)

4.1 问题

某些存储系统(如云盘、Local PV)的 Volume 只能被特定节点访问。如果 Pod 被调度到没有对应 Volume 的节点,Attach 会失败。

4.2 解决方案

CSI 插件通过 GetPluginCapabilities 声明支持拓扑,然后:

  1. CSI 插件在 CreateVolume 时指定 AccessibilityRequirements(可访问拓扑)
  2. K8s 调度器根据 CSI 插件声明的拓扑信息过滤节点
  3. 确保 Pod 调度到能访问该 Volume 的节点
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// CSI 插件声明支持拓扑
func (d *Driver) GetPluginCapabilities(ctx context.Context, req *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) {
    return &csi.GetPluginCapabilitiesResponse{
        Capabilities: []*csi.PluginCapability{
            {
                Type: &csi.PluginCapability_Service_{
                    Service: &csi.PluginCapability_Service{
                        Type: csi.PluginCapability_Service_CONTROLLER_SERVICE,
                    },
                },
            },
            {
                Type: &csi.PluginCapability_VolumeExpansion_{
                    VolumeExpansion: &csi.PluginCapability_VolumeExpansion{
                        Type: csi.PluginCapability_VolumeExpansion_ONLINE,
                    },
                },
            },
        },
    }, nil
}

// NodeGetInfo 返回节点拓扑标签
func (d *Driver) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) {
    return &csi.NodeGetInfoResponse{
        NodeId: d.nodeID,
        AccessibleTopology: &csi.Topology{
            Segments: map[string]string{
                "topology.example.com/zone": "zone-1",
            },
        },
    }, nil
}

4.3 常见拓扑维度

拓扑键说明典型场景
topology.kubernetes.io/zone可用区云盘只能在本区 Attach
topology.kubernetes.io/region地域跨区存储延迟过高
topology.example.com/rack机架Ceph 集群按机架划分

5. 特性支持矩阵

特性CSI SpecK8s 版本依赖 CRD
动态供应v0.3+1.13+
拓扑感知v1.0+1.14+
卷扩容v1.0+1.16+
卷快照v1.0+1.17+(GA)VolumeSnapshot
卷克隆v1.0+1.18+(GA)

参考链接

分享

Hex
作者
Hex
CloudNative Developer