Introducing Volume Snapshot Alpha for Kubernetes
Author: Jing Xu (Google) Xing Yang (Huawei), Saad Ali (Google)
Kubernetes v1.12 introduces alpha support for volume snapshotting. This feature allows creating/deleting volume snapshots, and the ability to create new volumes from a snapshot natively using the Kubernetes API.
What is a Snapshot?
Many storage systems (like Google Cloud Persistent Disks, Amazon Elastic Block Storage, and many on-premise storage systems) provide the ability to create a "snapshot" of a persistent volume. A snapshot represents a point-in-time copy of a volume. A snapshot can be used either to provision a new volume (pre-populated with the snapshot data) or to restore the existing volume to a previous state (represented by the snapshot).
Why add Snapshots to Kubernetes?
The Kubernetes volume plugin system already provides a powerful abstraction that automates the provisioning, attaching, and mounting of block and file storage.
Underpinning all these features is the Kubernetes goal of workload portability: Kubernetes aims to create an abstraction layer between distributed systems applications and underlying clusters so that applications can be agnostic to the specifics of the cluster they run on and application deployment requires no “cluster specific” knowledge.
The
By providing a standard way to trigger snapshot operations in the Kubernetes API, Kubernetes users can now handle use cases like this without having to go around the Kubernetes API (and manually executing storage system specific operations). Instead, Kubernetes users are now empowered to incorporate snapshot operations in a cluster agnostic way into their tooling and policy with the comfort of knowing that it will work against arbitrary Kubernetes clusters regardless of the underlying storage. Additionally these Kubernetes snapshot primitives act as basic building blocks that unlock the ability to develop advanced, enterprise grade, storage administration features for Kubernetes: such as data protection, data replication, and data migration. Kubernetes supports three types of volume plugins: in-tree, Flex, and CSI. See
Snapshots are only supported for CSI drivers (not for in-tree or Flex). To use the Kubernetes snapshots feature, ensure that a CSI Driver that implements snapshots is deployed on your cluster. As of the publishing of this blog, the following CSI drivers support snapshots: Snapshot support for other
Similar to the API for managing Kubernetes Persistent Volumes, Kubernetes Volume Snapshots introduce three new API objects for managing snapshots: It is important to note that unlike the core Kubernetes Persistent Volume objects, these Snapshot objects are defined as CustomResourceDefinitions (CRDs). The Kubernetes project is moving away from having resource types pre-defined in the API server, and is moving towards a model where the API server is independent of the API objects. This allows the API server to be reused for projects other than Kubernetes, and consumers (like Kubernetes) can simply install the resource types they require as CRDs.
In addition to these new objects, a new, DataSource field has been added to the This new alpha field enables a new volume to be created and automatically pre-populated with data from an existing snapshot. Before using Kubernetes Volume Snapshotting, you must: Before creating a snapshot, you also need to specify CSI driver information for snapshots by creating a You must set any required opaque parameters based on the documentation for your CSI driver. As the example above shows, the parameter And finally, before creating a snapshot, you must provision a volume using your CSI driver and populate it with some data that you want to snapshot (see the
Once a The source of the snapshot specifies the volume to create a snapshot from. It has two parameters: The namespace of the volume to snapshot is assumed to be the same as the namespace of the In the In response, the CSI driver triggers a snapshot of the volume and then automatically creates a If a snapshot class is not specified, the external snapshotter will try to find and set a default snapshot class for the snapshot. The Please note that the alpha release of Kubernetes Snapshot does not provide any consistency guarantees. You have to prepare your application (pause application, freeze filesystem etc.) before taking the snapshot for data consistency. You can verify that the You can always import an existing snapshot to Kubernetes by manually creating a A A Once these objects are created, the snapshot controller will bind them together, and set the field Ready (under To provision a new volume pre-populated with data from a snapshot object, use the new dataSource field in the The namespace of the source When the To implement the snapshot feature, a CSI driver MUST add support for additional controller capabilities Although Kubernetes is as
As part of this recommended deployment process, the Kubernetes team provides a number of sidecar (helper) containers, including a new
The external-snapshotter watches the Kubernetes API server for In order to support snapshot feature, it is recommended that storage vendors deploy the external-snapshotter sidecar containers in addition to the external provisioner the external attacher, along with their CSI driver in a statefulset as shown in the following diagram. In this
The alpha implementation of snapshots for Kubernetes has the following limitations: Depending on feedback and adoption, the Kubernetes team plans to push the CSI Snapshot implementation to beta in either 1.13 or 1.14. Check out additional documentation on the snapshot feature here: https://kubernetes-csi.github.io/docs/ This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together. In addition to the contributors who have been working on the Snapshot feature: We offer a huge thank you to all the contributors in Kubernetes Storage SIG and CSI community who helped review the design and implementation of the project, including but not limited to the following: If you’re interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the
Which volume plugins support Kubernetes Snapshots?
Kubernetes Snapshots API
VolumeSnapshot
PersistentVolumeClaim
object, the creation and deletion of this object represents a user desire to create or delete a cluster resource (a snapshot).VolumeSnapshotContent
PersistentVolume
object, this object represents a provisioned resource on the cluster (a snapshot).PersistentVolumeClaim
and PersistentVolume
objects, once a snapshot is created, the VolumeSnapshotContent
object binds to the VolumeSnapshot for which it was created (with a one-to-one mapping).VolumeSnapshotClass
PersistentVolumeClaim
object:type PersistentVolumeClaimSpec struct {
AccessModes []PersistentVolumeAccessMode
Selector *metav1.LabelSelector
Resources ResourceRequirements
VolumeName string
StorageClassName *string
VolumeMode *PersistentVolumeMode
DataSource *TypedLocalObjectReference
}
Kubernetes Snapshots Requirements
--feature-gates=VolumeSnapshotDataSource=true
VolumeSnapshotClass
object and setting the snapshotter
field to point to your CSI driver. In the example of VolumeSnapshotClass
below, the CSI driver is com.example.csi-driver
. You need at least one VolumeSnapshotClass
object per snapshot provisioner. You can also set a default VolumeSnapshotClass
for each individual CSI driver by putting an annotation snapshot.storage.kubernetes.io/is-default-class: "true"
in the class definition.apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: default-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true"
snapshotter: com.example.csi-driver
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
snapshotter: com.example.csi-driver
parameters:
fakeSnapshotOption: foo
csiSnapshotterSecretName: csi-secret
csiSnapshotterSecretNamespace: csi-namespace
fakeSnapshotOption: foo
and any referenced secret(s) will be passed to CSI driver during snapshot creation and deletion. The
Creating a new Snapshot with Kubernetes
VolumeSnapshotClass
object is defined and you have a volume you want to snapshot, you may create a new snapshot by creating a VolumeSnapshot
object.
kind
- must be PersistentVolumeClaim
name
- the PVC API object nameVolumeSnapshot
object.apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: new-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
source:
name: mypvc
kind: PersistentVolumeClaim
VolumeSnapshot
spec, user can specify the VolumeSnapshotClass
which has the information about which CSI driver should be used for creating the snapshot . When the VolumeSnapshot
object is created, the parameter fakeSnapshotOption: foo
and any referenced secret(s) from the VolumeSnapshotClass
are passed to the CSI plugin com.example.csi-driver
via a CreateSnapshot
call.VolumeSnapshotContent
object to represent the new snapshot, and binds the new VolumeSnapshotContent
object to the VolumeSnapshot
, making it ready to use. If the CSI driver fails to create the snapshot and returns error, the snapshot controller reports the error in the status of VolumeSnapshot
object and does not retry (this is different from other controllers in Kubernetes, and is to prevent snapshots from being taken at an unexpected time).CSI driver
specified by snapshotter
in the default snapshot class must match the CSI driver
specified by the provisioner
in the storage class of the PVC.VolumeSnapshot
object is created and bound with VolumeSnapshotContent
by running kubectl describe volumesnapshot
:
Ready
should be set to true under Status
to indicate this volume snapshot is ready for use.Creation Time
field indicates when the snapshot is actually created (cut).Restore Size
field indicates the minimum volume size when restoring a volume from the snapshot.Snapshot Content Name
field in the spec
points to the VolumeSnapshotContent
object created for this snapshot.Importing an existing snapshot with Kubernetes
VolumeSnapshotContent
object to represent the existing snapshot. Because VolumeSnapshotContent
is a non-namespace API object, only a system admin may have the permission to create it. Once a VolumeSnapshotContent
object is created, the user can create a VolumeSnapshot
object pointing to the VolumeSnapshotContent
object. The external-snapshotter controller will mark snapshot as ready after verifying the snapshot exists and the binding between VolumeSnapshot
and VolumeSnapshotContent
objects is correct. Once bound, the snapshot is ready to use in Kubernetes.VolumeSnapshotContent
object should be created with the following fields to represent a pre-provisioned snapshot:
csiVolumeSnapshotSource
- Snapshot identifying information.
snapshotHandle
- name/identifier of the snapshot. This field is required.driver
- CSI driver used to handle this volume. This field is required. It must match the snapshotter name in the snapshot controller.creationTime
and restoreSize
- these fields are not required for pre-provisioned volumes. The external-snapshotter controller will automatically update them after creation.volumeSnapshotRef
- Pointer to the VolumeSnapshot
object this object should bind to.
name
and namespace
- It specifies the name and namespace of the VolumeSnapshot
object which the content is bound to.UID
- these fields are not required for pre-provisioned volumes.The external-snapshotter controller will update the field automatically after binding. If user specifies UID field, he/she must make sure that it matches with the binding snapshot’s UID. If the specified UID does not match the binding snapshot’s UID, the content is considered an orphan object and the controller will delete it and its associated snapshot.snapshotClassName
- This field is optional. The external-snapshotter controller will update the field automatically after binding.apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotContent
metadata:
name: static-snapshot-content
spec:
csiVolumeSnapshotSource:
driver: com.example.csi-driver
snapshotHandle: snapshotcontent-example-id
volumeSnapshotRef:
kind: VolumeSnapshot
name: static-snapshot-demo
namespace: demo-namespace
VolumeSnapshot
object should be created to allow a user to use the snapshot:
snapshotClassName
- name of the volume snapshot class. This field is optional. If set, the snapshotter field in the snapshot class must match the snapshotter name of the snapshot controller. If not set, the snapshot controller will try to find a default snapshot class.snapshotContentName
- name of the volume snapshot content. This field is required for pre-provisioned volumes.apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: static-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
snapshotContentName: static-snapshot-content
Status
) to True to indicate the snapshot is ready to use.Provision a new volume from a snapshot with Kubernetes
PersistentVolumeClaim
. It has three parameters:
VolumeSnapshot
object representing the snapshot to use as sourceVolumeSnapshot
snapshot.storage.k8s.io
VolumeSnapshot
object is assumed to be the same as the namespace of the PersistentVolumeClaim
object.apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-restore
Namespace: demo-namespace
spec:
storageClassName: csi-storageclass
dataSource:
name: new-snapshot-demo
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
PersistentVolumeClaim
object is created, it will trigger provisioning of a new volume that is pre-populated with data from the specified snapshot.As a storage vendor, how do I add support for snapshots to my CSI driver?
CREATE_DELETE_SNAPSHOT
and LIST_SNAPSHOTS
, and implement additional controller RPCs: CreateSnapshot
, DeleteSnapshot
, and ListSnapshots
. For details, see .VolumeSnapshot
and VolumeSnapshotContent
objects and triggers CreateSnapshot and DeleteSnapshot operations against a CSI endpoint. The CSI
What are the limitations of alpha?
What’s next?
How can I learn more?
How do I get involved?