# external-snapshotter: the sidecar that turns CSI snapshots into Kubernetes objects

> The Kubernetes CSI external-snapshotter is a sidecar container that watches VolumeSnapshotContent objects and calls CreateSnapshot and DeleteSnapshot on a CSI driver over a Unix socket. It is one piece of a four-part system whose other parts are shared across drivers, and the split between what the sidecar watches and what the controller watches is the design decision that matters.

**kubernetes-csi/external-snapshotter** — Sidecar container that watches Kubernetes Snapshot CRD objects and triggers CreateSnapshot/DeleteSnapshot against a CSI endpoint.

- Repository: https://github.com/kubernetes-csi/external-snapshotter
- Stars: 646 · Forks: 442
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/kubernetes-csi-external-snapshotter

## The sidecar watches only VolumeSnapshotContent, not VolumeSnapshot

The repository description is precise about the sidecar's job: it watches Kubernetes Snapshot CRD objects and triggers CreateSnapshot and DeleteSnapshot against a CSI endpoint. The design section then draws a line that is easy to miss on a first read.

Both the snapshot controller and the CSI external-snapshotter sidecar follow the controller pattern and use informers to watch for events. But they watch different objects. The snapshot controller watches for VolumeSnapshot and VolumeSnapshotContent create, update and delete events. The CSI external-snapshotter sidecar only watches for VolumeSnapshotContent events. When the volume group snapshot feature is enabled, the pattern repeats with VolumeGroupSnapshot and VolumeGroupSnapshotContent, and the sidecar again watches only the content object.

The reason is the filtering rule. The sidecar filters out content objects whose associated VolumeSnapshotClass does not specify `Driver==<CSI driver name>`. Each sidecar instance serves one driver, and the content objects belonging to other drivers are simply not its business.

So the split of responsibility is: the shared controller owns the user-facing intent object, the sidecar owns the driver-specific execution object. That is why the same controller deployment serves every CSI driver in a cluster while the sidecar has to run once per driver.

Events are processed in workqueues with exponential backoff, which is the standard Kubernetes pattern for absorbing a driver that is slow or temporarily unavailable.

## The sidecar talks to the driver over a Unix socket, not over the API

The communication path between the sidecar and the CSI driver is short and worth stating exactly, because it determines how you debug a snapshot that does not appear.

The README says the CSI external-snapshotter sidecar talks to CSI over socket, at `/run/csi/socket` by default, and that this is configurable by `-csi-address`. There is no HTTP client, no REST call, and no Kubernetes API involvement in the snapshot operation itself. The sidecar is a gRPC client, given that the module depends on `google.golang.org/grpc`, and the address is a local Unix domain socket inside the pod.

The practical consequence is that the CSI driver and the sidecar must be in the same pod, sharing the volume where that socket lives. If a driver is deployed differently, the sidecar has no way to reach it, and the symptom is a sidecar that never completes an operation. Changing the path with `-csi-address` is the documented way to point at a socket in a non-default location.

The dependencies in the module file line up with the rest of the design. `github.com/container-storage-interface/spec v1.13.0` is the CSI API definition, `github.com/kubernetes-csi/csi-lib-utils v0.25.0` provides the shared logging and connection helpers, `k8s.io/client-go v0.37.0` is the client for the API objects the sidecar watches, and `github.com/prometheus/client_golang v1.24.1` provides the metrics. The module path and language version are:

```go
module github.com/kubernetes-csi/external-snapshotter/v8

go 1.26.0
```

and the CSI spec version it is built against is pinned in the same file:

```go
require (
	github.com/container-storage-interface/spec v1.13.0
```

which is above the v1.10.0 needed for the volume group snapshot calls.

## One sidecar per driver, one controller for the whole cluster

The Usage section lists the components of the volume snapshot feature, and the deployment model is spelled out with unusual clarity.

The components are the Kubernetes Volume Snapshot and Volume Group Snapshot CRDs, the volume snapshot and volume group snapshot controller, the volume group snapshot conversion webhook, and the CSI Driver along with the CSI Snapshotter sidecar. The CRDs live under `client/config/crd`, the controller under `pkg/common-controller`, the webhook under `pkg/webhook` and the sidecar under `pkg/sidecar-controller`.

Then the deployment rules. The volume snapshot feature depends on a volume snapshot controller and the volume snapshot CRDs, and both of those are independent of any CSI driver. The CSI Snapshotter sidecar must run once per CSI driver. A single snapshot controller deployment works for all CSI drivers in a cluster.

Leader election is supported, and the README describes the mechanics: the CSI sidecars and the snapshot controller elect one leader per deployment, and if deployed with two or more pods and leader election is enabled, the non-leader containers will attempt to get the lease, so if the leader container dies a non-leader will take over.

