k8s之持久化存储流程
K8s 中的 Pod 在挂载存储卷时需经历三个的阶段:Provision/Delete(创盘/删盘)、Attach/Detach(挂接/摘除)和 Mount/Unmount(挂载/卸载)
Provisioning Volumes 时序流程详解
一、流程图
sequenceDiagramtitle Provisioning Volumes 时序流程participant 集群管理员participant 用户participant api-serverparticipant 卷控制器 as 卷控制器(PersistentVolumeController)participant ExternalProvisionerparticipant CSI插件 as CSI插件(Controller)集群管理员->>+api-server: 1 创建 StorageClass 资源(type=cloud_ssd)用户->>+api-server: 2 创建 PersistentVolumeClaim 资源卷控制器->>+api-server: 3 观察到 PVC 无匹配 PV<br/>且为 out-of-tree 类型api-server-->>-卷控制器: 返回 PVC 信息卷控制器->>api-server: 4 为 PVC 打 annotationExternalProvisioner->>+api-server: 5 观察到 PVC annotation 匹配自身api-server-->>-ExternalProvisioner: 返回 PVC 和 StorageClass 参数ExternalProvisioner->>ExternalProvisioner: 6 解析 StorageClass 参数(type=cloud_ssd)ExternalProvisioner->>+CSI插件: 7 通过 Unix Domain Socket 调用<br/>CreateVolume(name=xxx, capacity=10Gi, parameters={type=cloud_ssd})CSI插件->>CSI插件: 8 执行实际存储创建操作CSI插件-->>-ExternalProvisioner: 9 返回 VolumeID 和 VolumeContextExternalProvisioner->>+api-server: 10 创建 PV 资源<br/>(包含 VolumeID 和 CSI 卷信息)api-server-->>-ExternalProvisioner: PV 创建成功卷控制器->>+api-server: 11 检测到 PV 和 PVC 可绑定api-server-->>-卷控制器: 返回 PV/PVC 信息卷控制器->>api-server: 12 执行 PV-PVC 绑定操作
二、详细流程步骤
-
创建 StorageClass 资源
集群管理员向 API Server 提交StorageClass
资源定义(例如type=cloud_ssd
),定义存储卷的类型、后端插件、参数等配置,为后续动态创建 PV 提供模板。 -
创建 PersistentVolumeClaim(PVC)
用户通过创建 PVC 声明所需的存储资源(如容量、访问模式等),PVC 会引用步骤1中定义的 StorageClass。 -
卷控制器检测未绑定 PVC
Kubernetes 内置的 卷控制器(PersistentVolumeController) 持续监听 PVC 资源,发现未绑定且关联了 StorageClass 的 PVC(即out-of-tree
类型,依赖外部插件管理的存储)。 -
为 PVC 打标记
卷控制器为该 PVC 添加特定 Annotation(如volume.beta.kubernetes.io/storage-provisioner
),标识需要外部供应器处理。 -
External Provisioner 监听并匹配 PVC
external-provisioner
边车容器持续监听 PVC 变化,通过 Annotation 匹配到需要自身处理的 PVC,并获取对应的 PVC 和 StorageClass 配置。 -
解析存储参数
External Provisioner 解析 StorageClass 中的参数(如type=cloud_ssd
),确定存储卷的具体配置。 -
调用 CSI 插件创建卷
External Provisioner 通过 Unix Domain Socket 调用 CSI 控制器插件的CreateVolume
接口,传递卷名称、容量、参数等信息。 -
CSI 插件执行实际创建
CSI 控制器插件对接底层存储(如 AWS EBS、阿里云 EBS 等),通过云 API 或本地存储接口创建实际存储卷。 -
返回卷信息
CSI 插件创建成功后,向 External Provisioner 返回卷的唯一标识(VolumeID
)和上下文信息(VolumeContext
)。 -
创建 PV 资源
External Provisioner 基于返回的卷信息,向 API Server 创建 PersistentVolume(PV)资源,PV 中包含 CSI 卷的绑定信息。 -
卷控制器检测可绑定关系
卷控制器监听 PV 和 PVC 变化,发现新创建的 PV 与未绑定的 PVC 匹配(容量、访问模式、StorageClass 等一致)。 -
执行 PV-PVC 绑定
卷控制器通过 API Server 将 PV 与 PVC 绑定,此时 PVC 进入Bound
状态,用户 Pod 可通过 PVC 使用该存储卷。
三、不执行该流程的场景
以下情况不会触发上述动态卷供应流程,而是采用静态方式管理存储卷:
-
静态创建 PV
若集群管理员已手动创建 PV 并指定存储卷信息(如已存在的云盘 ID、本地路径等),且 PV 与 PVC 的参数(容量、访问模式、StorageClass)匹配,则卷控制器会直接绑定 PV 和 PVC,无需调用 External Provisioner 和 CSI 插件创建卷。 -
PVC 未关联 StorageClass
若 PVC 未指定storageClassName
,且集群未配置默认 StorageClass,则卷控制器会等待手动创建匹配的 PV,不会触发动态供应。 -
使用 in-tree 存储插件
对于 Kubernetes 内置的 in-tree 存储插件(如kubernetes.io/aws-ebs
,非 CSI 类型),动态供应由 Kubernetes 内部组件直接处理,无需 External Provisioner 和 CSI 插件参与。
四、组件代码位置与集群部署信息表
组件名称 | 代码位置 | 部署命名空间 | 部署形式 | 部署说明 |
---|---|---|---|---|
卷控制器(PersistentVolumeController) | kubernetes/kubernetes/pkg/controller/volume/persistentvolume/ | kube-system | 集成于 kube-controller-manager 静态 Pod | 作为 kube-controller-manager 的内置组件运行,随控制平面启动;控制节点上通过静态 Pod 配置文件(/etc/kubernetes/manifests/kube-controller-manager.yaml )定义,由 kubelet 自动管理。 |
API Server | kubernetes/kubernetes/pkg/apiserver/ kubernetes/cmd/kube-apiserver/ | kube-system | 独立静态 Pod(kube-apiserver ) | 控制平面核心组件,以静态 Pod 形式部署在控制节点;配置文件位于 /etc/kubernetes/manifests/kube-apiserver.yaml ,通过负载均衡器实现多实例高可用,接收所有集群 API 请求。 |
External Provisioner | github.com/kubernetes-csi/external-provisioner | 与 CSI 插件同命名空间(如 csi-system ) | 边车容器(Sidecar) | 与 CSI 控制器插件部署在同一 Pod 中,作为辅助容器运行;通过 Unix Domain Socket 与 CSI 插件通信,需配置 RBAC 权限以监听 PVC、创建 PV 等。 |
CSI 插件(Controller) | 各存储厂商实现 | 自定义命名空间(如 csi-system 、kube-system ) | Deployment 或 StatefulSet | 以容器化方式部署,包含控制器组件和节点组件;控制器组件需挂载主机的 Unix Domain Socket 目录(供与 External Provisioner 通信),并配置 ClusterRole 权限以访问 API 资源。 |
CSI Volume Attach 时序流程详解
一、流程图
sequenceDiagramtitle CSI Volume Attach 时序流程participant ADController as AD控制器(AttachDetachController)participant api-serverparticipant ExternalAttacherparticipant CSIDriverparticipant CloudProviderparticipant Node%% 1. AD Controller 监听 Pod 调度并触发 AttachADController->>api-server: 监听 Pod 调度事件api-server-->>ADController: 返回调度到节点的 Pod 列表ADController->>ADController: 计算待 Attach 的 PV 列表(对比节点 status.volumesAttached)ADController->>ADController: 检查 RWO 卷是否已被其他节点挂载ADController->>api-server: 调用 in-tree CSI 插件的 Attach 函数%% 2. 创建并处理 VolumeAttachment(隐式)ADController->>api-server: 创建 VolumeAttachment 资源ExternalAttacher->>api-server: 监听 VolumeAttachment 变化api-server-->>ExternalAttacher: 返回新创建的 VA%% 3. External Attacher 调用 CSI 插件ExternalAttacher->>CSIDriver: 调用 ControllerPublishVolume(PV, Node)CSIDriver->>CloudProvider: 调用云 API(如 AWS EBS Attach)CloudProvider-->>CSIDriver: 返回设备 ID(如 /dev/xvdf)CSIDriver-->>ExternalAttacher: 返回挂载成功%% 4. 更新状态(通过 API Server)ExternalAttacher->>api-server: 更新 VolumeAttachment.status.attached=trueADController->>api-server: 监听 VA 状态变化api-server-->>ADController: 返回 VA.status.attached=true%% 5. AD Controller 更新节点状态ADController->>ADController: 更新内部状态 (ActualStateOfWorld)ADController->>api-server: 更新 Node.status.volumesAttachedapi-server->>Node: 添加已挂载卷信息api-server-->>ADController: 返回更新成功
二、详细流程步骤
-
AD 控制器监听 Pod 调度事件
Kubelet 内置的 AD 控制器(AttachDetachController) 持续监听集群中 Pod 的调度结果,获取已调度到本节点的 Pod 列表,识别这些 Pod 声明的存储卷需求。 -
计算待挂载卷并检查冲突
AD 控制器对比节点当前已挂载卷(Node.status.volumesAttached
)与 Pod 所需卷,筛选出未挂载的 PV;同时对ReadWriteOnce (RWO)
类型卷进行冲突检查,确保同一卷未被其他节点挂载(避免数据不一致)。 -
触发 Attach 操作并创建 VolumeAttachment
AD 控制器调用内部 in-tree CSI 插件的Attach
函数,通过 API Server 创建VolumeAttachment
资源,记录卷与节点的绑定关系(包含 PV 标识、目标节点等信息)。 -
External Attacher 监听并处理 VolumeAttachment
External Attacher
边车容器持续监听VolumeAttachment
资源变化,发现新创建的资源后,通过 API Server 获取卷和节点信息。 -
调用 CSI 插件执行挂载
External Attacher 调用 CSI 驱动的ControllerPublishVolume
接口,传递 PV 和目标节点信息;CSI 驱动对接底层云厂商存储(如 AWS EBS、阿里云 EBS),调用云 API 执行实际的卷挂载操作(如将云盘挂载到目标节点)。 -
云厂商返回挂载结果
云厂商完成卷挂载后,向 CSI 驱动返回设备标识(如/dev/xvdf
),表示卷已成功挂载到节点。 -
更新 VolumeAttachment 状态
CSI 驱动向 External Attacher 返回挂载成功结果,External Attacher 通过 API Server 将VolumeAttachment.status.attached
更新为true
,标识卷已完成节点级挂载。 -
AD 控制器同步节点状态
AD 控制器监听VolumeAttachment
状态变化,确认挂载成功后更新内部状态(ActualStateOfWorld
),并通过 API Server 将卷信息添加到Node.status.volumesAttached
中,完成节点存储状态的同步。
三、不执行该流程的场景
1. 文件存储协议(NFS/SMB)
NFS(Network File System)和 SMB(Server Message Block)等网络文件系统通过文件级协议实现共享,无需将块设备“Attach”到节点:
- 原理:客户端直接通过网络协议(如NFS的RPC、SMB的CIFS)挂载远程共享目录,本质是建立文件路径到本地目录的逻辑映射,而非块设备与节点的绑定。
- 差异:无需创建
VolumeAttachment
资源或调用ControllerPublishVolume
接口,直接通过mount
命令或文件系统驱动完成网络目录挂载。
2. 对象存储协议(S3/OSS)
S3(Amazon Simple Storage Service)、阿里云 OSS 等对象存储服务基于 HTTP/HTTPS API 提供对象访问,完全不涉及节点级挂载:
- 原理:客户端通过 RESTful API(如
PUT
/GET
)直接操作对象(文件、图片等),无需将存储设备关联到节点。 - 差异:无块设备或文件系统挂载过程,通过 SDK 或工具(如
s3fs
)实现对象与本地目录的映射,但不属于 CSI Attach 流程范畴。
3. 静态挂载的本地存储卷
hostPath
、local
等本地存储类型的 PV 依赖节点本地文件系统或目录,无需网络存储的 Attach 流程:
- 原理:卷对应的路径直接存在于节点本地(如
/data/local-vol
),Pod 通过绑定到该节点直接访问本地路径。 - 差异:无需云厂商 API 调用或
VolumeAttachment
资源,Kubelet 直接验证路径存在性后完成挂载。
4. 已完成挂载的卷复用
若卷已通过 VolumeAttachment
成功挂载到节点(Node.status.volumesAttached
中存在记录),且未被卸载:
- 原理:新调度到该节点的 Pod 复用已有挂载点,AD 控制器检测到卷已在节点挂载,跳过重复的 Attach 流程。
- 场景:同一节点上多个 Pod 使用同一 RWX(ReadWriteMany)卷,或同一 RWO 卷被同一节点的 Pod 重新调度。
5. in-tree 存储插件管理的卷
Kubernetes 内置的 in-tree 存储插件(如 kubernetes.io/aws-ebs
非 CSI 版本)由内部组件直接处理挂载,无需 External Attacher 参与:
- 原理:挂载逻辑集成于 Kubernetes 核心代码,通过内部接口调用云厂商 API,不依赖
VolumeAttachment
资源或外部边车容器。 - 现状:in-tree 插件正逐步被 CSI 插件替代,但存量集群中仍可能存在此类场景。
总结
“Attach 流程”的核心是块存储设备与节点的绑定,依赖 VolumeAttachment
资源和 CSI 插件的协同。而文件存储、对象存储、本地存储等场景因协议设计或实现方式不同,无需通过该流程即可完成存储访问,这体现了 Kubernetes 存储体系对多样化存储类型的适配能力。
四、组件代码位置与集群部署信息表
组件名称 | 代码位置 | 部署命名空间 | 部署形式 | 部署说明 |
---|---|---|---|---|
AD 控制器(AttachDetachController) | kubernetes/kubernetes/pkg/kubelet/volumemanager/attachdetach/ | 无独立命名空间(集成于 Kubelet) | 内置于 Kubelet 进程 | 作为 Kubelet 的核心模块运行在所有节点(控制节点和工作节点),随 Kubelet 启动;负责节点级存储卷的挂载管理和状态同步。 |
API Server | kubernetes/kubernetes/pkg/apiserver/ kubernetes/cmd/kube-apiserver/ | kube-system | 独立静态 Pod(kube-apiserver ) | 控制平面核心组件,以静态 Pod 形式部署在控制节点;接收所有资源的 CRUD 请求,存储 VolumeAttachment 等资源到 etcd。 |
External Attacher | github.com/kubernetes-csi/external-attacher | 与 CSI 驱动同命名空间(如 csi-system ) | 边车容器(Sidecar) | 与 CSI 驱动部署在同一 Pod 中,通过 Unix Domain Socket 与 CSI 驱动通信;需配置 RBAC 权限以监听 VolumeAttachment 资源和更新状态。 |
CSI 驱动(CSIDriver) | 各存储厂商实现(如 aws-ebs-csi-driver) | 自定义命名空间(如 csi-system ) | Deployment 或 DaemonSet | 控制器组件以 Deployment 部署(处理挂载调度),节点组件以 DaemonSet 部署(处理本地设备映射);需挂载主机路径(如 /dev 、/var/lib/kubelet )与存储设备交互。 |
云厂商存储服务(CloudProvider) | 云厂商自研实现(如 AWS EBS SDK、阿里云 EBS SDK) | 无(集群外部服务) | 云厂商托管服务 | 独立于 Kubernetes 集群的外部服务,通过 API 接口接收 CSI 驱动的挂载请求,负责底层存储设备的节点级挂载操作。 |
Node 组件 | kubernetes/kubernetes/pkg/kubelet/ | 无独立命名空间(节点级进程) | 内置于 Kubelet 节点状态 | 节点状态(Node.status.volumesAttached )由 Kubelet 维护,通过 API Server 同步集群状态;存储卷挂载点在节点本地路径(如 /var/lib/kubelet/pods/<pod-id>/volumes/ )。 |
CSI 存储卷节点挂载(Node Mount)时序流程详解
一、流程图
sequenceDiagramtitle CSI 存储卷节点挂载时序流程participant VolumeManager as Volume Manager<br/>(Kubelet 组件)participant InTreeCSIAttacher as in-tree CSI 插件<br/>(csiAttacher)participant InTreeCSIMountMgr as in-tree CSI 插件<br/>(csiMountMgr)participant api-serverparticipant ExternalCSIPlugin as 外部 CSI 插件participant Host as 主机节点participant Container as 容器%% 前置条件:Node 已处于 Ready 状态Note over Host: Node 已达到 Ready 状态<br/>存储卷在主机内可见%% 1. Volume Manager 触发节点级存储准备流程VolumeManager->>InTreeCSIAttacher: 1. 调用 WaitForAttach 函数<br/>(等待卷 Attach 完成)InTreeCSIAttacher->>api-server: 2. 监听 VolumeAttachment 对象状态api-server-->>InTreeCSIAttacher: 3. 返回 VolumeAttachment.status.attached=true%% 2. 执行 NodeStageVolume (分区格式化)InTreeCSIAttacher->>InTreeCSIAttacher: 4. 确认卷已 Attach 成功InTreeCSIAttacher->>ExternalCSIPlugin: 5. 通过 Unix Socket 调用<br/>NodeStageVolume 接口<br/>(分区格式化操作)ExternalCSIPlugin->>Host: 6. 执行存储卷分区、格式化Host-->>ExternalCSIPlugin: 7. 分区格式化完成ExternalCSIPlugin-->>InTreeCSIAttacher: 8. 返回 Stage 成功<br/>(Volume Ready 状态)Note over ExternalCSIPlugin: Volume Ready 状态<br/>(完成分区格式化)%% 3. 执行 NodePublishVolume (挂载至容器目录)InTreeCSIAttacher->>InTreeCSIMountMgr: 9. 调用 SetUp 函数<br/>(触发容器挂载流程)InTreeCSIMountMgr->>ExternalCSIPlugin: 10. 通过 Unix Socket 调用<br/>NodePublishVolume 接口<br/>(挂载至容器目录)ExternalCSIPlugin->>Host: 11. 将存储卷挂载至容器指定目录Host-->>ExternalCSIPlugin: 12. 挂载操作完成ExternalCSIPlugin-->>InTreeCSIMountMgr: 13. 返回 Publish 成功<br/>(Published 状态)Note over ExternalCSIPlugin: Published 状态<br/>(已挂载至容器目录)%% 4. 容器访问存储卷InTreeCSIMountMgr-->>VolumeManager: 14. 通知存储卷准备完成VolumeManager->>Container: 15. 容器启动并访问挂载目录Note over Container: 存储卷可用 (容器内可见)
二、详细流程步骤
-
等待卷 Attach 完成
Kubelet 内置的 Volume Manager 负责节点级存储卷的生命周期管理,当检测到使用 CSI 卷的 Pod 调度到本节点后,首先调用内部 in-tree CSI 插件(csiAttacher
)的WaitForAttach
函数,确保卷已通过 Attach 流程绑定到节点。 -
监听 VolumeAttachment 状态
csiAttacher
通过 API Server 持续监听VolumeAttachment
资源的状态变化,等待其status.attached
变为true
,确认卷已成功挂载到节点(如块设备已通过云 API 关联到主机)。 -
执行 NodeStageVolume(分区格式化)
卷 Attach 完成后,csiAttacher
调用外部 CSI 插件的NodeStageVolume
接口:- 外部 CSI 插件对节点级存储卷执行分区(如 GPT 分区)和格式化(如
mkfs.ext4
)操作,将原始块设备转换为可挂载的文件系统。 - 完成后,卷进入 Volume Ready 状态,表示已具备挂载到容器的基础条件。
- 外部 CSI 插件对节点级存储卷执行分区(如 GPT 分区)和格式化(如
-
触发容器挂载流程
csiAttacher
调用内部 in-tree CSI 插件(csiMountMgr
)的SetUp
函数,将存储卷从“节点级可用”推进到“容器级可用”,准备将卷挂载到 Pod 的指定目录。 -
执行 NodePublishVolume(容器目录挂载)
csiMountMgr
通过 Unix Domain Socket 调用外部 CSI 插件的NodePublishVolume
接口:- 外部 CSI 插件将已格式化的卷(或网络共享目录)挂载到容器的指定路径(如
/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~csi/<pv-name>/mount
)。 - 挂载过程可能涉及绑定挂载(
bind mount
)、权限设置(如chmod
)或挂载选项配置(如ro
只读)。 - 完成后,卷进入 Published 状态,表示已成功挂载到容器的目标目录。
- 外部 CSI 插件将已格式化的卷(或网络共享目录)挂载到容器的指定路径(如
-
通知存储卷准备完成
csiMountMgr
向 Volume Manager 反馈挂载成功,Volume Manager 确认存储卷就绪后,允许容器启动并访问挂载目录。 -
容器访问存储卷
容器启动后,通过 Pod 定义中指定的volumeMounts
路径访问存储卷,此时卷已完全集成到容器的文件系统中,用户数据可通过容器读写存储卷。
三、不执行该流程的场景
以下情况不会触发上述节点挂载流程,存储卷通过其他方式完成容器访问:
-
网络文件系统(NFS/SMB)
NFS、SMB 等基于文件共享的存储卷无需分区格式化:- 原理:远程共享目录已提前格式化,节点直接通过网络协议(如 NFS v4、CIFS)挂载目录,无需
NodeStageVolume
操作。 - 差异:
NodePublishVolume
仅执行网络目录到容器路径的绑定挂载,跳过块设备相关的分区格式化步骤。
- 原理:远程共享目录已提前格式化,节点直接通过网络协议(如 NFS v4、CIFS)挂载目录,无需
-
对象存储映射(S3/OSS)
S3、OSS 等对象存储通过工具(如s3fs
)映射为本地目录时:- 原理:通过 FUSE(用户态文件系统)将对象接口转换为目录结构,无需块设备或传统文件系统格式化。
- 差异:
NodeStageVolume
可能被跳过,NodePublishVolume
直接挂载 FUSE 映射的目录。
-
临时存储卷(emptyDir/ephemeral)
节点本地临时卷(如emptyDir
)依赖主机临时目录:- 原理:直接使用节点本地路径(如
/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir/
),无需 CSI 插件参与。 - 差异:整个流程由 Kubelet 内部处理,不涉及
NodeStageVolume
或NodePublishVolume
调用。
- 原理:直接使用节点本地路径(如
-
只读卷复用已有挂载点
若卷已通过NodePublishVolume
挂载到节点且为只读模式(ro
):- 原理:新 Pod 复用同一挂载点,通过绑定挂载将只读卷映射到不同容器目录,无需重复执行格式化和挂载流程。
- 场景:多个 Pod 共享同一 RWX 只读卷,或同一 RWO 卷被同一节点的 Pod 重新使用。
四、组件代码位置与集群部署信息表
组件名称 | 代码位置 | 部署命名空间 | 部署形式 | 部署说明 |
---|---|---|---|---|
Volume Manager | kubernetes/kubernetes/pkg/kubelet/volumemanager/ | 无独立命名空间(集成于 Kubelet) | 内置于 Kubelet 进程 | 作为 Kubelet 的核心模块运行在所有节点,负责协调卷的 Attach、挂载和卸载流程,通过控制循环监听 Pod 和卷状态变化。 |
in-tree CSI 插件(csiAttacher/csiMountMgr) | kubernetes/kubernetes/pkg/volume/csi/ | 无独立命名空间(集成于 Kubelet) | 内置于 Kubelet 代码 | Kubelet 内置的 CSI 适配层,负责桥接 Kubelet 与外部 CSI 插件,实现 WaitForAttach 、SetUp 等接口的逻辑转发。 |
外部 CSI 插件(External CSI Plugin) | 各存储厂商实现(如 csi-driver-nfs) | 自定义命名空间(如 csi-system ) | DaemonSet(节点插件) | 以 DaemonSet 形式部署在所有节点,通过 Unix Domain Socket(如 /var/lib/kubelet/plugins/<driver-name>/csi.sock )提供 NodeStageVolume 和 NodePublishVolume 接口,直接操作节点存储设备。 |
API Server | kubernetes/kubernetes/pkg/apiserver/ kubernetes/cmd/kube-apiserver/ | kube-system | 独立静态 Pod | 控制平面核心组件,存储 VolumeAttachment 资源并提供状态查询接口,支持 Kubelet 和 CSI 插件的监听操作。 |
Host 节点 | 操作系统内核/工具(如 mount 、mkfs ) | 无(节点本地) | 节点操作系统组件 | 提供存储卷的物理挂载点(如 /dev 设备、/var/lib/kubelet 目录),执行分区、格式化和挂载命令,是存储卷实际运行的硬件载体。 |
Container 容器 | 应用镜像/容器运行时(如 containerd) | 应用所属命名空间 | Pod 中的容器实例 | 通过容器运行时的挂载命名空间隔离,访问绑定挂载的存储卷目录,感知不到底层 CSI 插件的操作细节。 |