Kubernetes: збільшення Persistent Volume з PersistentVolumeClaim та volumeClaimTemplates

Автор |  21/02/2023
 

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 це робиться автоматично завдяки параметру ExpandInUsePersistentVolumesonline 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]

Готово.