Можно ли связать ПВХ с конкретным ПВ?

Это обсуждалось сопровождающими k8s в https://github.com/kubernetes/kubernetes/issues/7438:

Разрешение пользователям запрашивать определенный PV нарушает разделение между ними

Я не покупаю это. Мы разрешаем пользователям выбирать узел. Это не обычный случай, но он существует по причине.

Как это закончилось? Каким образом должен быть>1 PV и PVC, как в https://github.com/kubernetes/kubernetes/tree/master/examples/nfs?

Мы используем NFS, а PersistentVolume - удобная абстракция, потому что мы можем сохранить server IP и path там. Но PersistentVolumeClaim получает любой PV с достаточным размером, предотвращая path повторное использование.

Можно установить volumeName в ПВХ spec блокировать (см. https://github.com/kubernetes/kubernetes/pull/7529), но это не имеет значения.

9 ответов

Сегодня существует способ предварительно связать PV с PVC, вот пример, показывающий, как:

1) Создайте объект PV с полем ClaimRef, ссылающимся на PVC, который вы впоследствии создадите:

$ kubectl create -f pv.yaml
persistentvolume "pv0003" created

где pv.yaml содержит:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  claimRef:
    namespace: default
    name: myclaim
  nfs:
    path: /tmp
    server: 172.17.0.2

2) Затем создайте ПВХ с тем же именем:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

3) PV и PVC должны быть связаны немедленно:

$ kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESSMODES   AGE
myclaim   Bound     pv0003    5Gi        RWO           4s
$ ./cluster/kubectl.sh get pv
NAME      CAPACITY   ACCESSMODES   STATUS    CLAIM             REASON    AGE
pv0003    5Gi        RWO           Bound     default/myclaim             57s

Мы также планируем ввести "Выбор томов", который позволит пользователям выбирать конкретное хранилище на основе некоторых специфических характеристик реализации (например, в конкретной стойке или, в вашем случае, способ принудительного преобразования 1:1 PV в PVC).

См. https://github.com/kubernetes/kubernetes/issues/18333.

Это можно сделать с помощью ключевого слова volumeName:

например

apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
  name: "claimapp80"
spec:
  accessModes:
    - "ReadWriteOnce"
  resources:
    requests:
      storage: "10Gi"
  volumeName: "app080"

будет требовать конкретного PV app080

Лучше указать оба volumeName в pvc а также claimRef в pvc,

Используя storageClassName: manual в обоих pv а также pvc мы можем связать друг с другом, но это не гарантирует, если есть много manual PV и ПВХ.

Указание volumeName в вашем PVC не предотвращает связывание другого PVC с указанным PV до того, как это сделает ваш. Ваша претензия останется в ожидании, пока PV не станет доступным.

Указание в качестве PVR в PV не препятствует привязке указанного PVC к другому PV. PVC может выбрать другой PV для связывания в соответствии с обычным процессом связывания. Поэтому, чтобы избежать этих сценариев и убедиться, что ваша заявка связана с нужным томом, вы должны убедиться, что указаны и volumeName, и requestRef.

Вы можете сказать, что ваши настройки volumeName и / или demandRef повлияли на процесс сопоставления и связывания, проверив пару Bound PV и PVC на предмет аннотации pv.kubernetes.io/bound-by-controller. PV и PVC, для которых вы сами задаете volumeName и / или instanceRef, не будут иметь такой аннотации, но обычные PV и PVC будут иметь значение "да".

Когда для PVR в свойстве RequestRef задано какое-то имя и пространство имен PVC, и он освобождается в соответствии с политикой возврата Retain, для его requestRef будет оставаться то же имя и пространство имен PVC, даже если PVC или все пространство имен больше не существует.

источник: https://docs.openshift.com/container-platform/3.11/dev_guide/persistent_volumes.html

Storage ClassName в PV и PVC должно быть одинаковым. Добавьте имя постоянного тома в качестве volumeName в PVC, чтобы связать PVC с определенным PV.

нравиться:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-name
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 40Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-name
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  volumeName: pv-name

Согласно документации :


Плоскость управления может связывать PersistentVolumeClaims с соответствующими PersistentVolumes в кластере. Однако, если вы хотите, чтобы PVC был привязан к определенному PV , вам необходимо предварительно привязать их.

