Csi driver

What is?

The Container Storage Interface (CSI) is a standard for exposing arbitrary block and file storage systems to containerized workloads on Container Orchestration Systems (COs) like Kubernetes.

Why we need the csi-driver?

The csi driver will allow us to inject the developed fuse filesystem as an ephimeral volume to the pods that make a request through the pod definition as follows.

kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app
spec:
  containers:
    - name: my-frontend
      image: busybox:1.28
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-inline-vol
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-csi-inline-vol
      csi:
        driver: inline.storage.kubernetes.io
        volumeAttributes:
          foo: bar

This will allow containers application to have read only access to the different data retrieved by the fuse filesystem at run time

Problems

Which languague to implement this Csi driver specification?

Due to the big support and that kubernetes was done using golang, we found this as a suitable language for doing this implementation, supported by github.com/container-storage-interface/spec/lib/go/csi library

How we do csi driver recognizable?

  • kubelet to CSI driver communication
  • Master to CSI driver communication
    • not UDS communication allowed instead, this one MUST watch the kubernetes api and trigger appropiate actions.

How to mount fuse using the csi driver?

For mounting the fuse filesystem, we decide to mount it when a pod requires it, for avoiding fuse processes running without purposes, this will be done implementing the node service function NodePublishVolume()

What services do we need to implement?

As we want to mount the fuse filesystem as an ephemeral volume, we need to implement two fundamental services set by the csi specification with their following grpc methods.

  • Node service
    • nodePublishVolume()
    • nodeUnpublishVolume()
    • nodeGetCapabilities()
  • Identity service
    • GetPluginInfo()
    • GetPluginCapabilities()
    • Probe()

Optional service ?

If we would like to extend the funtionalitie of our csi_driver by been able to attach persistent volumes instead of ephemeral volume, then implementing the controller service has to be implemented

What sidecars containers we are going to use

For this csi driver implementation will be important to use the node-driver-registrar, because as said before we need kubelet to have registered the csi-driver and this k8-sidecontainer fetches driver information and registers it with the kubelet on that node using kubelet registration plugin

What architecure suits better for implement the csi driver?

As we want and easy to extend and compact schema, and regarding we will use ephemeral volume for injecting the fuse filesystem, this is the architecture selected.

                            CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    |    Node    |  |
|  |            +----------->   Plugin   |  |
|  +------------+           +------------+  |
|                                           |
+-------------------------------------------+

Figure 4: Headless Plugin deployment, only the CO Node hosts run
Plugins. A Node-only Plugin component supplies only the Node Service.
Its GetPluginCapabilities RPC does not report the CONTROLLER_SERVICE
capability. 
(got from https://github.com/container-storage-interface/spec/blob/master/spec.md)

Kubernetes Csi driver documentation

For finding more information concerning to:

  • Concepts
  • Development
  • Deployment

Redirect to the kubernetes csi documentation kubernetes_csi

Csi specifications

For finding the rules of how a csi driver should be implemented. Redirect to the csi specification csi_specification