GitLab для зберігання репозиторіїв по дефолту створює диск розміром 50 GB, чого для Production явно буде мало.
Persistent Volume resize опція доступна як general availability з версії Kubernetes 1.24, див. Kubernetes 1.24: Volume Expansion Now A Stable Feature, а в Beta – з версії 1.11, див. Resizing Persistent Volumes using Kubernetes.
Доступно для дисків AWS EBS, GCE PD, Azure Disk, Azure File, Glusterfs, Cinder, Portworx та Ceph RBD.
Спочатку подивимось на приклад, коли у нас PVC створються зі звичайного маніфесту, а потім – як збільшити диск, котрий створювався через StatefulSet та його volumeClaimTemplates.
Зміст
Збільшення диску через PersistentVolumeClaim
Перевіряємо чи можливо це з нашим “залізом”, тобто StorageClass, який використовується, в нашому випадку це AWS Elastic Block Store з типом gp3 – дивимось ресурс StorageClass, та його колонку ALLOWVOLUMEEXPANSION:
[simterm]
$ kk get StorageClass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE cold-storage ebs.csi.aws.com Delete WaitForFirstConsumer true 362d encrypted ebs.csi.aws.com Delete WaitForFirstConsumer true 362d gp2 ebs.csi.aws.com Delete WaitForFirstConsumer true 362d gp3 (default) ebs.csi.aws.com Delete WaitForFirstConsumer true 362d high-iops-ssd ebs.csi.aws.com Delete WaitForFirstConsumer true 362d medium-iops-ssd ebs.csi.aws.com Delete WaitForFirstConsumer true 362d throughput ebs.csi.aws.com Delete WaitForFirstConsumer true 362d
[/simterm]
Також памя’таємо, що після зміни розміру EBS потрібно змінити розмір файлової системи. У Kubernetes з версії 1.24 це робиться автоматично завдяки параметру ExpandInUsePersistentVolumes – online file system expansion. Між 1.11 та 1.24 потрібно перезапускати поди, які використовують цей PVC.
Ну і перевіримо.
Створимо Pod з PersistentVolumeClaim на 1 гігабайт:
---
apiVersion: v1
kind: Pod
metadata:
name: test-resize-pv-pod
labels:
app: test-resize
spec:
containers:
- name: test-resize-pv-container
image: nginxdemos/hello
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/data"
name: test-resize-pv-volume
volumes:
- name: test-resize-pv-volume
persistentVolumeClaim:
claimName: test-resize-pv-volume-pvc
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-resize-pv-volume-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: gp3
Деплоїмо:
[simterm]
$ kk -n tests apply -f test-pod-w-pvc.yaml pod/test-resize-pv-pod created persistentvolumeclaim/test-resize-pv-volume-pvc created
[/simterm]
Перевіряємо PersistentVolumeClaim:
[simterm]
$ kk -n tests get pvc test-resize-pv-volume-pvc
[/simterm]
По ID подивимось на сам PersistentVolume (тобто AWS EBS):
[simterm]
$ kk -n tests get pv pvc-8e75b850-8ef2-431b-a525-2a3200d17634 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-8e75b850-8ef2-431b-a525-2a3200d17634 1Gi RWO Delete Bound tests/test-resize-pv-volume-pvc gp3 86s
[/simterm]
Редагуємо PersistentVolumeClaim – збільшимо в resources.requests.storage розмір до 2 ГБ:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-resize-pv-volume-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: gp3
Оновлюємо:
[simterm]
$ kk -n tests apply -f test-pod-w-pvc.yaml pod/test-resize-pv-pod configured persistentvolumeclaim/test-resize-pv-volume-pvc configured
[/simterm]
Та перевіряємо ще раз:
[simterm]
$ kk -n tests get pvc test-resize-pv-volume-pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test-resize-pv-volume-pvc Bound pvc-8e75b850-8ef2-431b-a525-2a3200d17634 2Gi RWO gp3 4m50s
[/simterm]
В самому поді:
[simterm]
$ kk -n tests exec -ti test-resize-pv-pod -- df -h /data Filesystem Size Used Available Use% Mounted on /dev/nvme4n1 1.9G 24.0K 1.9G 0% /data
[/simterm]
Гуд.
Збільшення диску з StatefulSet та volumeClaimTemplates
Створюємо маніфест з STS та volumeClaimTemplates – цей volumeClaimTemplates створить PersistentVolumeClaim:
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
Деплоїмо, перевіряємо:
[simterm]
$ kk -n tests get pvc www-web-0 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-ca9d909f-1d34-40d9-acac-78ab778f500f 1Gi RWO gp3 2m7s
[/simterm]
The StatefulSet is invalid: spec: Forbidden
Пробуємо змінити volumeClaimTemplates.spec.resources.requests.storage на 2GB, аплаїмо:
[simterm]
$ kubectl -n tests apply -f test-sts-w-pvc.yaml The StatefulSet "web" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', 'updateStrategy' and 'minReadySeconds' are forbidden
[/simterm]
Ага…

Тож лишаємо значення в volumeClaimTemplates, та редагуємо PVC вручну:
Або з kubectl patch:
[simterm]
$ kubectl -n tests patch pvc www-web-0 -p '{"spec":{"resources":{"requests":{"storage":"2Gi"}}}}'
[/simterm]
І за хвилину перевіряємо:
[simterm]
$ kk -n tests get pvc www-web-0 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-ca9d909f-1d34-40d9-acac-78ab778f500f 2Gi RWO gp3 3m43s
[/simterm]
Та сам Persistent Volume:
[simterm]
$ kk -n tests get pv pvc-ca9d909f-1d34-40d9-acac-78ab778f500f NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ca9d909f-1d34-40d9-acac-78ab778f500f 2Gi RWO Delete Bound tests/www-web-0 gp3 4m14s
[/simterm]
Готово.
