Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Persistent Storage With OpenShift or Kubernetes

DZone's Guide to

Persistent Storage With OpenShift or Kubernetes

As useful as containers are, data persistence is a challenge. Here is how to configure MySQL containers to persist data for OpenShift and Kubernetes in Dev environments.

· Cloud Zone ·
Free Resource

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

We know that containers in OpenShift or Kubernetes don’t persist data. Every time we start an application, it is started in a new container with an immutable Docker image. Hence, any persisted data in the file systems is lost when the container stops. If an application or container is rebuilt or restarted, we can’t view previous logs. If we are using containers with MySQL or any other database, then schema, tables, and all data will be lost. If we are using any messaging broker, then if there is a journal file, it will also not persist.

Hence, these ephemeral containers cannot be used in a production environment. In a production environment, we must configure shared storage.

But what about the development environment — because we might not always have enough labs and VMs available? To the rescue, we have the volume type hostPath, which can be easily set up with Minishift and Minikube.

This article will provide details of how to set up the hostPath volume type.

PersistentVolumes

We have to configure a PersistentVolume. We can create a pv.yaml file like this:

apiVersion: v1
kind: PersistentVolume
metadata: null
name: pv0002
spec: null
accessModes:
  - ReadWriteOnce
capacity: null
storage: 500Mi
hostPath: null
path: /data/pv0002/


  • Above, we have created a pv0002 PersistentVolume with a specification like accessModes, capacity, and hostPath.
  • In OpenShift, we can easily create a PersistentVolume with the command:
oc create -f pv.yaml


  • To view all configured PersistentVolumes, run the command below:
oc get pv


Check HostPath Privileges

It needs elevated privileges to read and write from hostpath /data/pv0002. So we would have to first ssh to the host machine (which is a minishift virtual machine) then set the privileges so that all users can read/write.

minishift ssh
 
docker@minishift:~$ id
uid=1000(docker) gid=50(staff) groups=50(staff),100(docker)
 
docker@minishift:~$ pwd
/home/docker
 
docker@minishift:~$ cd /data
 
docker@minishift:~$ sudo chmod -R 777 pv0002
 
docker@minishift:/mnt/sda1/data$ ls -ltr|grep pv0002
drwxrwxrwx 5 root root 4096 Oct 18 07:41 pv0002/
 
docker@minishift:/mnt/sda1/data$ pwd
/data


PersistentVolumeClaims

To access this storage from Projects, PersistentVolumeClaims must be created that can access the PersistentVolume. PersistentVolumeClaims are created for each Project with customized claims for a certain amount of storage with certain access modes. We can create another YAML (mysql-deployment.yaml) file with the following configuration. Using this configuration, we can have a MySQL container that would also persist the data. This is a reference from this link.

apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
    - port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
    - ReadWriteOnce
resources:
requests:
storage: 300Mi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
    - image: mysql:5.6
name: mysql
env:
# Use secret in real usage
    - name: MYSQL_ROOT_PASSWORD
value: password
ports:
    - containerPort: 3306
name: mysql
volumeMounts:
    - name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
    - name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim


Points to note above:

  • We are creating a service: mysql.
  • We are creating a PersistentVolumeClaimmysql-pv-claim, which should bind to volume pv0002.
  • We are creating a Deploymentmysql, with the environment variable MYSQL_ROOT_PASSWORD and mount path /var/lib/mysql, which mounts to persistentVolumeClaimmysql-pv-claim. We know persistentVolumeClaim is referring to /data/pv0002/ — we have defined this path in pv0002.

Deploy the YAML Content

We can run this YAML as:

oc create -f mysql-deployment.yaml


Check if pv and pvc Are Bound

We can get the details of persistentvolume and persistentvolumeclaim via:

[cpandey@cpandey minishit_persistence_host]$ oc get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
mysql-pv-claim Bound pv0002 500Mi RWO 1d
 
[cpandey@cpandey minishit_persistence_host]$ oc get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE
pv0002 500Mi RWO Retain Bound myproject/mysql-pv-claim 1d
 
[cpandey@cpandey minishit_persistence_host]$ oc get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql None none 3306/TCP 1d


  • Above, we find that pv0002 is bound and claimed by mysql-pv-claim.
  • Also, we see that the MySQL service is up and running on port 3306.

ssh to minishift

Now, if we again ssh to minishift, we will find files created within the /data/pv0002 hostpath.

docker@minishift:~$ cd /data/pv0002
 
docker@minishift:/mnt/sda1/data/pv0002$ ls -ltr
total 110608
-rw-rw---- 1 10000400 root 50331648 Oct 17 03:51 ib_logfile1
drwx------ 2 10000400 root 4096 Oct 17 03:51 performance_schema/
-rw-rw---- 1 10000400 root 56 Oct 17 03:51 auto.cnf
drwx------ 2 10000400 root 4096 Oct 17 03:51 mysql/
drwx------ 2 10000400 root 4096 Oct 17 03:55 csp/
-rw-rw---- 1 10000400 root 12582912 Oct 18 07:41 ibdata1
-rw-rw---- 1 10000400 root 50331648 Oct 18 07:42 ib_logfile0


Access the MySQL Pod

Below we can access the MySQL pod. Note that database csp and table testtable were created manually on the first run.

[cpandey@cpandey minishit_persistence_host]$ oc get pods
NAME READY STATUS RESTARTS AGE
mysql-63082529-66jyn 1/1 Running 1 1d
  
[cpandey@cpandey minishit_persistence_host]$ oc rsh mysql-63082529-66jyn
$ mysql -u root -ppassword
  
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| csp |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)
 
mysql> use csp;
Database changed
 
mysql> show tables;
+---------------+
| Tables_in_csp |
+---------------+
| testtable |
+---------------+
1 row in set (0.00 sec)
 
mysql> select * from testtable;
Empty set (0.00 sec)


Verify Whether the Data Persists

Now let us delete the current running pod and check if the mysql DB and tables still exist.

[cpandey@cpandey minishit_persistence_host]$ oc delete pod mysql-63082529-66jyn
pod "mysql-63082529-66jyn" deleted
 
[cpandey@cpandey minishit_persistence_host]$ oc get pods
NAME READY STATUS RESTARTS AGE
mysql-63082529-66jyn 1/1 Terminating 1 1d
mysql-63082529-q7e5n 1/1 Running 0 4s
 
[cpandey@cpandey minishit_persistence_host]$ oc get pods
NAME READY STATUS RESTARTS AGE
mysql-63082529-q7e5n 1/1 Running 0 14s
 
[cpandey@cpandey minishit_persistence_host]$ oc rsh mysql-63082529-q7e5n
$ mysql -u root -ppassword
 
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| csp |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)
 
mysql> use csp;
 
mysql> show tables;
+---------------+
| Tables_in_csp |
+---------------+
| testtable |
+---------------+
1 row in set (0.00 sec)


This way, we can easily configure persistence even in our development environment, which is mostly minishift or minikube.

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

Topics:
cloud ,development environment ,persistent storage ,openshift ,kubernetes

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}