As you would have already heard, the 19.07 Alpha release is packed with some cool new features, of which Volume Snapshots is an important one. Trident 19.07 Alpha is designed to provide on-demand Volume Snapshots and support the creation of Persistent Volumes from snapshots using the CSI framework. If you haven’t already, be sure to check All New CSI Trident! for an introduction of how CSI Trident works.
Note: Snapshots are offered as an Alpha feature beginning with Kubernetes 1.13 and are subject to change. The ontap-nas-flexgroup
driver does not support snapshots as of the Alpha release.
Note: Trident 19.07 Alpha is meant for Greenfield deployments only and should only be used in a dev/test environment. It is not intended to be used for production, or upgraded once 19.07 GA release is available.
In this blog, we will implement the workflow listed below to see how snapshots work:
- Create a
VolumeSnapshotClass
. - Create a
VolumeSnapshot
for an existing Persistent Volume (PV) that has been provisioned by Trident and attached to a pod. - Use the
VolumeSnapshot
to create a new Persistent Volume Claim (PVC). The PVC will be served by Trident by creating a PV using the VolumeSnapshot as a source.
Kubernetes currently allows CSI Drivers to expose the following functionality via the Kubernetes API:
- Creation and deletion of volume snapshots via Kubernetes native API.
- Creation of new volumes pre-populated with the data from a snapshot via Kubernetes dynamic volume provisioning (through Trident in our case).
Note: For CSI Trident to work, the following feature gates must be enabled:
CSIDriverRegistry
CSINodeInfo
VolumeSnapshotDataSource
[For using Snapshots to create PVs]
By default, CSIDriverRegistry
and CSINodeInfo
are enabled in Kubernetes 1.14. Please ensure all feature gates listed above are enabled for CSI Trident to function as expected. Refer to the documentation on Feature gates to identify the stage for the gates in question.
Constructs that define Snapshots
Before looking at how snapshots can be created, let us look at some constructs that will be required to support snapshots:
- VolumeSnapshotClass: A
VolumeSnapshotClass
serves to classify the different classes of storage available when creating a volume snapshot. This is similar to the “StorageClass” construct which we use to identify the provisioner that needs to be used. AVolumeSnapshotClass
abstracts the details of how volume snapshots should be dynamically provisioned.
- VolumeSnapshotContent: A
VolumeSnapshotContent
is a snapshot that is taken from a volume in the cluster than has been provisioned by an administrator. It is analogous to a Persistent Volume.
- VolumeSnapshot: This represents a request to create a snapshot of a PV. It is analogous to a PVC. When a user creates a
VolumeSnapshot
by referencing the PVC of the volume in question, Trident dynamically creates a snapshot and exposes it to Kubernetes, making theVolumeSnapshot
object accessible through Kubernetes native APIs.
These constructs are implemented as CRDs and are automatically installed by Trident during the installation process. You can take a look at them by running a kubectl get crds
and examine them in detail by doing a kubectl describe crd
.
Working with Snapshots
The environment I am working with has Kubernetes 1.13 with the Trident 19.07 Alpha release. An ONTAP NAS backend has been configured and there is a pod [centos-pod] running a CentOS container. This pod has a PV attached to it which has been served by Trident.
[root@trident-1907-alpha ~]# cat pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: centos-pod
spec:
volumes:
- name: vol1
persistentVolumeClaim:
claimName: pvc1
containers:
- name: centos
image: centos:latest
command: ["/bin/sh"]
args: ["-c", "echo Container has been set up on $(date -u) >> /data/vol1/logger && sleep 60m"]
volumeMounts:
- mountPath: "/data/vol1"
name: vol1
[root@trident-1907-alpha ~]#
kubectl get pods
NAME READY STATUS RESTARTS AGE
centos-pod 1/1 Running 0 54s
As can be seen, the pod consists of a CentOS container, which writes a file named “logger” to the mountpoint where the PV is attached.
The contents of the file can be examined by an exec into the container:
[root@trident-1907-alpha ~]# kubectl exec -it centos-pod bash
[root@centos-pod /]# cat /data/vol1/logger
Container has been set up on Wed Jun 26 15:00:36 UTC 2019
Creating a VolumeSnapshotClass
All’s well and good, and I would now like to create a snapshot of this volume to preserve its “pristine” state. To do that, I first create a VolumeSnapshotClass using the yaml shown below:
[root@trident-1907-alpha ~]# cat sc-snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name:
csi-
vsc
snapshotter: csi.trident.netapp.io
This basic VolumeSnapshotClass
instructs Kubernetes that snapshots pertaining to this class will be taken care of by Trident [notice the snapshotter parameter says “csi.trident.netapp.io”].
Creating a Volume Snapshot
A snapshot can now be created by referencing the PVC named “pvc1”. This PVC served the backing volume for the CentOS container running within the pod.
[root@trident-1907-alpha ~]# cat snap-create.yaml
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: centos-vol1-snapshot
spec:
snapshotClassName: csi-vsc
source:
name: pvc1
kind: PersistentVolumeClaim
It is as simple as that.
[root@trident-1907-alpha ~]# kubectl create -f snap-create.yaml
volumesnapshot.snapshot.storage.k8s.io/centos-vol1-snapshot created
[root@trident-1907-alpha ~]# kubectl get volumesnapshots
NAME AGE
centos-vol1-snapshot 50s
[root@trident-1907-alpha ~]# kubectl describe volumesnapshots centos-vol1-snapshot
Name: centos-vol1-snapshot
Namespace: default
Labels:
Annotations:
API Version: snapshot.storage.k8s.io/v1alpha1
Kind: VolumeSnapshot
Metadata:
Creation Timestamp: 2019-06-26T15:27:29Z
Finalizers:
snapshot.storage.kubernetes.io/volumesnapshot-protection
Generation: 5
Resource Version: 62765
Self Link: /apis/snapshot.storage.k8s.io/v1alpha1/namespaces/default/volumesnapshots/centos-vol1-snapshot
UID: e8d8a0ca-9826-11e9-9807-525400f3f660
Spec:
Snapshot Class Name: csi-vsc
Snapshot Content Name: snapcontent-e8d8a0ca-9826-11e9-9807-525400f3f660
Source:
API Group:
Kind: PersistentVolumeClaim
Name: pvc1
Status:
Creation Time: 2019-06-26T15:27:29Z
Ready To Use: true
Restore Size: 3Gi
Events:
A quick look at the VolumeSnapshot
reveals some interesting parameters:
- The
UID
represents the unique ID associated with this snapshot. The snapshot that is created on the ONTAP backend is named after the UID. - The
VolumeSnapshotContent
object associated with this snapshot is listed [snapcontent-e8d8a0ca-9826-11e9-9807-525400f3f660
]. - The source of the snapshot is the PVC created for the pod [
pvc1
]. - The
Ready To Use
parameter is set toTrue
, indicating that this snapshot can be used to provision new PVs.
You can also do a kubectl describe volumesnapshotcontents snapcontent-e8d8a0ca-9826-11e9-9807-525400f3f660
to take a look at the creation time, the driver that handles the creation [csi.trident.netapp.io], the Snapshot Handle [the unique identifier for each snapshot] and details of the backing PV. For the sake of brevity, this has been excluded in this blog.
Tridentctl also exposes the snapshots and their associated volumes.
[root@trident-1907-alpha trident]# tridentctl get snapshots -n trident
+-----------------------------------------------+------------------------------------------+
| NAME | VOLUME |
+-----------------------------------------------+------------------------------------------+
| snapshot-e8d8a0ca-9826-11e9-9807-525400f3f660 |
pvc-23905d26-981f-11e9-9807-525400f3f660 |
+-----------------------------------------------+------------------------------------------+
Creating a PVC from the VolumeSnapshot
I can now create a PVC that uses the previously created snapshot as the source.
[root@trident-1907-alpha ~]# cat pvc-from-snap.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-from-snap
spec:
accessModes:
- ReadWriteOnce
storageClassName: golden
resources:
requests:
storage: 3Gi
dataSource:
name: centos-vol1-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
Once the PVC is created and bound, let’s take a look at the associated volume.
[root@trident-1907-alpha ~]#
kubectl describe pv pvc-318c7ec0-9829-11e9-9807-525400f3f660
Name: pvc-318c7ec0-9829-11e9-9807-525400f3f660
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: csi.trident.netapp.io
Finalizers: [kubernetes.io/pv-protection external-attacher/csi-trident-netapp-io]
StorageClass: golden
Status: Bound
Claim: default/pvc-from-snap
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 3Gi
Node Affinity: <none>
Message:
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: csi.trident.netapp.io
VolumeHandle: pvc-318c7ec0-9829-11e9-9807-525400f3f660
ReadOnly: false
VolumeAttributes: backendUUID=9caab3cb-fd0a-4bc4-831f-af55d5fb5ef6
internalName=trid_1907_alpha_pvc_318c7ec0_9829_11e9_9807_525400f3f660
name=pvc-318c7ec0-9829-11e9-9807-525400f3f660
protocol=file
storage.kubernetes.io/csiProvisionerIdentity=1561512408442-8081-
Events: <none>
The volume’s type indicates that it has been provisioned by CSI Trident. Contrary to an NFS or iSCSI volume type, it is now a CSI volume.
I create another pod that requests the pvc-from-snap
PVC. This file creates a pod running a CentOS container and a PV created from the snapshot that is mounted at “/mnt/vol1”. This PV must contain the logger file that was created earlier.
kind: Pod
apiVersion: v1
metadata:
name: centos-pod-from-snap
spec:
volumes:
- name: vol1
persistentVolumeClaim:
claimName:
pvc-from-snap
containers:
- name: centos
image: centos:latest
command:
- /bin/sh
- "-c"
- "sleep 60m"
volumeMounts:
-
mountPath: "/mnt/vol1"
name: vol1
[root@trident-1907-alpha ~]#
kubectl exec -it centos-pod-from-snap bash
[root@centos-pod-from-snap /]# cat /mnt/vol1/logger
Container has been set up on Wed Jun 26 15:00:36 UTC 2019
And there it is.
Stay Connected
Netapp.io contains the latest information on our Open Ecosystem contributions. Be sure to join us at our Slack workspace for all things Trident!