Because the controller and the CRDs are driver-independent, the README strongly recommends that Kubernetes distributors bundle and deploy the controller and the CRDs as part of the cluster management process, independent of any CSI driver. If your distribution does not bundle them, you install them manually. The README's manual install steps are truncated in the copy available here, so the exact commands are in the full document rather than in what can be quoted here.

The practical takeaway for anyone assembling a cluster by hand is that the controller and CRDs are a one-time, cluster-wide install, and the sidecar is a per-driver, per-namespace addition to the driver's own deployment.

## The compatibility table is per component, and the CRDs are the hard requirement

The compatibility table in the README gives a minimum and a recommended CSI version, a container image and Kubernetes versions, and it does this separately for each of the three images. All three rows list CSI Spec v1.0.0 as the minimum and CSI Spec v1.5.0 as the recommended version, with a minimum and recommended Kubernetes version of 1.20.

The three images are `k8s.gcr.io/sig-storage/csi-snapshotter`, `k8s.gcr.io/sig-storage/snapshot-controller` and `k8s.gcr.io/sig-storage/snapshot-conversion-webhook`. The table notes that it reflects the head of the branch.

Two notes below the table carry the migration weight. The first says that snapshot-controller, snapshot-conversion-webhook and csi-snapshotter v4.1 require the v1 snapshot CRDs to be installed, but that they serve both v1 and v1beta1 snapshot objects, and that the storage version is changed from v1beta1 to v1 in 4.1.0, so v1beta1 is deprecated and will be removed in a future release.

The second note says that when the volume group snapshot feature is enabled, the snapshot-controller, snapshot-conversion-webhook and csi-snapshotter require the v1beta2 volumegroupsnapshot CRDs to be installed.

So CRD installation is a precondition, and a versioned one. The APIs section repeats the first point in more detail: in the current release both v1 and v1beta1 APIs are served while the stored version is v1, v1beta1 is deprecated, users are recommended to switch to v1 as soon as possible, and any previously created invalid v1beta1 objects have to be deleted before upgrading to version 4.1. That last clause is the kind of thing that turns an upgrade into an incident.

## Volume snapshot is on by default, group snapshot is off

The feature status is asymmetric, and that asymmetry decides your rollout.

With the promotion of Volume Snapshot to GA, the feature is enabled by default on standard Kubernetes deployments and cannot be turned off. The feature gate history is spelled out: the `VolumeSnapshotDataSource` feature gate was introduced in Kubernetes 1.12, became enabled by default in 1.17 when the feature was promoted to beta, and in 1.20 it is enabled by default on standard deployments and cannot be turned off. The volume snapshot feature itself was introduced as Alpha in Kubernetes v1.12, promoted to Beta in 1.17, and moved to GA in 1.20.

The Volume Group Snapshot feature is the opposite. It is disabled by default and can be enabled using a command line option, with the README pointing at its usage section for the details. It supports CSI v1.10.0 and higher, and was introduced in Kubernetes 1.27 as an alpha feature.

For the sidecar specifically, the compatibility row lists CSI Spec v1.0.0 as the minimum supported version, and the group snapshot path needs v1.10.0, so a driver on an older CSI version can run volume snapshots but not group snapshots. Enabling the group feature is also what triggers the requirement for the v1beta2 volumegroupsnapshot CRDs.

One practical consequence of the asymmetric defaults is that the group snapshot path has a longer checklist than the plain one. Enabling it is a command line option on the components, it needs a CSI driver at v1.10.0 or above, and it needs the v1beta2 volumegroupsnapshot CRDs present before the components will behave as expected. A cluster that has been running volume snapshots happily for months can still have all three of those missing.

## Compared with vendor backup agents and with a controller-only approach

The alternatives to a CSI snapshot implementation differ in where the snapshot logic lives.

A vendor backup agent is a separate daemon that talks to the storage system through the vendor's own API or a plugin, and it usually runs as a workload in the cluster or in a separate VM. The difference in approach is that the CSI snapshotter path keeps the operation inside the Kubernetes API model. A snapshot becomes a VolumeSnapshot object with a lifecycle, a retained flag and a status, so it is visible to kubectl and to any policy engine, and it is created and deleted the same way as any other object. The vendor agent's output is usually a job, a backup record in the vendor console, or a file, all of which live outside the cluster's object model.

A controller-only approach, meaning the shared snapshot controller with no per-driver sidecar, is not a real alternative for CSI. The controller creates and reconciles the content objects, but something has to call the driver's CreateSnapshot and DeleteSnapshot methods, and the sidecar is that something. Without a driver that implements those calls, the content object sits with no backing snapshot.

