Keep in mind that Kubernetes does not manage the storage itself, just access.
Persistent Volume
For things like Databases, persistence, with Kubernetes has a few requirements.
Pod storage “dies” when the pod dies, so ‘persistent’ storage that persists beyond the lifecycle of a pod is required.
Because a pod intended to replace a pod might be deployed to any node in the cluster, storage must be accessible to any node.
Generally, storage is expected to persist even if the cluster dies.
A Persistent volume is a Cluster resource
just like RAM or CPU.
Like all other Kubernetes components it’s created with yaml
files
Attributes are storage type specific - you need GCP specific attributes that aren’t applicable to local disk, for example.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-name
spec: # Note the attributes of the PV
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.0
nfs:
path: /dir/path/on/nfs/server
server: nfs-server-ip-address
---
# GCP example
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
labels:
failure-domain: .beta.kubernetes.io/zone: us-central1-a__us-central1-b
spec:
capacity:
storage: 400Gi
accessmodes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
Questions that need to be answered:
What type of storage does your application need
- Object
- Block
- File
Where is the storage located
- Cloud
- On Prem
- Billy-Bob’s Datacentres R Us
What backup procedures are being implemented
These need to be managed by the devs or Ops, Kubernetes has only provided an interface for some of those characteristics to be described to the cluster management, it doesn’t do any of those things itself.
As far as Kubernetes is concerned the storage is a plugin to the cluster, and you can have multiple of them.
Persistent Volumes are not namespaced, they are not restricted to access by any namespace.
Persistent Volume Claim
Persistent Volumes need to be created before they are used.
Therefore the storage is provisioned by the Kubernetes Admin, based on the requirements that developers say that their applications need.
Applications then claim
some of the persistent volume.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-name
spec:
storageClassName: manual
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
That claim then needs to be used in the pod
configuration (so that the pod
knows how to access the PersistentVolume
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: pvc-name # Note that this is the name of the above Persistent Volume Claim
Claims need to be in the same namespace
as the pod
that wants to use it.
How it all works:
The pod
mounts the persistent volume claim
to access a persistent volume
, that mount is then mounted by the container
in the pod
.
The persistent volume claim
is fulfilled by any persistent volume
that can satisfy the requirements that are set out in their respective configuration files.
Two other types of storage - ConfigMap - Secret
These are always local volumes, and are not created via Persistent Volume or Persistent Volume Claim.
ConfigMap example
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox-container
image: busybox
volumeMounts:
- name: config-dir
mountPath: /etc/config
volumes:
- name: config-dir
configMap:
name: bb-configmap
A pod
can have multiple types of volumes mounted at once, secret
s, configMap
s, and persistentVolumeClaims
.
For example
spec:
volumeMounts: # Mounted inside the container
- name: es-persistent-storage
mountPath: /var/lib/data
- name: es-secret-dir
mountPath: /var/lib/secret
- name: es-config-dir
mountPath: /var/lib/config
volumes:
- name: es-persistent-storage
persistentVolumeClaim:
claimName: es-pv-claim
- name: es-secret-dir
secret:
secretName: es-secret
- name: es-config-dir
configMap:
name: es-config-map
Storage Class
Creates or provisions Persistent Volumes dynamically - in that when a PersistentVolumeClaim requires a PersistentVolume
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: storage-class-name
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
You add a storage class name to a PersistentVolumeClaim
so that when a pod
makes a PersistentVolumeClaim
it also specifies the storage class that it wishes to use. The storage Class will then provision some Persistent Volume that meets the needs of the claim.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: storage-class-name