What is the Container Storage Interface (CSI) in Kubernetes, and why were storage drivers moved out of the Kubernetes core codebase onto it?
answer
- gRPC contract, not a component
- out-of-tree = driver ships as pods
- controller Deployment + node DaemonSet
- StorageClass provisioner = driver name
- in-tree plugins removed, CSI migration
basics
~20 sCSI is a standard gRPC contract for storage drivers. A vendor ships the driver as ordinary pods in the cluster instead of code compiled into Kubernetes, so drivers install, upgrade and get fixed independently of the Kubernetes release.
solid answer
~40 sCSI is a vendor-neutral specification defining the gRPC calls a storage system must implement: create/delete a volume, attach/detach it to a node, stage/publish it into a container, snapshot it, expand it. Before CSI, drivers were **in-tree**: compiled into `kube-controller-manager` and `kubelet`. A storage bug needed a Kubernetes patch release, vendors had to get code merged by Kubernetes maintainers, and vendor SDKs bloated the core binaries. A CSI driver is deployed like any other workload: a **controller** component (usually a Deployment that talks to the storage system's API) and a **node** component (a DaemonSet that does the mounting on each machine), plus a `CSIDriver` object advertising its capabilities. The user-facing API does not change: you still write PersistentVolumeClaims, PersistentVolumes and StorageClasses. The driver name simply appears as the StorageClass `provisioner`, for example `ebs.csi.aws.com`.
code
bash · 3 lineskubectl get csidrivers
kubectl get csinodes -o wide
kubectl -n kube-system get pods -l app.kubernetes.io/name=aws-ebs-csi-drivergo deeper
Be able to say CSI is the standard interface storage vendors implement, that drivers run as pods, and that you still consume storage through PVCs and StorageClasses.
Add the shape of a driver install - controller Deployment, node DaemonSet, CSIDriver object, sidecars - and name a few CSI calls.
Frame it as lifecycle decoupling: driver upgrades, RBAC and credentials, capability advertisement, and the operational rule that the driver must be installed before the in-tree plugin is removed.
Discuss it as a platform extension-point decision: reduced core surface area versus a new operational dependency your platform team now owns, including upgrade sequencing and multi-cloud driver variance.
## The problem CSI solves A pod that needs durable storage requires something to call the storage system's API - EBS, Ceph, a NetApp filer, a vSphere datastore - to carve out a disk, attach it to the right machine, format it and mount it into the container. Originally that code lived **in-tree**: in the Kubernetes source repository, compiled into the core binaries. That had real costs. Vendors could only ship a driver fix on the Kubernetes release train. Kubernetes maintainers had to review storage code for hardware they could not test. Every cloud SDK a driver needed became a dependency of the core binaries, widening the attack surface of components that run as root on every node. ## What CSI actually is CSI is a specification, not a Kubernetes component. It defines gRPC services a storage plugin implements: - **Identity** - who am I, what capabilities do I have, am I healthy. - **Controller** - cluster-wide operations against the storage API: `CreateVolume`, `DeleteVolume`, `ControllerPublishVolume` (attach to a node), `ControllerUnpublishVolume`, `CreateSnapshot`, `ControllerExpandVolume`. - **Node** - machine-local operations: `NodeStageVolume` (format and mount once per node to a staging path), `NodePublishVolume` (bind-mount into the pod's directory), and the unpublish/unstage counterparts. Because the contract is orchestrator-agnostic, one driver binary can serve Kubernetes, Nomad and others. ## How a driver shows up in a cluster A CSI driver installation typically creates: - a **controller Deployment** (often 1-2 replicas with leader election) containing the vendor's controller plugin plus Kubernetes-maintained sidecar containers that translate Kubernetes objects into CSI calls; - a **node DaemonSet** on every node containing the node plugin plus the `node-driver-registrar` sidecar that tells kubelet where the driver's UNIX socket is; - a `CSIDriver` object (cluster-scoped) declaring capabilities such as whether the driver needs an attach step, whether it supports fsGroup, and pod-info-on-mount; - one or more `StorageClass` objects whose `provisioner` field is the driver name; - RBAC and, in many drivers, a Secret holding cloud credentials. You can see the installed drivers with `kubectl get csidrivers`, and per-node driver state with `kubectl get csinodes` (which also records how many volumes a node can attach). ## What did not change The application-facing API is untouched. A workload still asks for storage with a PersistentVolumeClaim; a PersistentVolume object still represents the real disk; a StorageClass still selects the backend and parameters. CSI changes *who executes* the request, not *how you request it*. That is why moving a cluster from an in-tree plugin to the equivalent CSI driver can be transparent to manifests. ## Migration off in-tree drivers Kubernetes has removed the in-tree cloud volume plugins. A translation layer (CSI migration) rewrote in-tree volume specs such as `kubernetes.io/aws-ebs` into their CSI equivalent (`ebs.csi.aws.com`) so existing PersistentVolumes kept working, while the CSI driver did the real work. That translation went stable for the major clouds and the in-tree code was then deleted over subsequent releases. The practical rule for operators: the matching CSI driver must be installed *before* upgrading past the release that removes the in-tree plugin, or volumes stop attaching. ## Why interviewers ask this It separates candidates who know only `kubectl apply -f pvc.yaml` from those who know that storage in Kubernetes is an extension point with its own control loops, its own failure modes, and its own upgrade lifecycle.
- If CSI drivers are out of tree, what still lives in Kubernetes core for storage?The API objects and the generic control loops: the PV/PVC binding controller, the attach/detach controller that creates VolumeAttachment objects, and kubelet's volume manager that decides when to stage and publish. Core also owns the CSI client code that speaks to the driver socket. The vendor-specific part - talking to EBS or Ceph - is what moved out.
- What breaks if you upgrade a cluster past the release that removed an in-tree plugin without installing the CSI driver?Existing PersistentVolumes still have in-tree specs, but nothing can act on them: new pods fail to attach or mount with driver-not-found errors, and detach on node drain hangs. Running pods that already have the volume mounted usually keep working until they are rescheduled. The fix is to install the CSI driver, which then adopts the migrated volumes.
In-tree drivers were like device drivers compiled into the kernel: to fix one you rebuilt the kernel. CSI is the loadable-module model - the same kernel, drivers plugged in and swapped at will.
saying these in an interview costs you the question
- Saying CSI is a Kubernetes component or controller rather than a specification that drivers implement
- Claiming CSI changed how applications request storage (PVC/PV/StorageClass are unchanged)
- Thinking a CSI driver is a single pod rather than a controller component plus a per-node DaemonSet
- Assuming in-tree plugins still exist as a fallback if no CSI driver is installed