【问题标题】:Statefulset with replicas : 1 pod has unbound immediate PersistentVolumeClaims带有副本的 Statefulset:1 个 pod 具有未绑定的立即 PersistentVolumeClaims
【发布时间】:2021-04-07 09:44:29
【问题描述】:

我正在尝试在我的单节点集群(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

结果是只有一个“pod”的 pvc 绑定到 pv,另一个得到错误循环“0/1 个节点可用:1 个 pod 有未绑定的立即 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、..)

【问题讨论】:

  • 您是否尝试过将 accessModes: - ReadWriteOnce 更改为 ReadWriteMany ?这将使卷能够从多个节点挂载。
  • 澄清一下,我说的是持久卷而不是持久卷声明。 pic 应该有 readWriteOnce 因为它将由 statefulset 为每个副本创建一个
  • 请提供kubectl get -o yaml sc/elasticdata的输出
  • ReWriteOnce/readWriteMany 在single node cluster 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 中应该没有区别
  • @Lukman,这是命令的结果:Error from server (NotFound): storageclasses.storage.k8s.io "elasticdata" not found

标签: kubernetes docker-desktop statefulset


【解决方案1】:

让我在 cmets 和 Jonas's 答案中已经说过的话添加一些细节。

从 cmets 推断,您尚未定义名为 elasticdataStorageClass。如果它不存在,则不能在 PVPVC 中引用它。

快速了解如何使用 hostPath 定义 PersistentVolume 以及如何在 PersistentVolumeClaim 中引用它。 Here 您可以看到在示例中使用了 storageClassName: manual。 Kubernetes 文档没有明确说明,但是如果您查看 Openshift docs,它会非常清楚地说明:

使用 hostPath 卷的 Pod 必须手动引用 (静态)配置。

这不仅仅是用于将PVC 请求绑定到此特定PV 的一些值。所以如果elasticdataStorageClass没有被定义,你就不应该在这里使用它。

第二件事。正如Jonas 在他的评论中已经说明的那样,PVCPV 之间存在一对一的绑定,所以不管你的PV 仍然有足够的容量,它已经被另一个PVC 声明了并且不再可用。你可以在官方docs阅读:

PVC 到 PV 的绑定是一对一的映射,使用的 ClaimRef 是 PersistentVolume 和 PersistentVolumeClaim。

如果匹配的卷不存在,则声明将无限期保持未绑定 存在。当匹配的数量可用时,索赔将受到约束。为了 例如,配置有许多 50Gi PV 的集群不会匹配 PVC 请求 100Gi。增加一个 100Gi PV 就可以绑定 PVC 集群。

反之亦然。如果只有一个 100Gi PV,它将无法满足来自两个 PVCs 各自声称 50Gi 的请求。请注意,在您发布的 kubectl get pv,pvc 的结果中,PVPVC 的容量均为 20Gi,尽管您在每个从 PVC 模板创建的 PVC 中仅请求 3Gi

您在这里不使用任何动态存储配置器,因此您需要根据您的用例需要手动提供尽可能多的PersistentVolumes

顺便说一句,我宁愿建议您使用local 音量和正确定义的StorageClass,而不是使用hostPath。它比HostPath 有一些优势。此外,可以单独运行外部静态配置器,以改进对本地卷生命周期的管理

【讨论】:

    【解决方案2】:

    当使用StatefulSetvolumeClaimTemplates 时,它将为每个副本创建一个PersistentVolumeClaim。所以如果你使用replicas: 2,将会创建两个不同的PersistentVolumeClaims,es-data-esnode-0es-data-esnode-1

    每个PersistentVolumeClaim 将绑定到一个唯一的PersistentVolume,因此对于两个PVC,您需要两个不同的PersistentVolumes。但这并不容易在桌面设置中使用volumeClaimTemplatehostPath-volumes。

    在这种情况下,您需要replicas: 2 的原因是什么?它通常用于提供更好的可用性,例如使用多个节点。但是对于桌面环境中的本地设置,通常单个节点上的单个副本应该可以吗?我认为对您来说最简单的解决方案是使用replicas: 1

    【讨论】:

    • 您好,感谢您的解释,但我需要构建一个 Elastic 集群,因此至少需要 2 个实例。我使用 VolumeClaimsTemplates 创建两个 PersistantVolumesClaims,但它不起作用。只有第一个被创建并绑定到 PersistantVolume,另一个没有。 Each PersistentVolumeClaim will bound to an unique PersistentVolume 很有趣,因为我认为它仅通过 StorageClassName 和容量链接。每个pvc需要3Gi,一共6Gi。 PV 提供 20Gi。它们共享相同的 StorageClassName。还不够吗?
    • 只有一个 PV 时,它不适用于两个 PVC。使用两个 PVC 时,需要两个 PV。
    猜你喜欢
    • 2021-01-06
    • 2022-10-18
    • 2020-12-27
    • 2019-03-11
    • 1970-01-01
    • 2020-12-19
    • 2022-01-11
    • 2022-01-10
    • 2019-12-07
    相关资源
    最近更新 更多