Statefulset с репликами: 1 pod имеет несвязанные немедленные PersistentVolumeClaims

Я пытаюсь настроить в своем кластере с одним узлом (Docker Desktop Windows) эластичный кластер. Для этого я создал PV следующим образом (работает)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: elastic-pv-data
  labels:
    type: local
spec:
  storageClassName: elasticdata
  accessModes:   
    - ReadWriteOnce
  capacity:
    storage: 20Gi
  hostPath:
    path: "/mnt/data/elastic"

Тогда вот конфигурация:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: esnode
spec:
  selector:
    matchLabels:
      app: es-cluster # has to match .spec.template.metadata.labels
  serviceName: elasticsearch
  replicas: 2
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: es-cluster
    spec:
      securityContext:
        fsGroup: 1000
      initContainers:
      - name: init-sysctl
        image: busybox
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
      containers:
      - name: elasticsearch
        resources:
            requests:
                memory: 1Gi
        securityContext:
          privileged: true
          runAsUser: 1000
          capabilities:
            add:
            - IPC_LOCK
            - SYS_RESOURCE
        image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.7.1
        env:
        - name: ES_JAVA_OPTS
          valueFrom:
              configMapKeyRef:
                  name: es-config
                  key: ES_JAVA_OPTS
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /_cluster/health?local=true
            port: 9200
          initialDelaySeconds: 5
        ports:
        - containerPort: 9200
          name: es-http
        - containerPort: 9300
          name: es-transport
        volumeMounts:
        - name: es-data
          mountPath: /usr/share/elasticsearch/data
  volumeClaimTemplates:
    - metadata:
        name: es-data
      spec:
        storageClassName: elasticdata
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 3Gi

И в результате только один модуль имеет pvc, привязанный к pv, другой получает цикл ошибок 0/1, доступны узлы: 1 модуль имеет несвязанные немедленные PersistentVolumeClaims. Вот результат kubectl get pv,pvc:

NAME                               CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                      STORAGECLASS   REASON   AGE
persistentvolume/elastic-pv-data   20Gi       RWO            Retain           Bound    default/es-data-esnode-0   elasticdata             14m

NAME                                     STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/es-data-esnode-0   Bound    elastic-pv-data   20Gi       RWO            elasticdata    13m

Если я правильно понял, у меня должен быть второй persistantolumeclaim со следующим идентификатором: es-data-esnode-1 Есть ли что-то, что я упускаю или не понимаю правильно? Спасибо за вашу помощь

Я пропускаю здесь ненужные части (configmap, loadbalancer и т. д.)


person David DOS SANTOS    schedule 30.12.2020    source источник
comment
Вы пытались изменить режимы доступа: - ReadWriteOnce на ReadWriteMany? Это позволит монтировать том со многих узлов.   -  person Althaf M    schedule 31.12.2020
comment
просто чтобы уточнить, я говорю о постоянном объеме, а не о заявлении о постоянном объеме. pic должен иметь readWriteOnce, поскольку он будет создан по одному для каждой реплики с помощью statefulset.   -  person Althaf M    schedule 31.12.2020
comment
Предоставьте вывод kubectl get -o yaml sc/elasticdata   -  person Lukman    schedule 31.12.2020
comment
ReWriteOnce/readWriteMany не должен иметь никакого значения в кластере с одним узлом ReadWriteOnce -- the volume can be mounted as read-write by a single node ReadOnlyMany -- the volume can be mounted read-only by many nodes ReadWriteMany -- the volume can be mounted as read-write by many nodes   -  person David DOS SANTOS    schedule 31.12.2020
comment
@Lukman, вот результат команды: Error from server (NotFound): storageclasses.storage.k8s.io "elasticdata" not found   -  person David DOS SANTOS    schedule 31.12.2020
comment
Как вы смогли создать PVC, если класс хранения не найден?? Вы запускали команду в том же кластере???   -  person Lukman    schedule 01.01.2021


Ответы (2)


Позвольте мне добавить несколько деталей к тому, что уже было сказано как в комментариях, так и в ответе Jonas.

