Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to configure persistent storage with OpenShift or Kubernetes for development environment

October 26, 2017
Chandra Shekhar Pandey
Related topics:
CI/CDContainersDeveloper ToolsDevOpsKubernetesMicroservices
Related products:
Red Hat FuseStreams for Apache KafkaRed Hat OpenShiftRed Hat OpenShift Container PlatformRed Hat Enterprise Linux

Share:

    • 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. Hence if an application or container is rebuilt or restarted than we can't view previous logs or if we are using containers with mysql or any other database then schema, tables, and all data will be lost, if using any messaging broker than if there is journal file than it will also not persist.
      Hence, these ephemeral containers cannot be used in production environment. In a production environment, we must configure a shared storage.
    • But what about the development environment, because we might not always have enough labs and VM's available. To rescue we have volume type hostPath, which can be easily set up with Minishift and Minikube.
    • This article will provide details how to setup hostPath volume type.

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

    apiVersion: v1
     kind: PersistentVolume
     metadata:
     name: pv0002
     spec:
     accessModes:
     - ReadWriteOnce
     capacity:
     storage: 500Mi
     hostPath:
     path: /data/pv0002/
    •  Above we have created pv0002 Persistent Volume. With a specification like accessModes, capacity, and hostPath.
    • In OpenShift we can easily create PersistentVolume with the command,
    oc create -f pv.yaml
    • To view all configured persistent volume, run the command below,
    oc get pv

    2. 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

    3. 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 below configuration. Using below configuration, we can have a mysql container, which 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 PersistentVolumeClaim mysql-pv-claim, which should bind to volume pv0002.
    • We are creating a Deployment mysql, with the environment variable MYSQL_ROOT_PASSWORD and mountPath /var/lib/mysql which mounts to persistentVolumeClaim mysql-pv-claim. We know persistentVolumeClaim is referring to /data/pv0002/, we have defined this path in persistent volume pv0002.

    4. Deploy the yaml content: We can run this yaml as

    oc create -f mysql-deployment.yaml

    5.  Check if pv and pvc are bound: We can get details of persistentvolume and persistentvolumeclaim as

    [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 mysql service is up and running on port 3306 port.

    6. Now if we again ssh to minishift. We will find files created within /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

    7. Access mysql pod: Below we can access mysql pod. Here note that database csp and table testtable was 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)

    8. Verify if data persists: Now let us delete the current running pod and check if 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.

    Last updated: November 2, 2023

    Recent Posts

    • Expand Model-as-a-Service for secure enterprise AI

    • OpenShift LACP bonding performance expectations

    • Build container images in CI/CD with Tekton and Buildpacks

    • How to deploy OpenShift AI & Service Mesh 3 on one cluster

    • JVM tuning for Red Hat Data Grid on Red Hat OpenShift 4

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue