Wednesday, December 23, 2020

Persistence Volume Allocation on a Bare Metal Kubernetes



 

When we have a kubernetes based deployment, we usually need to use persistence volumes. This is usually required for databases such as Redis and ElasticSearch, but might be required for many other services.

In a cloud based kubernetes, such as GKE, and EKS, automatically provision the persistence volumes according to the persistence volume claims that our application deployments and statefulsets create.

But in a bare metal environments, which many use as a debugging environment, persistence volume are not provisioned automatically.

Until recently I have been using hostpath-provisioner to handle the persistence volumes allocation, but once I've upgarded my kubernetes to version 1.20, the hostpath-provisioner was broken with error: "selflink was empty". I could not find the reason for the failure.

However, I did find a simple bypass using HELM, and I think I should have used it anyways instead of using the hostpath-provisioner.

The idea is to use Helm (that is widely used for kubernetes deployments) to create the persistence volumes only when hostpath is specified as the storage class for the persistence volume.

For example, a statefulset would create a persistence volume claim:



apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:



volumeClaimTemplates:
- metadata:
name: pvc
spec:
accessModes: [ "ReadWriteOnce" ]
{{- if ne .Values.storageClass "" }}
storageClassName: "{{ .Values.storageClass }}"
{{- if eq .Values.storageClass "hostpath" }}
volumeName: my-pv
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.storageSize }}



Notice that in case the storage class is hostpath, we ask for a specific volume name.

Next we create the persistence volume, only if the storage class is hostpath:


{{- if eq .Values.storageClass "hostpath" }}
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
labels:
type: local
spec:
storageClassName: hostpath
capacity:
storage: {{ .Values.storageSize }}
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/my-folder"
{{- end }}


That's it. 

No need of any special tricks.

Also, our helm chart support both deployment on a bare metal kubernetes, and on a cloud based kubernetes with a change of a single helm value.






No comments:

Post a Comment