Appearance
Container Storage Interface (CSI)
How does Kubernetes talk to my specific storage vendor?
Historically, Kubernetes integrated storage solutions by building them directly into the core codebase. These "in-tree" volume plugins meant that adding support for a new storage vendor (or fixing a bug in an existing one) required checking code directly into the Kubernetes repository and waiting for the next official Kubernetes release cycle.
To solve this scaling bottleneck, Kubernetes adopted the Container Storage Interface (CSI). CSI defines a standard, out-of-tree interface for container orchestrators to expose arbitrary storage systems to their workloads. This extensibility model allows storage vendors—such as AWS (ebs.csi.aws.com), Azure (disk.csi.azure.com), and Portworx (pxd.portworx.com)—to develop, release, and install their plugins entirely independently of the core Kubernetes binaries.
Here is how the Kubernetes control plane communicates with these independent storage vendors without knowing any of their underlying APIs.
The CSI Architecture and gRPC
Kubernetes does not communicate with the storage vendor's proprietary API directly. Instead, the storage vendor provides a CSI driver, which is typically deployed into the Kubernetes cluster as a combination of Deployment (or StatefulSet) for control-plane tasks and a DaemonSet for node-level tasks.
The CSI driver exposes a standardized set of gRPC endpoints. The Kubernetes system interacts with the driver by making gRPC calls to these endpoints (such as ControllerPublishVolume or NodePublishVolume).
The Sidecar Pattern: Bridging the Kubernetes API and CSI
To keep the core Kubernetes control plane lightweight and unaware of CSI-specifics, the communication between the Kubernetes API server and the vendor's CSI driver is brokered by a set of standardized, community-managed sidecar containers.
These sidecars run in the same Pod as the vendor's CSI driver. They actively watch the Kubernetes API for specific object changes and translate those declarative API objects into imperative gRPC commands sent to the vendor's driver over a local UNIX domain socket.
1. The external-provisioner Sidecar
When a user creates a PersistentVolumeClaim (PVC) requesting dynamically provisioned storage, the Kubernetes API simply stores the object. The external-provisioner sidecar watches the API for new PVCs.
- How it works: When it sees a PVC that references a
StorageClassbelonging to its associated CSI driver, theexternal-provisionerintercepts the request. It extracts the parameters from theStorageClassand makes a gRPCCreateVolumecall to the vendor's CSI driver. - Once the vendor driver successfully creates the physical storage (e.g., provisions an EBS volume in AWS), the
external-provisionercreates the correspondingPersistentVolume(PV) object in the Kubernetes API to bind with the PVC.
2. The external-attacher Sidecar
Creating a volume is different from attaching it to a specific virtual machine or physical node. When the Kubernetes scheduler places a Pod onto a Node, the core Kubernetes attach/detach controller recognizes that a volume must be attached to that specific Node. However, it does not talk to the storage vendor directly. Instead, it creates a VolumeAttachment object in the Kubernetes API.
- How it works: The
external-attachersidecar continuously watches for newVolumeAttachmentobjects. - When it detects one, it makes a gRPC
ControllerPublishVolumecall to the vendor's CSI driver, instructing it to attach the physical volume to the underlying infrastructure node. - Once the vendor's driver confirms the operation is complete, the
external-attacherupdates theVolumeAttachmentstatus in Kubernetes toattached: true. Only then does the kubelet proceed to mount the volume into the Pod.
Other Critical CSI Sidecars
The CSI extensibility model utilizes several other specialized sidecars following this exact same pattern:
external-resizer: Watches for modifications to PVC capacity orVolumeAttributesClassobjects and makes gRPC calls to expand or modify the physical volume dynamically.csi-snapshotter: Watches forVolumeSnapshotandVolumeSnapshotContentobjects created by users and triggersCreateSnapshotorDeleteSnapshotgRPC operations against the vendor's CSI endpoint.node-driver-registrar: Runs on every worker node alongside the node-level CSI driver, automatically populating theCSINodeobject in the Kubernetes API to inform the kubelet that the CSI driver is successfully installed and available on that specific host.