Search code examples
kuberneteslonghorn

How can I retain a PersistenceVolume in Longhorn


I have setup a self managed kubernetes cluster together with longhorn as a distributed storage. The installation was quite simple.

I have created a storage class like this one:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: longhorn
  annotations:
    # make this class the default storage class
    storageclass.kubernetes.io/is-default-class: "true"

provisioner: driver.longhorn.io
reclaimPolicy: Retain
allowVolumeExpansion: true
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880" # 48 hours in minutes
  fromBackup: ""

I can create and bind a new PersistenceVolume to my pod (e.g a postgres server) now easily defining a PersistenceVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: appdata
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 2Gi

Now after I deployed my pod I can see that a PV was created (and of course it is working)

kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
pvc-803d3061-457c-4023-9864-636c7a3f626a   2Gi        RWO            Retain           Bound    default/dbdata   longhorn                10d

When I delete my postgreSQL pod my PV still exists thanks to the 'Retain' policy. But when I recreate my pod again, a new PersistenceVolume is created. So now I have two:

kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
pvc-803d3061-457c-4023-9864-636c7a3f626a   2Gi        RWO            Retain           Released   default/dbdata   longhorn                10d
pvc-9385b1ad-4c06-4bf2-b595-db6681334c3d   2Gi        RWO            Retain           Bound      default/dbdata   longhorn                10d

What I did not understand so far - and this is my question - is how can I create/claim a PersistenceVolume with a custom name (without the random UUID). And how can I tell my POD to reuse this PV? Or asked the other way: how can I tell longhorn to create a PersistenceVolume with a given name and not with a random UUID?


Solution

  • When you delete a PVC, corresponding PV becomes Released. This PV usually contains sensitive data and that is why there is no possibility to bind to it, even if it is a PVC with the same name and in the same namespace as the previous one - who knows who's trying to steal the data!

    Admin intervention is required here. There are two options:

    1. Make the PV available to everybody - delete PV.Spec.ClaimRef. This PV can bound to any PVC (assuming that capacity, access mode and selectors match)
    2. Make the PV available to a specific PVC - pre-fill PV.Spec.ClaimRef with a pointer to a PVC. Leave the PV.Spec.ClaimRef and empty UID, as the PVC does not to need exist at this point and you don't know PVC's UID. This PV can be bound only to the specified PVC.

    If you are focus on dynamics provisioning usually pvc has static name, because you create it manually, pv's are generated then based on information in claim.

    Take a look here: reusing-persistent-volume.

    Let me know if it helped.