A Container Storage Interface (CSI) Driver for DigitalOcean Block Storage. The CSI plugin allows you to use DigitalOcean Block Storage with your preferred Container Orchestrator.
The DigitalOcean CSI plugin is mostly tested on Kubernetes. Theoretically it should also work on other Container Orchestrators, such as Mesos or Cloud Foundry. Feel free to test it on other CO's and give us a feedback.
The DigitalOcean CSI plugin follows semantic versioning. The version will be bumped following the rules below:
- Bug fixes will be released as a
PATCH
update. - New features (such as CSI spec bumps with no breaking changes) will be released as a
MINOR
update. - Significant breaking changes makes a
MAJOR
update.
Below is a list of functionality implemented by the plugin. In general, CSI features implementing an aspect of the specification are available on any DigitalOcean Kubernetes version for which beta support for the feature is provided.
See also the project examples for use cases.
Volumes can be expanded by updating the storage request value of the corresponding PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-pvc
namespace: default
spec:
[...]
resources:
requests:
# The field below can be increased.
storage: 10Gi
[...]
After successful expansion, the status section of the PVC object will reflect the actual volume capacity.
Important notes:
- Volumes can only be increased in size, not decreased; attempts to do so will lead to an error.
- Expanding a volume that is larger than the target size will have no effect. The PVC object status section will continue to represent the actual volume capacity.
- Resizing volumes other than through the PVC object (e.g., the DigitalOcean cloud control panel) is not recommended as this can potentially cause conflicts. Additionally, size updates will not be reflected in the PVC object status section immediately, and the section will eventually show the actual volume capacity.
Volumes can be used in raw block device mode by setting the volumeMode
on the corresponding PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-pvc
namespace: default
spec:
[...]
volumeMode: Block
Important notes:
- If using volume expansion functionality, only expansion of the underlying persistent volume is guaranteed. We do not guarantee to automatically expand the filesystem if you have formatted the device.
Snapshots can be created and restored through VolumeSnapshot
objects.
See also the example.
Volume statistics are exposed through the CSI-conformant endpoints. Monitoring systems such as Prometheus can scrape metrics and provide insights into volume usage.
Volumes can be transferred across clusters. The exact steps are outlined in our example.
The following table describes the required DigitalOcean CSI driver version per Kubernetes release.
Kubernetes Release | DigitalOcean CSI Driver Version |
---|---|
1.10 (1.10.5+) | v0.2.x |
1.11 | v0.2.x |
1.12 | v0.4.x |
1.13 | v1.0.x |
1.14 | v1.2.x |
1.15 | v1.2.x |
1.16 | v1.2.x |
Note: The DigitalOcean Kubernetes
products comes
with the CSI driver pre-installed and no further steps are required.
Requirements:
--allow-privileged
flag must be set to true for both the API server and the kubelet--feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true
feature gate flags must be set to true for both the API server and the kubelet- Mount Propagation needs to be enabled. If you use Docker, the Docker daemon of the cluster nodes must allow shared mounts.
Replace the placeholder string starting with a05...
with your own secret and
save it as secret.yml
:
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
stringData:
access-token: "a05dd2f26b9b9ac2asdas__REPLACE_ME____123cb5d1ec17513e06da"
and create the secret using kubectl:
$ kubectl create -f ./secret.yml
secret "digitalocean" created
You should now see the digitalocean secret in the kube-system
namespace along with other secrets
$ kubectl -n kube-system get secrets
NAME TYPE DATA AGE
default-token-jskxx kubernetes.io/service-account-token 3 18h
digitalocean Opaque 1 18h
Before you continue, be sure to checkout to a tagged release. Always use the latest version compatible with your Kubernetes release (see the compatibility information).
The releases directory directory holds manifests for all plugin releases. You can deploy a specific version by executing the command
kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-vX.Y.Z.yaml
where vX.Y.Z
is the plugin target version.
If you see any issues during the installation, this could be because the newly
created CRDs haven't been established yet. If you call kubectl apply -f
again
on the same file, the missing resources will be applied again.
Create a PersistentVolumeClaim. This makes sure a volume is created and provisioned on your behalf:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: do-block-storage
Check that a new PersistentVolume
is created based on your claim:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-0879b207-9558-11e8-b6b4-5218f75c62b9 5Gi RWO Delete Bound default/csi-pvc do-block-storage 3m
The above output means that the CSI plugin successfully created (provisioned) a new Volume on behalf of you. You should be able to see this newly created volume under the Volumes tab in the DigitalOcean UI
The volume is not attached to any node yet. It'll only attached to a node if a workload (i.e: pod) is scheduled to a specific node. Now let us create a Pod that refers to the above volume. When the Pod is created, the volume will be attached, formatted and mounted to the specified Container:
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox
volumeMounts:
- mountPath: "/data"
name: my-do-volume
command: [ "sleep", "1000000" ]
volumes:
- name: my-do-volume
persistentVolumeClaim:
claimName: csi-pvc
Check if the pod is running successfully:
$ kubectl describe pods/my-csi-app
Write inside the app container:
$ kubectl exec -ti my-csi-app /bin/sh
/ # touch /data/hello-world
/ # exit
$ kubectl exec -ti my-csi-app /bin/sh
/ # ls /data
hello-world
When upgrading to a new Kubernetes minor version, you should upgrade the CSI driver to match. See the table above for which driver version is used with each Kubernetes version.
Special consideration is necessary when upgrading from Kubernetes 1.11 or
earlier, which uses CSI driver version 0.2 or earlier. In these early releases,
the driver name was com.digitalocean.csi.dobs
, while in all subsequent
releases it is dobs.csi.digitalocean.com
. When upgrading, use the commandline
flag --driver-name
to force the new driver to use the old name. Failing to do
so will cause any existing PVs to be unusable since the new driver will not
manage them and the old driver is no longer running.
Requirements:
- Go: min
v1.13.x
After making your changes, run the unit tests:
$ make test
If you want to test your changes, create a new image with the version set to dev
:
$ VERSION=dev make publish
This will create a binary with version dev
and docker image pushed to
digitalocean/do-csi-plugin:dev
To run the integration tests on a DOKS cluster, follow these instructions.
Dependencies are managed via Go modules.
To release a new version vX.Y.Z
, first bump the version:
$ make NEW_VERSION=vX.Y.Z bump-version
Make sure everything looks good. Create a new branch with all changes:
$ git checkout -b new-release
$ git add .
$ git push origin
After it's merged to master, create a new Github
release from
master with the version vX.Y.Z
and then publish a new docker build:
$ git checkout master
$ make publish
This will create a binary with version vX.Y.Z
and docker image pushed to
digitalocean/do-csi-plugin:vX.Y.Z
.
At DigitalOcean we value and love our community! If you have any issues or would like to contribute, feel free to open an issue/PR