This is an old revision of the document!
Overview
In Kubernetes and in docker in general, there are several type of storage, but let's focus on the basics here:
- Dynamic
- Static
To better illustrate this, check the following pictures:
Now, let's discuss a little bit about the components here. We will start from left to right.
- Storage
First you have the actual storage, that storage can be cloud (AWS, Google, IBM Cloud etc) or Local (iSCSI, NAS, SAN, bare metal, etc). Kubernetes has a lot of plugins to provide access to that storage. On the other side, that storage can be replicated, hashed, mapped, encrypted, in RAID and so on and so on. From Kubernetes point of view, it is seen simply as a storage thanks to the plugin
- Plugin
Plugins provide the entry point for Kubernetes, as described above, there are different plugins, like EBS Plugin for Cloud Volume or local for local storage. You can check more about Kubernetes Plugins here.
- Persistent Volume (PV)
Persistent Volume represent the volumes in Kubernetes term, in other words, the physical representation of the volume gets translated to persistent volume in kubernetes terms. To use that volume, of course we have to use the next component, which is:
- Persistent Volume Claim (PVC)
Both, PV and PVC are first class objects in Kubernetes, which means, that just like we can GET and DESCRIBE Pods, we can do the same for PV/PVC. It is important to note, that once a PVC has connected to PV, other PVC cannot connect to the same PV.
- Volume
Lastly, we have the Volumes, which are the PV in the POD. Once the Volume is linked with the PVC which is linked with the PV. That PV can be used only by the containers which are in that pod. Other pods or other containers outside of the pod, cannot use that storage.
So, in a nutshell:
- We define the storage
- We define the PV
- We define the PVC
- Lastly, we define the Volume in the pod configuration.
There is a BIG issue with that kinda provisioning, IT DOESN'T SCALE. because of that, we have two type of privisioning:
- Static
- Dynamic
So let's get going and see how it is done with each type:
Static Provisioning
Let's configure Static storage.
Create PV
Firstly, as we said, we have to configure, the PV, let's take one example of a PV:
PV Specs
kind: PersistentVolume apiVersion: v1 <- It is first Class object, just like Pod, Deployment and so on metadata: name: ps-pv <- The name is completely arbitrary, so choose whatever, but with reason :) labels: type: local <- Local Label spec: storageClassName: ps-fast <- Indicate that it is in "ps-fast" storage Class capacity: storage: 10Gi <- We allocate 10 GBs persistentVolumeReclaimPolicy: Retain # ^ # | # What to happen after you remove a PVC? #Retain - Keep it in "protected" mode #Delete(Default) - This will DELETE the PV after removing the PVC # accessModes: - ReadWriteOnce # ^ # | #There are 3 access modes: #ReadWriteOnce - The PV can be taken in RW once by one pod #ReadWriteMany - Same as above just it can be taken lots of times. #ReadOnlyMany - RO for a lot of PODs. Not all type support all 3 modes #For example, block devices don't support ReadWriteMany, but File based volumes (NFS, Object Volumes) usually do. Check your plugin docks hostPath: path: "/home/ubuntu/volume1"
You can see the description for each important attritube above. So that covers the explanation :) So, how we create it then ? Well, like any other kubernetes' object, we APPLY it:
Create PV
ubuntu@k8s-master:~/volume1$ kubectl apply -f pov1.yml persistentvolume/ps-pv created ubuntu@k8s-master:~/volume1$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE ps-pv 10Gi RWO Retain Available ps-fast 3s ubuntu@k8s-master:~/volume1$ kubectl get pvc No resources found in default namespace. ubuntu@k8s-master:~/volume1$
To use it, we need a PVC, to claim it and pod so we have a container to present it to.
Create PVC
As we already said, PVC “claims” the PV. Without PVC, the PV is useless, without PVC the PV is useless. They need to exist together.
So let's check the specs for the PVC.
PVC specs
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ps-pvc spec: storageClassName: ps-fast accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
I will not go through this description as the attributes repeat, but you get the picture. We create a claim, and we hope that some volume can fulfil it :) As again, the PVC is a first class object, we can simply “apply” it:
Create PVC
ubuntu@k8s-master:~/volume1$ kubectl apply -f pvc.yml persistentvolumeclaim/ps-pvc created ubuntu@k8s-master:~/volume1$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE ps-pvc Bound ps-pv 10Gi RWO ps-fast 3s ubuntu@k8s-master:~/volume1$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE ps-pv 10Gi RWO Retain Bound default/ps-pvc ps-fast 5m8s ubuntu@k8s-master:~/volume1$
We see that, we have bounded them and we see the claim in the Persistent Volume description. It is important to note that the PVC will bind to ANY PV which has the SAME or MORE of the requested storage. For example if the PVC wants to claim 10 GBs and we have PV with 20 GBs, it will bind. However, if our PVC wants to claim 20GBs and we have only 10 GB PV, then we are screwed and the PVC won't bind. Congrats, we have a pvc to present to any pod we want to have storage.
Dynamic Provisioning
Let's configure Dynamic storage.