Introduction
Understand how OpenEBS provides Kubernetes-native persistent storage on Azure
Create an Arm64 virtual machine powered by Azure Cobalt 100
Deploy OpenEBS on an Arm-based virtual machine
Validate persistent storage with OpenEBS on an Arm-based virtual machine
Allow access to the OpenEBS application on Azure
Next Steps
In this section, you’ll install OpenEBS LocalPV using a lightweight single-node Kubernetes cluster on the virtual machine (VM) that you created in the previous section.
You’ll configure Kubernetes storage provisioning and prepare the environment for persistent workloads.
Start by updating the package index and installing the latest package updates on the virtual machine.
sudo apt update && sudo apt upgrade -y
Install the tools required for Kubernetes and Helm setup.
sudo apt install -y curl wget git apt-transport-https
K3s is a lightweight Kubernetes distribution optimized for edge systems, Arm64 environments, and single-node deployments.
Run the following command to install K3s:
curl -sfL https://get.k3s.io | sh -
Verify the installation:
sudo kubectl get nodes
The output is similar to:
NAME STATUS ROLES AGE VERSION
openebs-arm64 Ready control-plane 7s v1.35.5+k3s1
Create the Kubernetes configuration directory:
mkdir -p ~/.kube
Copy the K3s kubeconfig file:
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
Update ownership permissions:
sudo chown $USER:$USER ~/.kube/config
Set the Kubernetes configuration environment variable:
export KUBECONFIG=$HOME/.kube/config
Persist the configuration:
echo 'export KUBECONFIG=$HOME/.kube/config' >> ~/.bashrc
source ~/.bashrc
Verify access:
kubectl get nodes
The output is similar to:
NAME STATUS ROLES AGE VERSION
openebs-arm64 Ready control-plane 62s v1.35.5+k3s1
Helm is the Kubernetes package manager used to deploy OpenEBS.
Install Helm:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Verify that Helm installed successfully:
helm version
The output is similar to:
version.BuildInfo{Version:"v3.21.0", GitCommit:"e0878d41b711792be60777fd65ad23a101e6b85f", GitTreeState:"clean", GoVersion:"go1.25.10"}
Add the official OpenEBS Helm repository:
helm repo add openebs https://openebs.github.io/openebs
After adding the OpenEBS repository, update Helm repositories:
helm repo update
The output is similar to:
...Successfully got an update from the "openebs" chart repository
Update Complete. ⎈Happy Helming!⎈
Create the openebs namespace that will hold all OpenEBS components.
kubectl create namespace openebs
Install OpenEBS LocalPV components and disable Mayastor, Loki, Alloy, and observability services, which are unnecessary for a single-node setup:
The following command installs the latest available OpenEBS chart. To pin to a specific version, add --version <version> to the command. To find available versions, run helm search repo openebs/openebs --versions.
helm install openebs openebs/openebs \
--namespace openebs \
--set engines.replicated.mayastor.enabled=false \
--set loki.enabled=false \
--set alloy.enabled=false \
--set obs.enabled=false
OpenEBS components take a moment to start. Wait for the pods to become ready before continuing:
kubectl wait --for=condition=Ready pod -l app=openebs-localpv-provisioner -n openebs --timeout=120s
Then check whether all OpenEBS pods are running:
kubectl get pods -n openebs
The output is similar to:
NAME READY STATUS RESTARTS AGE
openebs-localpv-provisioner-6f9447fcc9-nnbgm 1/1 Running 0 17s
openebs-lvm-localpv-controller-5996c4fbfc-d8274 5/5 Running 0 17s
openebs-lvm-localpv-node-9g49t 2/2 Running 0 17s
openebs-zfs-localpv-controller-6b98b6cc9d-rjq76 5/5 Running 0 17s
openebs-zfs-localpv-node-p28g2 2/2 Running 0 17s
Check the available Kubernetes storage classes:
kubectl get sc
The output is similar to:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 2m16s
openebs-hostpath openebs.io/local Delete WaitForFirstConsumer false 32s
Remove the default flag from the K3s local-path storage class:
kubectl patch storageclass local-path \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
Set OpenEBS HostPath as the default storage class:
kubectl patch storageclass openebs-hostpath \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Verify that the configuration commands worked:
kubectl get sc
The output is similar to:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path rancher.io/local-path Delete WaitForFirstConsumer false 2m55s
openebs-hostpath (default) openebs.io/local Delete WaitForFirstConsumer false 71s
Check all OpenEBS resources:
kubectl get all -n openebs
At this stage, OpenEBS LocalPV is successfully configured and ready to provision persistent storage volumes for Kubernetes workloads.
You’ve now created a lightweight single-node Kubernetes cluster running on an Arm64 virtual machine powered by Azure Cobalt 100. You’ve configured OpenEBS LocalPV as the default storage class.
Next, you’ll create a PersistentVolumeClaim (PVC), deploy a stateful NGINX application, and validate data persistence.