Можно ли связать ПВХ с конкретным ПВ?
Это обсуждалось сопровождающими 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).
Это можно сделать с помощью ключевого слова 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.