运行原理

csi 主要为集群上的 容器 提供卷挂载的支持,以插件管理的方式支持扩展多种存储挂载。下面以juicefs为例分析csi.

1. juicefs-csi-node 运行在每个节点上,完成卷在节点上的具体挂载以及如何使容器可以读写挂载在节点上的卷。

2. juicefs-csi-node 启动时将向kubelet注册rpc, 当kubelet发现有pod调度到本节点且其中有容器挂载卷为juicefs时将通知juicsfs-csi-node 有该容器需要挂载卷。

3. juice-csi-node 收到通知后将创建 juicefs mount pod(juicsfs mount pod模式),  并创在节点上创建挂载目录  /var/lib/kubelet/pods/{podID}/volumes/kubernetes.io~csi/juicefs-xxxx/mount

4. juicefs mount pod 通过fuse管理节点上的挂载目录, 当该目录有读写操作时将通过fuse 调用 内部的juicsfs 服务提供vfs文件系统,vfs文件系统将数据最终写入到外部的data server 和 metadata server 中。 

5. 业务容器 也会将该目录 /var/lib/kubelet/pods/{podID}/volumes/kubernetes.io~csi/juicefs-xxxx/mount 目录挂载到容器中,如 /pvc/mountpath

6. 当业务容器向挂载目录写入数据时,juicefs mount pod 中fuse会将请求传给juicefs 提供的vfs 服务,最终将数据更新到 external storage provider.

7.  juicefs-controller 则主要负责在创建或删除卷,以及卷绑定与解绑节点关联时,将信息更新到 backend storage 的元数据中, 不负责节点上的具体挂载操作。

配置解析

容器的挂载配置

选用样例容器,查看挂载配置

pod 配置

  - apiVersion: v1
  kind: Pod
    ...    
    - mountPath: /root/model
      mountPropagation: HostToContainer
      name: model-netdisk
      subPath: model/123
    ...
    volumes:
    - name: model-netdisk
    persistentVolumeClaim:
      claimName: model-netdisk
        

对应pv 配置

apiVersion: v1
kind: PersistentVolume  
...
    csi:
    driver: csi.juicefs.com
    fsType: juicefs
    nodePublishSecretRef:
      name: juicefs-secret
      namespace: default
    volumeAttributes:
      juicefs/mount-delete-delay: 129600m
      juicefs/mount-image: /mount:ce-v1.2.0
    volumeHandle: model-netdisk
  persistentVolumeReclaimPolicy: Retain
  volumeMode: Filesystem

容器的config.json

容器的最终执行为runc,查看runc使用的config.json 配置.

可见容器内的/root/model 目录来自节点的目录

/var/lib/kubelet/pods/afd20c4b-95a0-4f7f-b0a3-cc67537c495f/volumes/kubernetes.io~csi/model-netdisk/mount

    {
      "destination": "/root/model",
      "type": "bind",
      "source": "/var/lib/kubelet/pods/afd20c4b-95a0-4f7f-b0a3-cc67537c495f/volumes/kubernetes.io~csi/model-netdisk/mount",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },

mount pod 的vfs支持

根据节点上存储挂载的目录,找到对应的mount pod 查看配置

通过注解可知该pod管理节点挂载目录

/var/lib/kubelet/pods/afd20c4b-95a0-4f7f-b0a3-cc67537c495f/volumes/kubernetes.io~csi/model-netdisk/mount 

- apiVersion: v1
  kind: Pod
  metadata:
    annotations:
   ...
      juicefs-2858a2fc3d6197a0262a146553b76e84b1fde34e248793c798a2bbb: /var/lib/kubelet/pods/afd20c4b-95a0-4f7f-b0a3-cc67537c495f/volumes/kubernetes.io~csi/model-netdisk/mount
      
    
    ...
  spec:
    containers:
    - command:
      - sh
      - -c
      - |-
        /usr/local/bin/juicefs format --storage=s3 --bucket=http://xxx --access-key=xxx --secret-key=${secretkey} ${metaurl} jfs-  userfile
        exec /bin/mount.juicefs ${metaurl} /jfs/xxxx -o metrics=0.0.0.0:9567
      ...
      volumeMounts:
      - mountPath: /jfs
        mountPropagation: Bidirectional
        name: jfs-dir
       ...
    volumes:
    - hostPath:
        path: /var/lib/juicefs/volume
        type: DirectoryOrCreate

该pod完成了节点上的挂载目录与juicefs的关联,向挂载目录读写时将通过fuse调用mount pod中提供的vfs

JuiceFS:jfs-userfile on /var/lib/kubelet/pods/cf732a4b-04c9-4f46-a7cd-55282bdd422b/volumes/kubernetes.io~csi/juicefs-netdisk-user/mount type fuse.juicefs

确认节点挂载目录与容器挂载目录关联

分别查询节点上的目录

/var/lib/kubelet/pods/afd20c4b-95a0-4f7f-b0a3-cc67537c495f/volumes/kubernetes.io~csi/model-netdisk/mount 

  Size: 4096            Blocks: 8          IO Block: 65536  directory
Device: 100009ah/16777370d      Inode: 1           Links: 13
Access: (0777/drwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-09-22 08:18:43.000000000 +0000
Modify: 2026-02-28 02:21:40.708461443 +0000
Change: 2026-02-28 02:21:40.708461443 +0000

以及业务容器进程 /proc 文件系统下对应目录

/proc/25730/root/root/xxx/

Device: 100009ah/16777370d      Inode: 1           Links: 13
Access: (0777/drwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-09-22 08:18:43.000000000 +0000
Modify: 2026-02-28 02:21:40.708461443 +0000
Change: 2026-02-28 02:21:40.708461443 +0000

inode号一致,由juicefs mount pod 管理的目录被挂载进了业务容器

更多推荐