deployment.md
October 13, 2025 Β· View on GitHub
π Deployment
π§ Requirements
- Kubernetes v1.16+
- LINODE_API_TOKEN: Personal Access Token with:
- Read/Write access to Volumes
- Read/Write access to Linodes
- Sufficient "Expiry" for continued use
- LINODE_REGION: Linode Region
π Secure a Linode API Access Token
Generate a Personal Access Token (PAT) using the Linode Cloud Manager.
βοΈ Deployment Methods
There are two primary methods to deploy the CSI Driver:
- Using Helm (Recommended)
- Using kubectl
π§ Prerequisites for running the driver
- The deployment assumes that the Linode Cloud Controller Manager (CCM) is running.
1. Using Helm
π Install the csi-linode Repo
helm repo add linode-csi https://linode.github.io/linode-blockstorage-csi-driver/
helm repo update linode-csi
π Deploy the CSI Driver
export LINODE_API_TOKEN="...your Linode API token..."
export REGION="your preferred region"
helm install linode-csi-driver \
--set apiToken="${LINODE_API_TOKEN}" \
--set region="${REGION}" \
linode-csi/linode-blockstorage-csi-driver
See helm install for command documentation.
π§Ή Uninstalling the CSI Driver
helm uninstall linode-csi-driver
See helm uninstall for command documentation.
β¬οΈ Upgrading the CSI Driver
export LINODE_API_TOKEN="...your Linode API token..."
export REGION="your preferred region"
helm upgrade linode-csi-driver \
--install \
--set apiToken="${LINODE_API_TOKEN}" \
--set region="${REGION}" \
linode-csi/linode-blockstorage-csi-driver
See helm upgrade for command documentation.
βοΈ Configurations
- Modify variables using the
--set var=valueflag or by providing a customvalues.yamlwith-f custom-values.yaml. - For a comprehensive list of configurable variables, refer to
helm-chart/csi-driver/values.yaml.
Controller kubeconfig (optional)
If your environment requires the controller to use a kubeconfig file explicitly, enable the controller kubeconfig by providing the following values. The Secret will be mounted as a directory and the sidecars will read the file <mountDir>/<secretKey>.
controller:
kubeconfig:
mountDir: /etc/kubeconfig
secretName: csi-kubeconfig
secretKey: external-kubeconfig
Helm example:
helm install linode-csi-driver \
--set apiToken="$LINODE_API_TOKEN" \
--set region="$REGION" \
--set controller.kubeconfig.mountDir=/etc/kubeconfig \
--set controller.kubeconfig.secretName=csi-kubeconfig \
--set controller.kubeconfig.secretKey=external-kubeconfig \
linode-csi/linode-blockstorage-csi-driver
The Secret should contain a key named external-kubeconfig (or your chosen secretKey). For example:
apiVersion: v1
kind: Secret
metadata:
name: csi-kubeconfig
namespace: kube-system
stringData:
external-kubeconfig: |
# contents of your kubeconfig file
Controller ServiceAccount and RBAC toggles
By default, the chart creates the controller ServiceAccount and its RBAC ClusterRoleBindings. You can disable these if you want to manage them externally. The controller ServiceAccount name defaults to csi-controller-sa.
controller:
serviceAccount:
enabled: true # set to false to skip creating the SA (still referenced by the StatefulSet)
name: "" # optionally override the ServiceAccount name (defaults to "csi-controller-sa")
rbac:
enabled: true # set to false to skip creating controller ClusterRoleBindings
When controller.serviceAccount.enabled=false, ensure a ServiceAccount named csi-controller-sa exists in the target namespace.
DaemonSet ServiceAccount and RBAC toggles
By default, the chart also creates the node DaemonSet ServiceAccount and its RBAC ClusterRoleBinding. You can disable these if you manage them externally. The node ServiceAccount name defaults to csi-node-sa.
daemonSet:
serviceAccount:
enabled: true # set to false to skip creating the node SA (DaemonSet will omit serviceAccount when false)
name: "" # optionally override the ServiceAccount name (defaults to "csi-node-sa")
rbac:
enabled: true # set to false to skip creating the node ClusterRoleBinding
When daemonSet.serviceAccount.enabled=false, ensure a ServiceAccount named csi-node-sa exists in the target namespace if you intend to set it explicitly on the DaemonSet yourself.
π Recommendation
Use a custom values.yaml file to override variables to avoid template rendering errors.
2. Using kubectl
π Create a Secret
apiVersion: v1
kind: Secret
metadata:
name: linode
namespace: kube-system
stringData:
token: "your linode api token"
region: "your preferred region"
Apply the secret to the cluster:
kubectl apply -f secret.yaml
Verify the secret was created:
kubectl get secret linode -n kube-system
π Deploy the CSI Driver
Apply the deployment manifest (changes on the main branch):
kubectl apply -f https://raw.githubusercontent.com/linode/linode-blockstorage-csi-driver/master/internal/driver/deploy/releases/linode-blockstorage-csi-driver.yaml
To deploy a specific release version:
kubectl apply -f https://raw.githubusercontent.com/linode/linode-blockstorage-csi-driver/master/internal/driver/deploy/releases/linode-blockstorage-csi-driver-v0.5.3.yaml
π§ Advanced Configuration and Operational Details
-
Storage Classes
- Default Storage Class:
linode-block-storage-retainLearn More- Reclaim Policy:
Retain- Volumes created by this CSI driver will default to using the
linode-block-storage-retainstorage class if one is not specified. Upon deletion of all PersistentVolumeClaims, the PersistentVolume and its backing Block Storage Volume will remain intact. - This behavior can be modified in the
csi-storageclass.yamlsection of the deployment by toggling thestorageclass.kubernetes.io/is-default-classannotation.
- Volumes created by this CSI driver will default to using the
- Reclaim Policy:
- Alternative Storage Class:
linode-block-storage- Reclaim Policy:
Delete- This policy will delete the volume when the PersistentVolumeClaim (PVC) or PersistentVolume (PV) is deleted.
- Reclaim Policy:
You can verify the storage classes with:
kubectl get storageclass - Default Storage Class:
-
Linode Cloud Controller Manager (CCM)
- The deployment assumes that the Linode CCM is initialized and running.
- If you intend to run this on a cluster without the Linode CCM, you must modify the init container script in the
cm-get-linode-id.yamlConfigMap and remove the line containingexit 1.
-
Maximum Volume Attachments
- The Linode Block Storage CSI Driver supports attaching more than 8 volumes for larger Linode instances. The maximum number of attachable volumes (including instance disks) scales with the instance's memory, up to a maximum of 64 attachments.
Instance Type Memory/RAM Max. Volume + Disk Attachments g6-nanode-1 1GB 8 g6-standard-1 2GB 8 g6-standard-2 4GB 8 g6-standard-4 8GB 8 g6-standard-6 16GB 16 g6-standard-8 32GB 32 g6-standard-16 64GB 64 g6-standard-20 96GB 64 g6-standard-24 128GB 64 g6-standard-32 192GB 64 This scaling also applies to dedicated, premium, GPU, and high-memory instance classes. The number of attached volumes is a combination of block storage volumes and instance disks (e.g., the boot disk).
Note: To support this change, block storage volume attachments are no longer persisted across reboots.
-
Offline Volume Resizing
- The CSI driver supports offline volume resizing. This means that the volume must be unmounted from all nodes before resizing.
- To resize a volume, update the
spec.resources.requests.storagefield in the PersistentVolumeClaim (PVC) manifest and apply the changes. - The CSI driver will automatically resize the underlying Linode Block Storage Volume to match the new size specified in the PVC.
- The volume must be unmounted from all nodes before resizing.
It could be unmounted by deleting the pod using the volume or by using the
kubectl delete pod <pod-name>command.
-
Driver Role Configuration
Set the DRIVER_ROLE environment variable to control which CSI components load:
-
controller
- Prerequisite:
LINODE_TOKENmust be defined. - Behavior: Boots the CSI Controller service.
- API: Actively calls the Linode API to provision, attach and manage volumes.
- Prerequisite:
-
nodeserver
- Prerequisite:
LINODE_TOKENnot required. - Behavior: Launches only the NodeServer endpoint.
- API: Operates entirely offlineβno Linode API interactions.
- Prerequisite: