Around the Storage Block

How to: Persistent Volumes with the HPE 3PAR Volume Plug-in for Docker - Volume Provisioning: Part 1

How to: Persistent Volumes using HPE 3PAR Volume Plug-in for Docker

A detailed guide – Part 1 – Volume provisioning

I have been planning on covering this topic for a while now after feedback from several customers. With so many features available from the HPE 3PAR Volume Plug-in for Docker, many have asked,

"How do I do X, Y, or Z using the 3PAR plug-in within Docker? and then how do I take that and use it within a Storage Class for Kubernetes?"

I think we often try to show examples of cool integrations and large deployments, and forget that the vast majority of the day-to-day tasks are simple, like creating a basic volume with various features, snapshots or clones of existing production data, replicating volumes between sites to name a few. The purpose of this post is to cover these scenarios because when you have a good foundation, scaling these workflows into larger continuous integration and deployment (CI/CD) pipelines becomes much easier.

If you are already comfortable with volume provisioning, you can skip ahead to my next post that covers how to use the HPE 3PAR Volume Plug-in for Docker to create snapshots and cloned volumes in Docker and Kubernetes.

How to: Persistent Volumes using HPE 3PAR Volume Plug-in for Docker - Snapshots/Clones - Part 2

I created several posts and videos on various topic that I highly recommend looking over for more in depth coverage.

So let’s get to it. As with all of my blogs, the expectation is that you are familiar with container technology and the commands and objects for Docker and Kubernetes.

To get started, the best place to find all of the supported Docker commands for the HPE 3PAR Volume Plug-in is found on the official Github page:

If you have the HPE 3PAR Volume Plug-in installed, you can also get access to the help file by using the help switch.





$ docker volume create -d hpe --help





Here are some of supported parameters HPE 3PAR Volume Plug-in for Docker that you can use during volume creation:

  • size- specifies the desired size in GB of the volume. (100 GB default)
  • provisioning - specifies the type of provisioning (thin, full, dedup)
  • compression - enables or disabled compression on the volume
  • cpg- name of user CPG to be used
  • snapcpg- name of snapshot CPG to be used.
    • Note:if snapcpg option is not explicitly specified, then the snapshot CPG takes the value of the cpg
  • replicationGroup – name of Remote Copy Group
  • fsOwneruser ID and group ID of owner of file system
  • fsModepermissions of the root directory of file system
  • backendbackend to be used for the volume creation


Basic Volume Provisioning

As we move into some of the examples, the first example will be the Docker command. Then I give a corresponding example of a Kubernetes Storage Class using the same parameters. This will help you be able to translate between the two.


To provision a volume with Docker, start with the basic docker volume create command





$ docker volume create





Then specify the 3PAR driver.





$ docker volume create –d hpe





Then specify a volume name.





$ docker volume create –d hpe --name <volume_name>





You can leave it at that and a simple 100 GB volume will be created on the 3PAR array and available to Docker. Or you can fine tune the volume to your specific needs using the various volume options that are available.

Let’s create a full provisioned, 250 GB volume using SSD.





$ docker volume create -d hpe --name <volume_name> -o size=250 -o provisioning=full -o cpg=SSD_r6





As you can see, it is just a matter of specifying the optional parameters along with the volume create command and the plug-in will create a volume for you.

To use the new volume, mount the volume in a container. For example, I mount the volume in an Ubuntu container image using the following command.





$ docker run -it -v <volume_name>:/data1 --rm --volume-driver hpe ubuntu bash






Kubernetes Storage Class

Now let’s take this same example and use it within a Storage Class for Kubernetes.

A StorageClass provides a way for administrators to describe the “classes” of storage they offer. You can create multiple Storage Classes (i.e. Gold, Silver and Bronze Storage Class) with particular storage parameters that meet your application needs. This helps drive consistency and control within your CI/CD pipelines.

I have added a number of these examples on our Github page.

Let’s get started with our StorageClass (SC) sc-gold using the same options used in the previous example.





$ vi sc_example.yml

kind: StorageClass
  name: sc-gold
  provisioning: 'full'
  cpg: 'SSD_r6'





In this example, you must specify a name for the StorageClass and specify the 3PAR driver as well. The last section volume parameters you will be using within the StorageClass sc-gold object, namely full provisioned and the CPG.

