Skip to main content
Simplyblock is a distributed software-defined storage engine that provides high-performance block storage for Kubernetes and other platforms. Storage is provided through NVMe over TCP or NVMe over RDMA (RoCEv2). It is composed of three main components: The control plane provides the management layer. It exposes the management API and tooling, handles cluster and volume lifecycle workflows, and keeps the metadata and orchestration state required to operate the platform. The storage plane provides the data layer. It runs the storage nodes that serve I/O and expose logical volumes, and it is where scale-out capacity and performance are delivered. The CSI driver is the Kubernetes integration layer. It maps Kubernetes storage operations, such as provisioning and attaching volumes, to Simplyblock control-plane actions and coordinates node-side publishing so pods can consume storage. Simplyblock is a highly versatile storage platform that can be deployed on Kubernetes and other platforms. That means that not all components must be installed on Talos. In this guide, we will focus on a full installation of simplyblock into Talos. For all options, see the simplyblock documentation.

Prerequisites

Installing simplyblock into Talos requires the minimum version of Kubernetes to be v1.26 or later, Talos v1.11.0 or later, and Helm v3.12.0 or later. Furthermore, simplyblock requires exclusive access to empty, unpartitioned, and unformatted NVMe devices as the storage backend. The simplyblock-managed NVMe devices of all storage nodes are combined into a shared pool.

Install Simplyblock Control Plane into Talos

Install the sbctl CLI:
pip install sbctl --upgrade
Find the Helm chart bundled with sbctl, then deploy the control plane:
CHART_DIR="$(python3 -c 'import simplyblock_core, pathlib; print(pathlib.Path(simplyblock_core.__file__).parent / "scripts/charts")')"
cd "${CHART_DIR}"
helm dependency build ./
helm upgrade --install simplyblock-cp \
  --namespace simplyblock --create-namespace ./
Create the simplyblock cluster from the admin control pod:
kubectl -n simplyblock exec -it \
  simplyblock-admin-control-<UUID> -- bash
sbctl cluster create --mgmt-ip <WORKER_IP> \
  --ha-type ha --mode kubernetes
If you want to use a load balancer for the Management API endpoint (highly recommended for highly available production environments), include:
--ingress-host-source loadbalancer --dns-name <LB_INGRESS_DNS>

Install Simplyblock Storage Plane into Talos

Before installing the simplyblock storage plane on Talos, you must prepare Talos worker nodes with the required kernel modules, huge page allocation, and namespace security settings.

Load required kernel modules on Talos worker nodes

Create a machine configuration patch (for example kernel-module-config.yaml):
machine:
  kernel:
    modules:
      - name: nbd
      - name: uio_pci_generic
      - name: vfio_pci
      - name: vfio_iommu_type1
Apply the patch to the worker nodes:
talosctl patch mc --nodes <WORKER_NODE_IP> \
  --patch @kernel-module-config.yaml

Reserve huge pages on Talos worker nodes

Simplyblock requires pre-reserved huge pages and expects the hugepages-2Mi pool (2 MiB page size). The required amount depends on your planned storage-node sizing (for example, CPU count, number of volumes, and expected provisioned capacity per node), so decide the target huge page memory first, then convert it into page count. To calculate the required huge pages, run the following commands to exec into a simplyblock control plane pod and run the calculation:
kubectl -n simplyblock exec -it \
  simplyblock-admin-control-<UUID> -- bash
sbctl storage-node configure \
  --calculate-hp-only \
  --max-lvol <MAX_LVOL> \
  --number-of-devices <NUMBER_OF_DEVICES>
Optional flags that also affect the result:
  • --nodes-per-socket (default: 1)
  • --sockets-to-use (default: 0)
  • --cores-percentage (default: 0 / unset)
Use the The required number of huge pages on this host is: ... value from the command output as your vm.nr_hugepages setting. Use this conversion:
  • nr_hugepages = (target_hugepage_memory_in_MiB) / 2
  • Example: 8192 MiB of huge page memory requires 4096 pages.
Round up to avoid under-allocation. If your sizing output is fractional, always choose the next whole page count. Create a machine configuration patch (for example huge-pages-config.yaml):
machine:
  sysctls:
    vm.nr_hugepages: "<NUMBER_OF_PAGES>"
Apply it with a reboot to activate the reservation, then restart kubelet:
talosctl patch mc --nodes <WORKER_NODE_IP> \
  --patch @huge-pages-config.yaml
