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: 

  1. Create a VolumeSnapshotClass. 
  2. Create a VolumeSnapshot for an existing Persistent Volume (PV) that has been provisioned by Trident and attached to a pod. 
  3. 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: 

  1. Creation and deletion of volume snapshots via Kubernetes native API. 
  2. 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 “StorageClassconstruct which we use to identify the provisioner that needs to be used. A VolumeSnapshotClass 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 the VolumeSnapshot 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 to True, 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 

Bala RameshBabu

Pin It on Pinterest