Data die op een lokale drive geplaatst wordt in een pod zal verloren gaan als de pod verwijderd wordt. Vaak willen we dat de data bewaard blijft zodat een nieuwe replica van de pod of een andere pod (op dezelfde node) er ook bij kan. Hiervoor maken we dan een volume (hostPath) op de node maar wat als er multi-node gebruikt wordt of als er iets met de node fout gaat? Om de data beschikbaar te stellen zullen we dus Persistant Volumes moeten gaan gebruiken en NFS is daar een goede kandidaat voor.
Uiteindelijk is het de bedoeling dat een K8s-Administrator een Persistent Volume (PV) kan aanmaken voor een shared disk op een NFS-server en zodra deze gereed is voor gebruik dat een Developer vervolgens een Persistent Volume Claim (PVC) maakt om (een gedeelte van) de PV te kunnen gebruiken in zijn/haar applicatie.
Voorbereiden disk
Allereerst gaan we een USB Externe disk van 500Gb aan de control-Raspberry PI van onze cluster koppelen en deze formateren als ext4 partitie zodat de NFS-server deze kan gebruiken. De USB disk voorzien we van spanning middels een USB-Bridge want de RPi zelf heeft daar niet genoeg stroom voor. Met het volgende commando zien we de disk op één van de USB poorten:
$ lsusb Bus 001 Device 005: ID 0480:a00d Toshiba America Inc STOR.E BASICS 500GB
Eenmaal deze gekoppeld is, gaan we een partitie maken. Mocht dit een tweede, derde of vierde disk zijn dan wordt het device /dev/sdb, /dev/sdc of /dev/sdd. In dit geval is dit de enige externe disk op de RPi dus wordt het device /dev/sda
$ fdisk /dev/sda
Met ‘n’ kan een nieuwe partitie gemaakt worden. Gebruik ‘d’ om eventuele oude partities te verwijderen.
Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): First sector (2048-976771082, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-976771082, default 976771082): Created a new partition 1 of type 'Linux' and of size 465.8 GiB.
Vergeet niet om de nieuwe partitie weg te schrijven met ‘w’!
Formateren van de nieuwe partitie gaat met:
$ sudo mkfs -t ext4 /dev/sda1
Mount point
We maken nu een mount-point en koppelen de USB disk hieraan:
$ sudo mkdir -p /mnt/storage $ sudo chown -R pi:pi /mnt/storage $ sudo mount /dev/sda1 /mnt/storage -o uid=pi,gid=pi
Om het mounten van de disk permanent te maken, ook na een herstart, voegen we de volgende regel toe aan /etc/fstab
/dev/sda1 /mnt/storage ext4 noatime,nodiratime,data=writeback,barrier=0,nobh,errors=remount-ro 0 1
NFS Server
Om nu de disk te delen over het netwerk, kan NFS hiervoor gebruikt worden. Installatie van de NFS Server op de RPi:
$ sudo apt install -y nfs-kernel-server nfs-common $ sudo systemctl enable nfs-kernel-server
Hierna gaan we het bestand /etc/exports aanpassen om de gedeelde schijf via NFS bekend te maken op het netwerk. Voeg de volgende regel toe aan /etc/exports: (pas het ip-adres van het netwerk aan)
/mnt/storage 192.168.1.0/24(rw,all_squash,insecure,no_subtree_check)
Vervolgens dienen de volgende commando’s uitgevoerd te worden:
$ sudo exportfs -ra $ sudo update-rc.d rpcbind enable $ sudo update-rc.d nfs-common enable $ sudo service rpcbind restart $ sudo systemctl restart nfs-kernel-server
Om nu de NFS share te mounten op een ander systeem in het netwerk, kunnen de volgende commando’s uitgevoerd worden:
$ sudo apt install -y nfs-common $ sudo mkdir -p /mnt/nfs $ sudo chown -R pi:pi /mnt/nfs $ sudo mount -t nfs 192.168.1.123:/mnt/storage/ /mnt/nfs
Persistent Volume
Als administrator van een Kubernetes Cluster kun je een Persistent Volume (PV) aanmaken die later gebruikt kunnen worden door developers. Maak een bestand genaamd pv-nfs.yaml met de volgende inhoud:
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-share namespace: default spec: capacity: storage: 20Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.1.123 path: /mnt/storage
Dit is een voorbeeld om 20Gb van de schijf te gebruiken waarbij de naam van de PV ‘nfs-share’ is. De accessMode geeft aan dat eerdere containers deze share mogen gebruiken om te lezen en te schrijven. De ‘persistentVolumeReclaimPolicy‘ geeft aan of de bestanden verwijdert moeten worden als de PVC gestopt wordt (Recycle) of bewaard moeten blijven (Retain). Voer het volgende commando uit om de PV aan te maken:
$ kubectl create -f pv-nfs.yaml $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE nfs-share 20Gi RWX Retain Available 2s
Persistent Volume Claim
De PV die eerder aangemaak is door de administrator kan nu gebruikt worden middels een claim door een developer. Daartoe dient een Persistent Volume Claim en die maken we aan met het bestand pvc-nfs.yml:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-app namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi
Hiermee vragen we om een schijf van 5Gb grootte en er wordt automatisch gezocht naar een geschikte PV in dezelfde namespace waarbij gecontroleerd wordt op:
- Voldoende capaciteit (resources)
- AccessMode overeenkomst
- Volume Mode
- Storage Class
- Selector
Indien een specifieke PV gewenst is voor de PVC, dan kan gebruik gemaakt wordt van ‘labels‘ en ‘selectors‘. Indien er een match plaatsvindt zal de PVC ge’bound‘ worden aan de PV. Indien er 5Gi gevraagd wordt en de PV heeft 20Gi beschikbaar, dan wordt dit als een match beschouwd en aangezien er een 1-op-1 relatie is tussen de PV en de PVC zal de overige ruimte niet door een andere PVC geclaimd kunnen worden!
Er wordt gezocht zodra het volgende commando wordt uitgevoerd:
$ kubectl create -f pvc-nfs.yaml
met als resultaat een match en dus ge-bound:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE nfs-share 20Gi RWX Retain Bound default/nfs-app 4m3s $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfs-app Bound nfs-share 20Gi RWX 85m
Een PVC kan verwijderd worden met het commando:
$ kubectl delete pvc nfs-app
en afhankelijk van de ReclaimPolicy in de PV, zal de PV bewaard blijven of verwijderd worden.
- Retain = bewaren tot een ‘pv delete’ commando
- Delete = verwijderen
- Recycle = verwijder data en maak beschikbaar voor andere claims
De PV en PVC maken gebruik van de default StorageClass voor NFS en kan opgevgraagd worden met:
$ kubectl get storageclass NAME PROVISIONER AGE nfs-ssd1 nfs-provisioner/nfs-ssd1 4d20h
PVC in een pod
We maken een manifest dat een pod aanmaakt en gebruik maakt van de NFS share middels de Persistent Volume Claim. Maak een bestand genaamd pvc-in-a-pod.yaml met de volgende inhoud:
kind: Pod apiVersion: v1 metadata: name: pvc-in-a-pod spec: containers: - name: app image: alpine volumeMounts: - name: data mountPath: /mnt/nfs command: ["/bin/sh"] args: ["-c", "sleep 500000"] volumes: - name: data persistentVolumeClaim: claimName: nfs-app
De pod maken we aan met:
$ kubectl create -f pvc-in-a-pod.yaml
Nadat de pod status ‘Ready’ is kunnen we deze gebruiken om als test een bestand in de NFS share te maken:
$ kubectl exec -it pvc-in-a-pod sh $ touch /mnt/nfs/fromApod
Controle
Via een ander systeem, bv. je laptop, kun je de NFS share ook mounten en het bestand gemaakt in de pod zien.
Nicos-MacBook-Pro:~ nico$ sudo mount -t nfs 192.168.1.123:/mnt/storage/ /mnt/nfs Nicos-MacBook-Pro:~ nico$ ls -l /mnt/nfs -rw-r--r-- 1 65534 65534 0 Aug 3 13:44 fromApod
That’s all, folks!