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
- A UDS which allows kubelet to make csi calls and mount and unmount volumes
- Kubelet discovers CSI drivers via kubelet plugin registration mechanism
- 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