diff --git a/deploy/kubernetes/controller.yaml b/deploy/kubernetes/controller.yaml index d1a6bcd535..a576637ec5 100644 --- a/deploy/kubernetes/controller.yaml +++ b/deploy/kubernetes/controller.yaml @@ -105,6 +105,56 @@ roleRef: --- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: external-snapshotter-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: external-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + kind: StatefulSet apiVersion: apps/v1beta1 metadata: @@ -186,6 +236,18 @@ spec: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter + image: quay.io/k8scsi/csi-snapshotter:v1.0.1 + args: + - --csi-address=$(ADDRESS) + - --connection-timeout=15s + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: Always + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ volumes: - name: socket-dir emptyDir: {} diff --git a/docs/README.md b/docs/README.md index 6d86ced359..e07ec5320d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -61,7 +61,7 @@ There are several optional parameters that could be passed into `CreateVolumeReq 2. Enable the flag `--allow-privileged=true` in the manifest entries of kubelet and kube-apiserver. -3. Add `--feature-gates=CSINodeInfo=true,CSIDriverRegistry=true` in the manifest entries of kubelet and kube-apiserver. This is required to enable topology support of EBS volumes in Kubernetes. +3. Add `--feature-gates=CSINodeInfo=true,CSIDriverRegistry=true,VolumeSnapshotDataSource=true` in the manifest entries of kubelet and kube-apiserver. This is required to enable topology support of EBS volumes in Kubernetes and restoring volumes from snapshots. 4. Install the `CSINodeInfo` CRD on the cluster using the instructions provided here: [Enabling CSINodeInfo](https://kubernetes-csi.github.io/docs/Setup.html#enabling-csinodeinfo). diff --git a/examples/kubernetes/snapshot/README.md b/examples/kubernetes/snapshot/README.md new file mode 100644 index 0000000000..2a607999d3 --- /dev/null +++ b/examples/kubernetes/snapshot/README.md @@ -0,0 +1,42 @@ +# Volume Snapshots with AWS EBS CSI Driver + +## Overview + +This driver implements basic volume snapshotting functionality, i.e. it is possible to use it along with the [external +snapshotter](https://github.com/kubernetes-csi/external-snapshotter) sidecar and create snapshots of EBS volumes using +the `VolumeSnapshot` custom resources. + +## Prerequisites + +1. Kubernetes 1.13+ (CSI 1.0) is required + +2. The `VolumeSnapshotDataSource` feature gate of Kubernetes API server and controller manager must be turned on. + +## Usage + +This directory contains example YAML files to test the feature. First, see the [deployment example](../../../deploy/kubernetes) and [volume scheduling example](../volume_scheduling) +to set up the external provisioner: + +### Set up + +1. Create the RBAC rules + +2. Start the contoller `StatefulSet` + +3. Start the node `DaemonSet` + +4. Create a `StorageClass` for dynamic provisioning of the AWS CSI volumes + +5. Create a `SnapshotClass` to create `VolumeSnapshot`s using the AWS CSI external controller + +6. Create a `PersistentVolumeClaim` and a pod using it + +### Taking and restoring volume snapshot + +7. Create a `VolumeSnapshot` referencing the `PersistentVolumeClaim`; the snapshot creation may take time to finish: + check the `ReadyToUse` attribute of the `VolumeSnapshot` object to find out when a new `PersistentVolume` can be + created from the snapshot + +8. To restore a volume from a snapshot use a `PersistentVolumeClaim` referencing the `VolumeSnapshot` in its `dataSource`; see the + [Kubernetes Persistent Volumes documentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-snapshot-and-restore-volume-from-snapshot-support) + and the example [restore claim](./restore-claim.yaml) diff --git a/examples/kubernetes/snapshot/claim.yaml b/examples/kubernetes/snapshot/claim.yaml new file mode 100644 index 0000000000..a883baa530 --- /dev/null +++ b/examples/kubernetes/snapshot/claim.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ebs-claim +spec: + accessModes: + - ReadWriteOnce + storageClassName: ebs-sc + resources: + requests: + storage: 4Gi diff --git a/examples/kubernetes/snapshot/pod.yaml b/examples/kubernetes/snapshot/pod.yaml new file mode 100644 index 0000000000..f274015916 --- /dev/null +++ b/examples/kubernetes/snapshot/pod.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: app +spec: + containers: + - name: app + image: centos + command: ["/bin/sh"] + args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"] + volumeMounts: + - name: persistent-storage + mountPath: /data + volumes: + - name: persistent-storage + persistentVolumeClaim: + claimName: ebs-claim diff --git a/examples/kubernetes/snapshot/restore-claim.yaml b/examples/kubernetes/snapshot/restore-claim.yaml new file mode 100644 index 0000000000..eba2c0646f --- /dev/null +++ b/examples/kubernetes/snapshot/restore-claim.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ebs-restore-claim +spec: + accessModes: + - ReadWriteOnce + storageClassName: ebs-sc + resources: + requests: + storage: 2Gi + dataSource: + name: ebs-volume-snapshot + kind: VolumeSnapshot + apiGroup: snapshot.storage.k8s.io diff --git a/examples/kubernetes/snapshot/snapshot.yaml b/examples/kubernetes/snapshot/snapshot.yaml new file mode 100644 index 0000000000..69bf3ef2f4 --- /dev/null +++ b/examples/kubernetes/snapshot/snapshot.yaml @@ -0,0 +1,9 @@ +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshot +metadata: + name: ebs-volume-snapshot +spec: + snapshotClassName: csi-aws-snapclass + source: + name: ebs-claim + kind: PersistentVolumeClaim diff --git a/examples/kubernetes/snapshot/snapshotclass.yaml b/examples/kubernetes/snapshot/snapshotclass.yaml new file mode 100644 index 0000000000..bc1220078f --- /dev/null +++ b/examples/kubernetes/snapshot/snapshotclass.yaml @@ -0,0 +1,5 @@ +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshotClass +metadata: + name: csi-aws-snapclass +snapshotter: ebs.csi.aws.com diff --git a/examples/kubernetes/snapshot/storageclass.yaml b/examples/kubernetes/snapshot/storageclass.yaml new file mode 100644 index 0000000000..d6e168e1ec --- /dev/null +++ b/examples/kubernetes/snapshot/storageclass.yaml @@ -0,0 +1,6 @@ +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: ebs-sc +provisioner: ebs.csi.aws.com +volumeBindingMode: WaitForFirstConsumer