0

I'm in the process of creating a StatefulSet based on this yaml, that will have 3 replicas. I want each of the 3 pods to connect to a different PersistentVolume.

For the persistent volume I'm using 3 objects that look like this, with only the name changed (pvvolume, pvvolume2, pvvolume3):

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pvvolume
  labels:
    type: local
spec:
  storageClassName: standard
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/nfs"
  claimRef:
    kind: PersistentVolumeClaim
    namespace: default
    name: mongo-persistent-storage-mongo-0

The first of the 3 pods in the StatefulSet seems to be created without issue.

The second fails with the error pod has unbound PersistentVolumeClaims Back-off restarting failed container.

enter image description here

Yet if I go to the tab showing PersistentVolumeClaims the second one that was created seems to have been successful.

enter image description here

If it was successful why does the pod think it failed?

4

1 回答 1

2

我希望 3 个 pod 中的每一个都连接到不同的 PersistentVolume。

  • 为了使其正常工作,您将需要:

    • 供应商(在您发布的链接中有如何在 aws、azure、googlecloud 和 minicube 上设置供应商的示例)或
    • 可以多次挂载的卷(例如 nfs 卷)。但是请注意,在这种情况下,您的所有 pod 都读/写到同一个文件夹,当它们不打算同时锁定/写入相同的数据时,这可能会导致问题。通常的用例是 pod 保存到的上传文件夹,稍后用于只读和此类用例。另一方面,SQL 数据库(如 mysql)并不打算写入此类共享文件夹。
  • 您使用的是 hostPath(指向 /nfs)并将其设置为 ReadWriteOnce(只有一个人可以使用它),而不是您的声明清单中提到的任何一个要求。您还使用“标准”作为存储类,并且在您提供的 url 中有快速和慢速,因此您可能也创建了存储类。

第二个失败,错误 pod has unbound PersistentVolumeClaims Back-off restarting failed container

  • 那是因为第一个 pod 已经获得了它的声明(一次读写,主机路径),如果没有设置正确的配置程序或访问权限,第二个 pod 就不能重用同一个。

如果它成功了,为什么 pod 会认为它失败了?

  • 所有 PVC 都成功绑定到伴随的 PV。但是您永远不会将第二个和第三个 PVC 绑定到第二个或第三个 pod。您正在重试第二个 pod 上的第一个声明,并且第一个声明已在 ReadWriteOnce 模式下绑定(到第一个 pod),并且也不能绑定到第二个 pod,并且您收到错误...

建议的方法

由于您将 /nfs 引用为主机路径,因此可以安全地假设您正在使用某种 NFS 支持的文件系统,因此这是一种替代设置,可以让您通过 nfs 将动态配置的持久卷挂载到尽可能多的 pod根据需要在有状态的集合中

笔记:

  • 这仅回答了在假设 nfs 共享的情况下跨有状态集复制 pod 安装持久卷的原始问题。
  • 对于数据库等动态数据,NFS 并不是真正可取的。通常的用例是上传文件夹或适度的日志记录/备份文件夹。数据库(sql 或 no sql)通常是 nfs 的禁忌。
  • 对于任务/时间关键型应用程序,您可能需要在生产中采用这种方法之前仔细进行时间/压力测试,因为 k8s 和外部 pv 都在中间添加了一些层/延迟。尽管对于某些应用程序这可能就足够了,但请注意它。
  • 您对动态创建的 pv 名称的控制有限(k8s 为新创建的后缀添加后缀,并在被告知这样做的情况下重用可用的旧名称),但 k8s 将在 pod 终止后保留它们并首先分配给新 pod,因此你不会丢失状态/数据。不过,这是您可以通过策略控制的。

脚步:

  • 为此,您首先需要从此处安装 nfs 配置器:

  • 存储类清单:

    kind: StorageClass
    apiVersion: storage.k8s.io/v1beta1
    metadata:
      name: sc-nfs-persistent-volume
    # if you changed this during provisioner installation, update also here
    provisioner: example.com/nfs 
    
  • 有状态集(仅重要摘录):

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: ss-my-app
    spec:
      replicas: 3
      ...
      selector:
        matchLabels:
          app: my-app
          tier: my-mongo-db
      ...
      template:
        metadata:
          labels:
            app: my-app
            tier: my-mongo-db
        spec:
          ...
          containers:
            - image: ...
              ...
              volumeMounts:
                - name: persistent-storage-mount
                  mountPath: /wherever/on/container/you/want/it/mounted
          ...
      ...
      volumeClaimTemplates:
      - metadata:
          name: persistent-storage-mount
      spec:
        storageClassName: sc-nfs-persistent-volume
        accessModes: [ ReadWriteOnce ]
        resources:
          requests:
            storage: 10Gi
      ...
    
于 2018-05-09T09:28:45.767 回答