Resizing a PersistentVolumeClaim for Postgres by moving content to a new PVC
Resize a PersistentVolumeClaim (PVC) for Postgres by creating a new, larger PVC, and moving content between the PVCs, on native Kubernetes.
Before you begin
About this task
Use this procedure when the storage class does not support volume expansion. This procedure is for use on native Kubernetes.
Note: This procedure is for use only with Postgres.
Procedure
-
Create a new temporary PVC. Ensure the requested storage size is more than the original PVC.
For example:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: temp-pvc spec: storageClassName: rook-ceph-block accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
- Determine the primary Postgres pod.
kubectl get pods --selector role=master | grep -v bootstrapselector=role=master
- Gracefully shutdown Postgres pods.
- Exec into the Postgres primary pod.
kubectl exec -it <postgres-pod> -- bash
- Pause the Patroni process. Note: you can skip this step if using the one replica profile.
patronictl pause
- Stop the Postgres process gracefully.
pg_ctl stop -D /pgdata/<cluster-name>
For example:
cluster-name
is usually the name of the cluster. If primary pod name ism1-1b12bf81-postgres-58dfcc5f97-fsvvt
,cluster-name
ism1-1b12bf81-postgres
.- There will be a folder named
cluster-name
located under/pgdata/
. - In this example, the command
is:
pg_ctl stop -D /pgdata/m1-1b12bf81-postgres
- Exec into the Postgres primary pod.
- Determine the PVC linked to the primary Postgres pod, and obtain the
claimName
of the PVC.kubectl get pod <postgres-pod> -o json | jq '.spec.volumes[] | select ( has ("persistentVolumeClaim"))'
- Scale down the Postgres deployment.
kubectl get deploy | grep postgres | grep -v bouncer | grep -v bootstrap | grep -v backrest | grep -v operator
If you are using
n3
profile then you find 3 deployments. Scale them down:kubectl scale deploy <deployment-name> --replicas=0
- Start a BusyBox pod with the source and destination PVC volumes mounted, to
swap the content between PVCs. For example:
apiVersion: v1 kind: Pod metadata: name: swap-pvc spec: volumes: - name: volume-source persistentVolumeClaim: claimName: m1-mgmt-35817114-postgres-wal - name: volume-destination persistentVolumeClaim: claimName: temp-pvc containers: - name: debug image: busybox command: ['sleep', '3600'] volumeMounts: - name: volume-source mountPath: /data-source - name: volume-destination mountPath: /data-destination
- Exec to the BusyBox pod, and
kubectl exec -it <busybox-pod-name> -- sh
cp -r data-source/ data-destination/
- Copy content to the temporary PVC. For example, using the
mountPath
values shown in Step 6:cp -r data-source/ data-destination/
- Delete the BusyBox pod.
kubectl delete pod <busybox-pod-name>
- Delete the original PVC.
kubectl delete pvc <claimName>
- Create an original PVC with the same name but with increased size. For example:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: m1-mgmt-35817114-postgres-wal spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi storageClassName: rook-ceph-block volumeMode: Filesystem
- Start the BusyBox pod again and this time copy the content from destination to source
PVC.
kubectl exec -it <busybox-pod> -- sh cp -r data-destination/ data-source/
- Delete the BusyBox pod.
kubectl delete pod <busybox-pod>
- Delete the temporary PVC that you created for swapping the content.
kubectl delete pvc temp-pvc
- Scale up the Postgres deployment.
kubectl get deploy | grep postgres | grep -v bouncer | grep -v bootstrap | grep -v backrest | grep -v operator
If you are using the
n3
profile then you find 3 deployments. Scale them up:kubectl scale deploy <deployment-name> --replicas=1
- If using the
n3
profile, resume the Patroni process. If using then1
profile, skip this step.-
Identify the Postgres pods.
kubectl get pods --selector role
-
Exec into any Postgres pod.
kubectl exec -it <postgres-pod> -- bash
-
Resume Patroni.
patronictl resume
-
Identify the Postgres pods.