Могут ли 3 реплики использовать один и тот же PersistentVolume в StatefulSet в Kubernetes?

Я создал StatefulSet для запуска моего NodeJS с 3 репликами и хочу подключить его к диску gce, который может стать хранилищем данных для загрузки файлов пользователем.

Название моего проекта: carx; Имя сервера: автомобиль-сервер

Однако при создании второго модуля у меня возникла ошибка.

kubectl describe pod car-server-statefulset-1

Ошибка AttachVolume.Attach для тома "my-app-data": googleapi: Ошибка 400: RESOURCE_IN_USE_BY_ANOTHER_RESOURCE - ресурс диска "projects/.../disks/carx-disk" уже используется экземплярами "projects/...//gke-cluster-...-2dw1'


автомобиль-сервер-statefulset.yml

apiVersion: v1
kind: Service
metadata:
  name: car-server-service
  labels:
    app: car-server
spec:
  ports:
  - port: 8080
    name: car-server
  clusterIP: None
  selector:
    app: car-server
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: car-server-statefulset
spec:
  serviceName: "car-server-service"
  replicas: 3
  template:
    metadata:
      labels:
        app: car-server
    spec:
      containers:
        - name: car-server
          image: myimage:latest
          ports:
            - containerPort: 8080
              name: nodejs-port
          volumeMounts:
          - name: my-app-data
            mountPath: /usr/src/app/mydata
      volumes:
      - name: my-app-data
        persistentVolumeClaim:
          claimName: example-local-claim
  selector:
    matchLabels:
      app: car-server

pvc.yml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: example-local-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-app-data
  labels:
    app: my-app
spec:
  capacity:
    storage: 60Gi
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  gcePersistentDisk:
    pdName: carx-disk
    fsType: ext4

2 ответа

Поле Access Mode рассматривается как запрос, но нет уверенности, что вы получите то, что запрашиваете. В вашем случае GCEPersistentDisk поддерживает только ReadWriteOnce или же ReadOnlyMany.

Ваш PV теперь установлен как ReadWriteOnceно может быть установлен только на одном узле одновременно. Таким образом, другие реплики не смогут смонтировать том.

При использовании StatefulSet обычно каждая реплика использует свой собственный том, используйте volumeClaimTemplate: часть StatefulSet манифест для этого.

Пример:

  volumeClaimTemplates:
  - metadata:
      name: example-claim
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"
      resources:
        requests:
          storage: 5Gi

В случае, если вы можете использовать только один том, вы можете рассмотреть возможность запуска StatefulSet только с одной репликой, например replicas: 1.

Если вам нужна дисковая репликация, вы можете использовать StorageClass для региональных дисков, которые также реплицируются в другую зону доступности. См. Региональный постоянный диск, но у него все те же режимы доступа.

Из документов

Особенностью PD является то, что они могут быть установлены как доступные только для чтения несколькими потребителями одновременно. Это означает, что вы можете предварительно заполнить PD своим набором данных, а затем обслуживать его параллельно из любого количества модулей, которое вам нужно. К сожалению, PD может быть смонтирован только одним потребителем в режиме чтения-записи - одновременная запись не допускается.

Альтернативным решением является Google Cloud Filestore, который является предложением NAS. Вы можете подключить хранилище файлов в экземплярах Compute Engine и Kubernetes Engine. Однако проблема с Filestore заключается в том, что он разработан с учетом больших систем хранения файлов и имеет минимальную емкость 1 ТБ, что дорого для небольших случаев использования.

Недорогой способ решить эту проблему - настроить сервер NFS в вашем кластере с резервным копированием PV ReadWriteOnce, а затем создать PV на основе NFS (который поддерживает ReadWriteMany) с помощью этого сервера NFS.