Note: The volume name or size is not specified here. Remember a StorageClass is a profile, the actual storage request along with volume name and size will be done within a PersistentVolumeClaim.

Here is a table of the supported StorageClass parameters for the HPE 3PAR Volume Plug-in for Docker:

StorageClass Options






thin, thick

provisioning: 'thin'



true, false

flash-cache: 'true'



true, false

compression: 'true'




MountConflictDelay: '30'



QoS enabled vvset name

qos-name: 'qos_vvset'



existing 3PAR CPG name

cpg: 'SSD_r6'



existing 3PAR CPG name

snapcpg: 'FC_r6'



3PAR RCG name

replicationGroup: 'sample_rcg'




fsOwner: '1001:1001'



chmod octal number

fsMode: '755'



3PAR ID specified in hpe.conf

backend: '3PAR1'


Use the kubectl create command to import the StorageClass definition into the Kubernetes cluster.





$ kubectl create –f sc_example.yml





Also, if you want to mark a StorageClass as default, set the annotation by issuing the following command:





$ kubectl patch storageclass <your-class-name> -p '{"metadata": {"annotations":{"":"true"}}}'






Persistent Volume Claim

PersistentVolumeClaim (PVC) is a request for storage by a user. It is based off of a StorageClass.

For example, we will be requesting a 250 GB volume based on the StorageClass sc-gold. Also because we are requesting block storage, we will need to need to specify ReadWriteOnce for the AccessModes.





$ vi pvc_example.yml

kind: PersistentVolumeClaim
apiVersion: v1
  name: pvc-nginx
    - ReadWriteOnce
      storage: 250Gi
  storageClassName: sc-gold





If we were using HPE 3PAR File Persona, we would change that option to ReadWriteMany. For more information on access modes, visit:

Use the kubectl create command to create the PVC.





$ kubectl create –f pvc_example.yml





Use the kubectl get pvc command to view the PVC





$ kubectl get pvc
NAME      STATUS  VOLUME                                        CAPACITY  ACCESS MODES  STORAGECLASS   AGE
pvc-nginx Bound   sc-gold-66d57a3e-6201-4c7f-a900-f3620b1724a0  250Gi     RWO           sc-gold        19d







Now that the volume has been created and is bound, it is ready for use within the Kubernetes cluster. Let’s create an application/pod to attach the volume to. We will use a simple nginx application. In order to use the previously created volume, we need only specify the pvc-nginx PVC we just created and a mount point. We will simultaneously create a service to make the pod accessible outside the cluster.





vi nginx-pod.yml

kind: Pod
apiVersion: v1
  name: pod-nginx
  app: nginx-hpe
  - name: nginx
    image: nginx
    - containerPort: 80
      name: "http-server"
    - name: export
      mountPath: "/usr/share/nginx/html"
    - name: export
        claimName: pvc-nginx

apiVersion: v1
kind: Service
  name: nginx-service
    name: nginx-service
  type: NodePort
  - port: 80
    nodePort: 30080
    name: nginx-hpe





Use the kubectl create command to create the pod.





$ kubectl create –f nginx-pod.yml





We can now log into this pod and write some data.





$ kubectl exec -it pod-nginx -- /bin/bash

$ echo Hello from Kubernetes Storage! > /usr/share/nginx/html/index.html





Now let’s check to see if everything is working properly.





$ kubectl describe pod pod-nginx | less

Name:               pod-nginx
Namespace:          default
Priority:           0
Start Time:         Thu, 01 Aug 2019 11:29:55 -0600
Labels:             <none>
Annotations:        <none>
Status:             Running






Look through the spec until you find the IP address for the pod. We will need the IP to verify everything is working.





$ curl

Hello from Kubernetes Storage!






If you see this output, you have successfully created a working persistent volume, claim and pod.


Being able to provide storage to your stateful applications is important. Because not all storage requirements for mission critical applications are the same, the HPE 3PAR Volume Plug-in for Docker gives you full control over the storage while providing resiliency to your containerized applications.

Stay tuned—in the next post we will go into more volume management scenarios like snapshots and clones.

0 Kudos
About the Author


Everything about Containers and Persistent Storage using HPE 3PAR/Primera in Docker, Kubernetes, Red Hat, as well as Storage Automation