Указав PersistentVolume в PersistentVolumeClaim, вы объявляете привязку между этим конкретным PV и PVC. Если PersistentVolume существует и не зарезервировал PersistentVolumeClaims с помощью своего поля ClaimRef, будут связаны PersistentVolume и PersistentVolumeClaim.

Связывание происходит независимо от некоторых критериев соответствия тома, включая сходство узлов. Плоскость управления по-прежнему проверяет, допустимы ли класс памяти, режимы доступа и запрошенный размер памяти.


Несмотря на то, что StatefulSets - это ресурс, используемый для управления приложениями с отслеживанием состояния , я изменил пример pv / pvc, который они предоставляют, в пример развертывания (с nginx, совместимым как минимум с minikube, прокомментируйте / отредактируйте совместимость с облачными поставщиками):

      apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: foo-pvc
  namespace: foo
spec:
  storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
  volumeName: foo-pv
  ...
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef:
    name: foo-pvc
    namespace: foo
  ...

Итак, чтобы уточнить документацию, если вы заполните файл spec.claimRef.name (как foo-pvc или что-то еще), ваш PVC будет находиться в ожидании и не будет связываться. (Я оставил его закомментированным.) Однако вы заметите, что если вы отредактируете его после создания PV, как указано выше, с kubectl edit pv foo-pv, что он задается плоскостью управления как таковой.

Кроме того, я оставил альтернативное имя PV metadata.name (закомментированное), вы можете переключить строку комментария и также увидеть, что он не будет связываться, если значение не соответствует тому, что указано в PVC с помощью spec.volumeName.

Дополнительное примечание: я обнаружил, что если вы не создали / mnt / test перед развертыванием вышеупомянутого, он создаст эту папку, когда вы будете писать в нее изнутри контейнера.

Да, вы можете предоставить volumeName в пвх. Он будет привязан именно к этому имени PV, указанному в volumeName (также спецификация должна быть синхронизирована)

Теперь мы можем использовать storageClassName (по крайней мере, из kubernetes 1.7.x)

Подробнее см. https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage

Здесь также скопирован пример кода

вид: PersistentVolume
apiVersion: v1
метаданные:
  имя: таск-пв-том
  метки:
    тип: местный
спецификация:
  storageClassName: ручной
  вместимость:
    хранение: 10 ги
  accessModes:
    - ReadWriteOnce
  hostPath:
    путь: "/tmp/data"
---
вид: PersistentVolumeClaim
apiVersion: v1
метаданные:
  Название: Task-PV-претензия
спецификация:
  storageClassName: ручной
  accessModes:
    - ReadWriteOnce
  Ресурсы:
    Запросы:
      хранение: 3Gi

Я не думаю, что редактирование @jayme к исходному ответу совместимо с прямой трансляцией.

Хотя селекторы меток в PVCs задокументированы только как предложение, похоже, работают с Kubernetes 1.3.0.

Я написал пример, который определяет два тома, которые идентичны, за исключением labels, Оба будут удовлетворять любой из претензий, но когда претензии указывают

selector:
    matchLabels:
      id: test2

очевидно, что один из зависимых модулей не запустится, а тест1 будет оставаться свободным.

Можно протестировать, например, в миникубе с:

$ kubectl create -f volumetest.yml
$ sleep 5
$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
volumetest1                       1/1       Running   0          8m
volumetest1-conflict              0/1       Pending   0          8m
$ kubectl get pv
NAME      CAPACITY   ACCESSMODES   STATUS      CLAIM          REASON    AGE
pv1       1Gi        RWO           Available                            8m
pv2       1Gi        RWO           Bound       default/test             8m

как насчет селектора меток, как описано в документации kubernetes:

В утверждениях можно указать селектор меток для дальнейшей фильтрации набора томов. К заявке могут быть привязаны только тома, метки которых соответствуют селектору. Селектор может состоять из двух полей:

matchLabels - у тома должна быть метка с этим значением.
matchExpressions - список требований, созданный путем указания ключа, списка значений и оператора, который связывает ключ и значения. Допустимые операторы включают In, NotIn, Exists и DoesNotExist.

Другие вопросы по тегам