Судя по комментариям, вы не определили StorageClass с именем elasticdata. Если он не существует, вы не можете ссылаться на него в своих PV и PVC.

Взгляните на то, как hostPath используется для определения PersistentVolume и как на него ссылаются в PersistentVolumeClaim. Здесь вы можете видеть, что в примере используется storageClassName: manual. Документы Kubernetes не говорят об этом явно, но если вы посмотрите на документы Openshift, там очень четко сказано, что:

На модуль, использующий том hostPath, необходимо ссылаться при ручной (статической) подготовке.

Это не просто какое-то значение, используемое для привязки PVC запроса к этому конкретному PV. Поэтому, если elasticdata StorageClass не было определено, вы не должны использовать его здесь.

Второе. Как уже заявил Джонас в своем комментарии, между PVC и PV существует однозначная привязка, поэтому независимо от того, что ваш PV по-прежнему имеет достаточную емкость, она уже занята другим PVC и больше недоступна. Как вы можете прочитать в официальных документах:

Привязка PVC к PV — это взаимно однозначное сопоставление с использованием ClaimRef, которое является двунаправленной привязкой между PersistentVolume и PersistentVolumeClaim.

Претензии останутся несвязанными на неопределенный срок, если соответствующий том не существует. Претензии будут связаны по мере появления соответствующих томов. Например, кластер с несколькими PV 50Gi не будет соответствовать PVC, запрашивающему 100Gi. PVC можно привязать, когда к кластеру добавляется PV 100Gi.

Наоборот. Если есть только один PV 100Gi, он не сможет удовлетворить запрос от двух PVCs, требующих 50Gi каждый. Обратите внимание, что в опубликованном вами результате kubectl get pv,pvc и PV, и PVC имеют емкость 20Gi, хотя вы запрашиваете в каждом PVC, созданном из шаблона PVC, только 3Gi.

Вы не работаете здесь с каким-либо поставщиком динамического хранилища, поэтому вам нужно вручную предоставить столько PersistentVolumes, сколько необходимо для вашего варианта использования.

Кстати, вместо hostPath я бы рекомендовал вам использовать local том с правильно определенным StorageClass. У него есть несколько преимуществ перед HostPath. Кроме того, внешнее статическое средство подготовки можно запустить отдельно для улучшения управления жизненным циклом локального тома.

person mario    schedule 31.12.2020

При использовании StatefulSet с volumeClaimTemplates будет создано PersistentVolumeClaim для каждой реплики. Таким образом, если вы используете replicas: 2, будут созданы два разных PersistentVolumeClaims, es-data-esnode-0 и es-data-esnode-1.

Каждый PersistentVolumeClaim будет привязан к уникальному PersistentVolume, поэтому в случае двух PVC вам потребуются два разных PersistentVolumes. Но это непросто сделать, используя volumeClaimTemplate и hostPath томов в настольной установке.

По каким причинам вам нужен replicas: 2 в этом случае? Обычно он используется для обеспечения большей доступности, например. использование более одного узла. Но для локальной установки в среде рабочего стола обычно достаточно одной реплики на одном узле? Я думаю, что для вас проще всего использовать replicas: 1.

person Jonas    schedule 31.12.2020
comment
Привет, спасибо за это объяснение, но мне нужно построить эластичный кластер, поэтому как минимум 2 экземпляра. И я использую VolumeClaimsTemplates для создания двух PersistantVolumesClaims, но это не работает. Только первый создается и привязывается к PersistantVolume, второй — нет. Each PersistentVolumeClaim will bound to an unique PersistentVolume интересно, потому что я думал, что это связано только с StorageClassName и емкостью. Каждому пвх нужно 3Gi, всего 6Gi. PV может предложить 20Gi. И они имеют одно и то же StorageClassName. Разве не достаточно? - person David DOS SANTOS; 31.12.2020
comment
Это не работает с двумя PVC, когда у вас есть только один PV. При использовании двух PVC вам потребуется два PV. - person Jonas; 31.12.2020