The third comparison is with a cloud provider's own volume snapshot and restore, which is often already available in a managed Kubernetes distribution. That path gives a native cloud resource with its own retention and replication story, and for a cluster entirely on one cloud with a supported disk type it is often less work than wiring up CSI snapshots. The CSI snapshotter path earns its keep when storage is not cloud-native, when you have a hybrid or on-premises backend, or when the same workflow has to work across drivers, which is exactly the case the shared-controller-and-per-driver-sidecar design is built for.

Whichever path you take, the failure modes to plan for are the same. A snapshot that succeeded but was never recorded as complete, and a retained snapshot whose underlying object was deleted out from under it.

## The repository is a Kubernetes SIG project with a client module of its own

This is a Kubernetes SIG Storage project, and the repository structure reflects the conventions of that community rather than the conventions of a standalone library.

The module lives at `github.com/kubernetes-csi/external-snapshotter/v8`, with a Go language version of 1.26.0, and the client is a separate Go module at `github.com/kubernetes-csi/external-snapshotter/client/v8`. The release history shows the two moving independently, with `v8.7.0` for the main module and `client/v8.7.0` for the client on the same day, and `client/v8.6.0` earlier on 2026-06-02. The client module is what consumers import when they want to write code that creates VolumeSnapshot objects, and it is versioned separately for exactly that reason.

The build is driven by a Makefile that includes `release-tools/build.make` and defines three commands: `CMDS=snapshot-controller csi-snapshotter snapshot-conversion-webhook`. The `all` target depends on `build`.

The `test` target depends on `test-vendor-client`, and the comments above it explain why the check exists. The `test-vendor` target does not perform vendor checks for the client module, and it cannot detect if vendor updates were made in the external-snapshotter module when changes are made in the client module, so the extra target runs the client module check and the main one in sequence:

```bash
test: test-vendor-client
test-vendor-client:
	@ echo; echo "### $@:"
	@ cd client && ../release-tools/verify-vendor.sh
	@ hack/verify-vendor.sh
```

There is also a `vendor/` directory in the repository, a `hack/` directory, a `deploy/` directory for the YAML, `examples/kubernetes/` for the example manifests, `client/` for the client module and CRDs, and a `CHANGELOG/` directory.

The licence is Apache-2.0, with the terms in the LICENSE file, and the repository is not archived with the last push on 2026-10-19 and v8.7.0 released on 2026-10-13.

## Conclusion

Adopt external-snapshotter when your CSI driver supports snapshots and you need Kubernetes-native VolumeSnapshot objects rather than a vendor-specific backup workflow, and you are prepared to install the CRDs and the shared controller alongside the per-driver sidecar. Do not adopt it if your storage backend has no CSI snapshot support, since the sidecar does nothing without a driver that implements the calls, or if you need group snapshots and your CSI driver predates v1.10.0. Verify first that the v1 snapshot CRDs are installed before upgrading past 4.1, since the storage version moves from v1beta1 to v1 and invalid v1beta1 objects must be deleted first.

## FAQ

### What does the CSI external-snapshotter sidecar actually watch?

Only VolumeSnapshotContent create, update and delete events, filtered by the `Driver==<CSI driver name>` value in the associated VolumeSnapshotClass. The shared snapshot controller is the component that watches VolumeSnapshot and VolumeSnapshotContent objects.

### How does the external-snapshotter talk to the CSI driver?

Over a Unix socket at /run/csi/socket by default, and the path is configurable with the -csi-address option. The sidecar and the driver must be able to reach that socket, which means they share a pod.

### Do I need to deploy one external-snapshotter per CSI driver?

Yes. The CSI Snapshotter sidecar must run once per CSI driver, while a single snapshot controller deployment serves all CSI drivers in a cluster. The README recommends that distributors bundle and deploy the controller and the CRDs as part of cluster management, independently of any driver.

### What CRDs does the external-snapshotter need installed?

The v1 snapshot CRDs are required by snapshot-controller, snapshot-conversion-webhook and csi-snapshotter v4.1 and later, and the v1beta2 volumegroupsnapshot CRDs are required when the volume group snapshot feature is enabled.

### Is the volume group snapshot feature on by default?

No. Volume group snapshot is disabled by default and enabled with a command line option, and it needs CSI v1.10.0 or higher. Plain volume snapshot, by contrast, was promoted to GA in Kubernetes 1.20 and is enabled by default on standard deployments.

## Sources

- [Issues](https://github.com/kubernetes-csi/external-snapshotter/issues)
- [kubernetes-csi/external-snapshotter on GitHub](https://github.com/kubernetes-csi/external-snapshotter)
- [License: Apache-2.0](https://github.com/kubernetes-csi/external-snapshotter/blob/master/LICENSE)
- [README](https://github.com/kubernetes-csi/external-snapshotter/blob/master/README.md)
- [Releases](https://github.com/kubernetes-csi/external-snapshotter/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kubernetes-csi-external-snapshotter
