Get Started
Learn about the ways to get started with Piraeus Datastore by deploying Piraeus Operator and provisioning your first volume.
Prerequisites
1: Install Piraeus Operator
In this tutorial we will be using kubectl
with the built-in kustomize
feature to deploy Piraeus Operator.
All resources needed to run Piraeus Operator are included in a single Kustomization.
Install Piraeus Operator by running:
$ kubectl apply --server-side -k "https://github.com/piraeusdatastore/piraeus-operator//config/default?ref=v2.7.0"
namespace/piraeus-datastore configured
...
The Piraeus Operator will be installed in a new namespace piraeus-datastore
. After a short wait the operator will be
ready. The following command waits until the Operator is ready:
$ kubectl wait pod --for=condition=Ready -n piraeus-datastore -l app.kubernetes.io/component=piraeus-operator
pod/piraeus-operator-controller-manager-dd898f48c-bhbtv condition met
2: Deploy Piraeus Datastore
Now, we will deploy Piraeus Datastore using a new resource managed by Piraeus Operator. We create a LinstorCluster
,
which creates all the necessary resources (Deployments, Pods, and so on...) for our Datastore:
$ kubectl apply -f - <<EOF
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec: {}
EOF
Again, all workloads will be deployed to the piraeus-datastore
namespace. After a short wait the Datastore will ready:
$ kubectl wait pod --for=condition=Ready -n piraeus-datastore -l app.kubernetes.io/name=piraeus-datastore
pod/linstor-controller-65cbbc74db-9vm9n condition met
pod/linstor-csi-controller-5ccb7d84cd-tvd9h condition met
pod/linstor-csi-node-2lkpd condition met
pod/linstor-csi-node-hbcvv condition met
pod/linstor-csi-node-hmrd7 condition met
pod/n1.example.com condition met
pod/n2.example.com condition met
pod/n3.example.com condition met
pod/piraeus-operator-controller-manager-dd898f48c-bhbtv condition met
We can now inspect the state of the deployed LINSTORĀ® Cluster using the linstor
client:
$ kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor node list
+-------------------------------------------------------------------+
| Node | NodeType | Addresses | State |
|===================================================================|
| n1.example.com | SATELLITE | 10.116.72.166:3366 (PLAIN) | Online |
| n2.example.com | SATELLITE | 10.127.183.190:3366 (PLAIN) | Online |
| n3.example.com | SATELLITE | 10.125.97.33:3366 (PLAIN) | Online |
+-------------------------------------------------------------------+
3: Configuring Storage
We have not yet configured any storage location for our volumes. This can be accomplished by creating a new
LinstorSatelliteConfiguration
resource. We will create a storage pool of type fileThinPool
on each node.
We chose fileThinPool
as it does not require further configuration on the host.
$ kubectl apply -f - <<EOF
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: storage-pool
spec:
storagePools:
- name: pool1
fileThinPool:
directory: /var/lib/piraeus-datastore/pool1
EOF
This will cause some Pods to be recreated. While this occurs linstor node list
will temporarily show offline nodes:
$ kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor node list
+--------------------------------------------------------------------+
| Node | NodeType | Addresses | State |
|====================================================================|
| n1.example.com | SATELLITE | 10.116.72.166:3366 (PLAIN) | OFFLINE |
| n2.example.com | SATELLITE | 10.127.183.190:3366 (PLAIN) | OFFLINE |
| n3.example.com | SATELLITE | 10.125.97.33:3366 (PLAIN) | OFFLINE |
+--------------------------------------------------------------------+
Waiting a bit longer, the nodes will be Online
again. Once the nodes are connected again, we can verify that
the storage pools were configured:
$ kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor storage-pool list
+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| StoragePool | Node | Driver | PoolName | FreeCapacity | TotalCapacity | CanSnapshots | State | SharedName |
|=========================================================================================================================================================|
| DfltDisklessStorPool | n1.example.com | DISKLESS | | | | False | Ok | |
| DfltDisklessStorPool | n2.example.com | DISKLESS | | | | False | Ok | |
| DfltDisklessStorPool | n3.example.com | DISKLESS | | | | False | Ok | |
| pool1 | n1.example.com | FILE_THIN | /var/lib/piraeus-datastore/pool1 | 24.54 GiB | 49.30 GiB | True | Ok | |
| pool1 | n2.example.com | FILE_THIN | /var/lib/piraeus-datastore/pool1 | 23.03 GiB | 49.30 GiB | True | Ok | |
| pool1 | n3.example.com | FILE_THIN | /var/lib/piraeus-datastore/pool1 | 26.54 GiB | 49.30 GiB | True | Ok | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------+
4: Using Piraeus Datastore
We now have successfully deployed and configured Piraeus Datastore, and are ready to create our first
PersistentVolume
in Kubernetes.
First, we will set up a new StorageClass
for our
volumes. In the StorageClass
, we specify the storage pool from above:
$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: piraeus-storage
provisioner: linstor.csi.linbit.com
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
parameters:
linstor.csi.linbit.com/storagePool: pool1
EOF
Next, we will create a PersistentVolumeClaim
,
requesting 1G of storage from our newly created StorageClass
.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-volume
spec:
storageClassName: piraeus-storage
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteOnce
EOF
When we check the created PersistentVolumeClaim, we can see that it remains in Pending
state.
$ kubectl get persistentvolumeclaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-volume Pending piraeus-storage 14s
We first need to create a "consumer", which in this case is just a Pod
. For our consumer, we will create a Deployment
for a simple web server, serving files from our volume.
$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app.kubernetes.io/name: web-server
template:
metadata:
labels:
app.kubernetes.io/name: web-server
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-volume
EOF
After a short wait, the Pod is Running
, and our PersistentVolumeClaim
is now Bound
:
$ kubectl wait pod --for=condition=Ready -l app.kubernetes.io/name=web-server
pod/web-server-84867b5449-hgdzx condition met
$ kubectl get persistentvolumeclaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-volume Bound pvc-9e1149e7-33db-47a7-8fc6-172514422143 1Gi RWO piraeus-storage 1m
Checking the running container, we see that the volume is mounted where we expected it:
$ kubectl exec deploy/web-server -- df -h /usr/share/nginx/html
Filesystem Size Used Avail Use% Mounted on
/dev/drbd1000 973M 24K 906M 1% /usr/share/nginx/html
Taking a look with the linstor
client, we can see that the volume is listed in LINSTOR and marked as InUse
by the
Pod.
$ kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor resource list-volumes
+-------------------------------------------------------------------------------------------------------------------------------------------+
| Node | Resource | StoragePool | VolNr | MinorNr | DeviceName | Allocated | InUse | State |
|===========================================================================================================================================|
| n1.example.com | pvc-9e1149e7-33db-47a7-8fc6-172514422143 | pool1 | 0 | 1000 | /dev/drbd1000 | 16.91 MiB | InUse | UpToDate |
+-------------------------------------------------------------------------------------------------------------------------------------------+
We have now successfully set up Piraeus Datastore and used it to provision a Persistent Volume in a Kubernetes cluster.