Using HELM Chart to Deploying OpenEBS to an Kubernetes Cluster using Terraform
After having been interested in the pure kubernetes storage management part proposed by HPE : HPE Ezmeral Data Fabric (formerly MapR Data Platform) delivered with their large scale containerized application deployment and management tool : HPE Ezmeral Container Platform,i wanted to test a more lite kubernetes storage solution.
I chose a native kubernetes OpenEBS solution !
This tool provides storage for Kubernetes stateful workloads using Kubernetes itself for storage management. OpenEBS can for example use the storage available on the cluster nodes to create replicated volumes! The architecture of this solution is really interesting because we can see the philosophy of microservices applied to storage. With these 6800 stars on Github, the project already has a good community.
I wanted to continue using Terraform for OpenEBS deployment using the HELM provider
The OpenEBS data plane offers three choices of storage engines: cStor, Jiva, and Local PV.
cStor is the preferred storage engine of OpenEBS. It’s a lightweight and feature-rich storage engine meant for HA workloads like databases. It provides enterprise-grade features including synchronous data replication, snapshots, clones, thin provisioning of data, high resiliency of data, data consistency and on-demand increase of capacity or performance. cStor’s synchronous replication delivers high availability to stateful Kubernetes Deployments with just a single replica. When the stateful application desires the storage to provide high availability of data, cStor is configured to have 3 replicas where data is written synchronously to all the three replicas. Since data is written to multiple replicas, terminating and scheduling a new Pod in a different Node doesn’t result in data loss.
Jiva is the first storage engine that was included in the early versions of OpenEBS. Jiva is the simplest of the available choices, which runs entirely in the user space with standard block storage capabilities such as synchronous replication. Jiva is ideal for smaller applications running on nodes that may not have the option to add additional block storage devices. So, it is not suitable for mission-critical workloads that demand high performance or advanced storage capabilities.
OpenEBS third and simplest storage engine is Local Persistent Volume (Local PV). A Local PV represents a local disk directly attached to a single Kubernetes Node.
For more information on the OpenEBS architecture :
In this post you will see :
- How to deploy OpenEBS with Terraform
- Creating a StoragePool
- Creating a Storage Class
- Provisioning a Persistent Volume Claim
- Deploying a SQL Server instance on an OpenEBS storage
- Restore Database
Prerequisites
Before you get started, you’ll need to have these things:
- Terraform > 0.13.x
- HELM > 3.0.x
- Kubernetes 1.13+ with RBAC enabled
- iSCSI PV support in the underlying infrastructure
- Storage disk available in each workers nodes
- kubernetes config file on Terraform platform (setup path in maint.tf file)
Infra
Initial setup
Clone the repository and install the dependencies:
Usage
Deploy OpenEBS:
If you use the terraform apply command without parameters the default values will be those defined in the variables.tf file.
This will do the following :
- create a namespace
- create a deployment object for OpenEBS
Tear down the whole Terraform plan with :
Resources can be destroyed using the terraform destroy command, which is similar to terraform apply but it behaves as if all of the resources have been removed from the configuration.
Verifying OpenEBS installation
Verify pods:
Wait for some time to see all the pods in the running state in the OpenEBS namespace (dans cette exemple le namespace est epc-openebs) :
The pods epc-openebs-ndm-xxx should be running on all worker nodes or on the nodes that are selected through nodeSelector configuration. This pod is responsible for scanning the host for the block devices that can be used by the applications. As we need to check the devices mount in all the nodes this pod is deployed as a daemonset.
We have a pod named epc-openebs-apiserver-d956f7fc6-h7gxk which acts an API server for all our storage requests.
The pod epc-openebs-ndm-operator-6f94f484b5-nr7n6 relates operations performed on the block device using the methods in data planes.
The OpenEBS operator will deploy each Snapshot-controller and snapshot-provisioner container inside the single pod called snapshot-controller.
Check if they are scheduled on the appropriate nodes by listing the pods through : kubectl get pods -n epc-openebs -o wide
Verify Block Device CRs
NDM daemon set creates a block device CR for each block devices that is discovered on the node with two exceptions
The disks that match the exclusions in ‘vendor-filter’ and ‘path-filter’ The disks that are already mounted in the node
List the block device CRs to verify the CRs are appearing as expected.
In our configuration we have 3 disks of 110 GB available on each workers nodes :
Node cabernet
Node sauvignon
To know which block device CR belongs to which node, check the node label set on the CR by doing the following command :
Now we can create cStor Storage Pools. The cStorStoragePool can be created by specifying the blockDeviceList.
Create a StoragePoolClaim configuration YAML and update the required details.
Create a StoragePoolClaim configuration YAML file called cstor-pool1-config.yaml with the following content. The resources will be shared for all the volume replicas that reside on a pool. The value of these resources can be 2Gi to 4Gi per pool on a given node for better performance. These values can be changed as per the Node configuration for better performance. Refer setting pool policies for more details on the pool policies applicable for cStor.
In the above file, change the following parameters as required.
-
poolType
This field represents how the data will be written to the disks on a given pool instance on a node. Supported values are striped, mirrored, raidz and raidz2.
Note: In OpenEBS, the pool instance does not extend beyond a node. The replication happens at volume level but not at the pool level. See volumes and pools relationship in cStor for a deeper understanding.
-
blockDeviceList
Select the list of selected unclaimed blockDevice CRs which are unmounted and does not contain a filesystem in each participating nodes and enter them under blockDeviceList.
To get the list of blockDevice CRs, use kubectl get blockdevice -n epc-openebs.
You must enter all selected blockDevice CRs manually together from the selected nodes.
When the poolType = mirrored , ensure the number of blockDevice CRs selected from each node are an even number. The data is striped across mirrors. For example, if 4x1TB blockDevice are selected on node1, the raw capacity of the pool instance of cstor-disk-pool on node1 is 2TB.
When the poolType = striped, the number of blockDevice CRs from each node can be in any number. The data is striped across each blockDevice. For example, if 4x1TB blockDevices are selected on node1, the raw capacity of the pool instance of cstor-disk-pool on that node1 is 4TB.
When the poolType = raidz, ensure that the number of blockDevice CRs selected from each node are like 3,5,7 etc. The data is written with single parity. For example, if 3x1TB blockDevice are selected on node1, the raw capacity of the pool instance of cstor-disk-pool on node1 is 2TB. 1 disk will be used as a parity disk.
When the poolType = raidz2, ensure that the number of blockDevice CRs selected from each node are like 6,8,10 etc. The data is written with dual parity. For example, if 6x1TB blockDevice are selected on node1, the raw capacity of the pool instance of cstor-disk-pool on node1 is 4TB. 2 disks will be used for parity.
The number of selected blockDevice CRs across nodes need not be the same. Unclaimed blockDevice CRs which are unmounted on nodes and does not contain any filesystem can be added to the pool spec dynamically as the used capacity gets filled up.
-
type
This value can be either sparse or disk. If you are creating a sparse pool using the sparse disk based blockDevice which are created as part of applying openebs operator YAML, then choose type as sparse. For other blockDevices, choose type as disk.
Now execute the above yaml file using the below-mentioned command
Verify if cStor Pool is created successfully using the following command.
Verify if cStor pool pods are running using the following command.
Create a StorageClasses:
StorageClass definition is an important task in the planning and execution of OpenEBS storage.
You can create a new StorageClass YAML called openebs-sc-student1.yaml and add content to it from below. By using this spec, a StorageClass (openebs-sc-student1) will be created with 2 OpenEBS cStor replicas and will configure them on the pools associated with the StoragePoolClaim:cstor-disk-pool. Refer setting storage policies for more details on Storage Policies.
Now execute the above yaml file using the below-mentioned command
Verify if storageclass : openebs-sc-student1 is created successfully using the following command.
Deployment of a database instance
We will use our Terraform Microsoft SQL Server 2019 Linux deployment plan described in the following post : Deploying Microsoft SQL Server 2019 Linux to an Kubernetes Cluster using Terraform To deploy Microsoft SQL Server on our OpenEBS storage. We will provision a Persistent Volume Claim (PVC): pvc-mssqldata01-student1 with our storage class : openebs-sc-student1
Create a MS SQL Server instance:
Check if your SQL Server instance works:
Our PVC is well created if our pods are running …
Perform the following command to get the details of the replicas of corresponding cStor volume:
Check connexion to Microsoft SQL Server instance
To access the SQL Server Instance you’ll need to find its port map :
In our deployment for the service we used the NodePort directive and port 1433 is mapped externally to port 30561. We can access our instance by specifying the name (or ip address) of one of the cluster nodes and port 30561.
You can connect to the SQL Server instance outside the Kubernetes cluster with command line :
we will now restore a database :
- STEP 1: Get POD Name :
- STEP 2: create a backup folder :
- STEP 3: Copy data backup files :
Check if files are copied.we must have 2 files: restorewide.sql and WideWorldImporters-Full.bak
- STEP 4: Now now we can restore our Database
After a few seconds the database is restored
- STEP 5: Verify the restored database
Perform the following command to get the details of the replicas of corresponding cStor volume: we can notice that the space used has increased and that it is synchronous on the second replica (due to the restoration of the database).
Conclusion
Terraform makes it easy to manage Kubernetes clusters and Kubernetes resources effectively. It gives organizations the opportunity to work with infrastructure-as-code, management of platforms, and also the opportunity to create modules for self-service infrastructure. Terraform Kubernetes provider gives organizations all the required tools necessary to manage Kubernetes clusters in the environment.
OpenEBS extends the benefits of software-defined storage to cloud native through the container attached storage approach. It represents a modern, contemporary way of dealing with storage in the context of microservices and cloud native applications.
Next step
Using Volume Snapshot and Clone of a cStor Volume in OpenEBS
Resources :
OpenEBS Helm Chart Documentation