talosctl reboot --nodes <WORKER_NODE_IP>
Verify the reservation from Kubernetes:
kubectl describe node <WORKER_NODE_NAME> | grep hugepages-2Mi
You should see non-zero Capacity/Allocatable values for hugepages-2Mi.

Create a privileged namespace for Simplyblock

Simplyblock components (storage plane and CSI driver) require privileged execution on Talos worker nodes because they need host-level storage access that is blocked in restricted namespaces. This includes native access to NVMe devices, establishing and managing NVMe/TCP multipathing sessions, and performing required block-device operations such as discovery, attach, format, and mount for Kubernetes volumes. Create simplyblock-namespace.yaml:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: simplyblock
  labels:
    pod-security.kubernetes.io/enforce: privileged
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/audit: privileged
    pod-security.kubernetes.io/audit-version: latest
    pod-security.kubernetes.io/warn: privileged
    pod-security.kubernetes.io/warn-version: latest
EOF

Installation via Helm Chart

Inside the control plane pod, retrieve the cluster UUID and secret:
kubectl -n simplyblock exec -it \
  simplyblock-admin-control-<UUID> -- bash
sbctl cluster list
sbctl cluster get-secret <CLUSTER_UUID>
And create a storage pool. The storage pool is a logical grouping for logical volumes.
sbctl pool add <POOL_NAME> <CLUSTER_UUID>
Label Talos nodes that should run simplyblock storage nodes:
kubectl label nodes <NODE_NAME> \
  io.simplyblock.node-type=simplyblock-storage-plane
Install storage plane nodes (and CSI) via Helm:
CLUSTER_UUID="<UUID>"
CLUSTER_SECRET="<SECRET>"
CNTR_ADDR="<CONTROL-PLANE-ADDR>"
POOL_NAME="<POOL-NAME>"
Install the helm chart
helm repo add simplyblock-csi https://install.simplyblock.io/helm/csi
helm repo update

helm upgrade --install simplyblock -n simplyblock \
  --create-namespace \
  simplyblock-csi/spdk-csi \
  --set csiConfig.simplybk.uuid=${CLUSTER_UUID} \
  --set csiConfig.simplybk.ip=${CNTR_ADDR} \
  --set csiSecret.simplybk.secret=${CLUSTER_SECRET} \
  --set logicalVolume.pool_name=${POOL_NAME} \
  --set storagenode.create=true
Verify pods:
kubectl --namespace=simplyblock get pods \
  --selector="release=simplyblock-csi" --watch

Install Simplyblock CSI Driver into Talos

If you installed the storage plane into Talos, the CSI driver is already deployed as part of the storage plane. If you want to connect to an external simplyblock storage cluster, install the CSI driver manually as described below. For CSI driver-only installations, no huge page reservation is required. Install the CSI driver only:
CLUSTER_UUID="<UUID>"
CLUSTER_SECRET="<SECRET>"
CNTR_ADDR="<CONTROL-PLANE-ADDR>"
POOL_NAME="<POOL-NAME>"
Install the helm chart
helm repo add simplyblock-csi https://install.simplyblock.io/helm/csi
helm repo update

helm upgrade --install simplyblock -n simplyblock \
  --create-namespace \
  simplyblock-csi/spdk-csi \
  --set csiConfig.simplybk.uuid=${CLUSTER_UUID} \
  --set csiConfig.simplybk.ip=${CNTR_ADDR} \
  --set csiSecret.simplybk.secret=${CLUSTER_SECRET} \
  --set logicalVolume.pool_name=${POOL_NAME}
Verify CSI controller/node pods:
kubectl --namespace=simplyblock get pods \
  --selector="release=simplyblock-csi"

Cleaning up Simplyblock

To remove simplyblock from the cluster, uninstall the Helm releases first, then clean up any remaining namespace resources. Uninstall the storage plane and CSI driver chart:
helm uninstall simplyblock -n simplyblock
If you installed the control plane with Helm as simplyblock-cp, uninstall it as well:
helm uninstall simplyblock-cp -n simplyblock
Check for leftovers in the namespace:
kubectl get all -n simplyblock
kubectl get pvc,pv,secret,configmap,sa,role,rolebinding -n simplyblock
If resources remain, delete them before removing the namespace:
kubectl delete all --all -n simplyblock
kubectl delete pvc --all -n simplyblock
kubectl delete secret,configmap,sa,role,rolebinding --all -n simplyblock
Finally, remove the namespace:
kubectl delete namespace simplyblock

References