Как повторно подключить выпущенный PersistentVolume в Kubernetes

Вот моя общая цель:

  • Запустите MongoDB

  • Сохраняйте данные при сбоях / обновлениях pod и т. д.

Подход, который я выбрал:

  • Провайдер K8S: Digital Ocean

  • Узлы: 3

  • Создать PVC

  • Создать безголовый сервис

  • Создать StatefulSet

Вот упрощенная версия конфига:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: some-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: do-block-storage
---
apiVersion: v1
kind: Service
metadata:
  name: some-headless-service
  labels:
    app: my-app
spec:
  ports:
  - port: 27017
    name: my-app-database
  clusterIP: None
  selector:
    app: my-app
    tier: database
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-app-database
  labels:
    app: my-app
    tier: database
spec:
  serviceName: some-headless-service
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      tier: database
  template:
    metadata:
      labels:
        app: my-app
        tier: database
    spec:
      containers:
      - name: my-app-database
        image: mongo:latest
        volumeMounts:
        - name: some-volume
          mountPath: /data
        ports:
        - containerPort: 27017
          name: my-app-database
      volumes:
      - name: some-volume
        persistentVolumeClaim:
          claimName: some-pvc

Это работает, как и ожидалось. Я могу раскрутить реплики до 0:

kubectl scale —replicas=0 statefulset/my-app-database

Раскрутите его обратно:

kubectl scale —replicas=1 statefulset/my-app-database

И данные сохранятся..

Но однажды, когда я возился с масштабированием statefulset вверх и вниз, я столкнулся с этой ошибкой:

Volume is already exclusively attached to one node and can't be attached to another

Будучи новичком в k8s, я удалил PVC и «пересоздал» такой же:

kubectl delete pvc some-pvc
kubectl apply -f persistent-volume-claims/

statefulset заработал резервную копию с новым PV, а старый PV был удален, так как persistentVolumeReclaimPolicy по умолчанию был установлен на Delete.

Я установил для этого нового PV persistentVolumeReclaimPolicy значение Retain, чтобы гарантировать, что данные не будут удалены автоматически... и я понял: я не уверен, как восстановить этот PV. Раньше, чтобы справиться с ошибкой «приложения тома», я удалил PVC, который просто создаст еще один новый PV с настройками, которые у меня есть, и теперь у меня остались мои данные в этом Released PV.

Мои основные вопросы:

  • Похоже ли это в целом на правильный подход к моей цели?

  • Должен ли я добавить claimRef к динамически созданному PV, а затем воссоздать новый PVC с этой претензиейRef, как указано здесь: Можно ли привязать PVC к определенному PV?

  • Должен ли я пытаться заставить этот свежий statefulset PVC использовать этот старый PV?

  • Имеет ли смысл попытаться повторно подключить старый PV к правильному узлу, и как мне это сделать?


person Jason Awbrey    schedule 29.05.2019    source источник


Ответы (1)


Если вы хотите использовать StatefulSet с масштабируемостью, ваше хранилище также должно поддерживать это, есть два способа справиться с этим:

  • Если класс хранения do-block-storage поддерживает ReadWriteMany, поместите все данные модуля в один том.

  • Каждый модуль использует свой том, добавьте volumeClaimTemplate к вашему StatefulSet.spec, тогда k8s автоматически создаст PVC, подобный some-pvc-{statefulset_name}-{idx}:

spec:
  volumeClaimTemplates:
  - metadata:
      name: some-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
      storageClassName: do-block-storage

Обновление:

StatefulSet реплики должны развертываться с помощью репликации mongodb, тогда каждый модуль в StatefulSet будет иметь одинаковое хранилище данных.

Поэтому, когда контейнер запускает команду mongod, вы должны добавить опцию --replSet={name}. когда все модули заработают, выполните команду rs.initiate(), чтобы сообщить mongodb, как обрабатывать репликацию данных. Когда вы масштабируете вверх или вниз StatefulSet, выполните команду rs.add() или rs.remove(), чтобы сообщить, что члены mongodb изменились.

person menya    schedule 30.05.2019
comment
На данный момент DigitalOcean do-block-storage StorageClass поддерживает только ReadWriteOnce в настоящее время (20190530). Мне нужно еще немного прочитать об использовании разных томов через volumeClaimTemplates, меня смущает, что я могу хранить коллекции MongoDB, распределенные по разным томам, но что StatefulSet и все его реплики будут рассматривать его как один источник.. так это изображается работать? - person Jason Awbrey; 30.05.2019
comment
Replicas сделать сервисный Load Balance запрос только к каждому модулю, поэтому это отличается от репликации данных. Чтобы сделать репликацию данных, вы должны использовать репликацию mongodb. Дополнительные сведения см. в разделе Обновление. - person menya; 31.05.2019