【问题标题】:Can 3 replicas use the same PersistentVolume in a StatefulSet in Kubernetes?3 个副本可以在 Kubernetes 的 StatefulSet 中使用相同的 PersistentVolume 吗?
【发布时间】:2020-09-23 16:24:57
【问题描述】:

我创建了一个 StatefulSet 用于运行具有 3 个副本的 NodeJS,并希望附加到一个 gce 磁盘,该磁盘可以成为用户上传文件的数据存储。

我的项目命名:carx;服务器名称:car-server

但是,我在创建第二个 pod 时遇到了错误。

kubectl describe pod car-server-statefulset-1

AttachVolume.Attach 为卷“my-app-data”失败:googleapi:错误 400: RESOURCE_IN_USE_BY_ANOTHER_RESOURCE - 磁盘资源 'projects/.../disks/carx-disk' 已被 'projects/.../instances/gke-cluster-...-2dw1'


car-server-statefulset.yml

apiVersion: v1
kind: Service
metadata:
  name: car-server-service
  labels:
    app: car-server
spec:
  ports:
  - port: 8080
    name: car-server
  clusterIP: None
  selector:
    app: car-server
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: car-server-statefulset
spec:
  serviceName: "car-server-service"
  replicas: 3
  template:
    metadata:
      labels:
        app: car-server
    spec:
      containers:
        - name: car-server
          image: myimage:latest
          ports:
            - containerPort: 8080
              name: nodejs-port
          volumeMounts:
          - name: my-app-data
            mountPath: /usr/src/app/mydata
      volumes:
      - name: my-app-data
        persistentVolumeClaim:
          claimName: example-local-claim
  selector:
    matchLabels:
      app: car-server

pvc.yml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: example-local-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-app-data
  labels:
    app: my-app
spec:
  capacity:
    storage: 60Gi
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  gcePersistentDisk:
    pdName: carx-disk
    fsType: ext4

【问题讨论】:

    标签: kubernetes persistent-volumes kubernetes-statefulset persistent-volume-claims gce-persistent-disk


    【解决方案1】:

    Access Mode 字段被视为请求,但不确定您是否获得了请求。在您的情况下,GCEPersistentDisk 仅支持ReadWriteOnceReadOnlyMany

    您的 PV 现在挂载为 ReadWriteOnce,但只能同时挂载在 一个 节点上。所以其他副本将无法挂载该卷。

    使用StatefulSet 时,每个副本通常使用自己的卷,为此使用StatefulSet 清单的volumeClaimTemplate: 部分。

    例子:

      volumeClaimTemplates:
      - metadata:
          name: example-claim
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "standard"
          resources:
            requests:
              storage: 5Gi
    

    如果您只能使用单个卷,您可以考虑仅使用一个副本运行 StatefulSet,例如replicas: 1.

    如果您想要磁盘复制,您可以将 StorageClass 用于 区域磁盘,这些磁盘也被复制到另一个 AZ。请参阅Regional Persistent Disk,但它仍然具有相同的访问模式

    【讨论】:

    • 感谢您的回复!如果每个副本使用自己的卷,这些卷中的数据文件不会自动同步?我需要设置另一个配置吗?
    • @potato,是的,这是真的。如果您的应用不复制数据,请仅使用 1 个副本。
    • 也就是说我不能在 GCE 中配置 3 个副本来共享一个 PV 上的数据文件?因为我希望我的应用程序具有可扩展性。那么这是让每个副本使用自己的卷并在卷之间同步数据以实现可扩展应用的正确方法吗?
    • @potato 如果不使用卷,则服务器可扩展性要容易得多,例如使用没有音量的Deployment。也许您可以使用 GCS 存储桶或数据库来代替您想要使用卷的东西?
    • 我的应用程序将允许用户上传每个 1MB 的文件,所以我想像存储图像一样使用磁盘存储。我会查看 GCS 存储桶是否适合我。谢谢你的建议。
    【解决方案2】:

    来自docs

    PD 的一个特点是它们可以被多个安装为只读 消费者同时。这意味着您可以预先填充 PD 使用您的数据集,然后从尽可能多的 Pod 并行提供它 你需要。不幸的是,PD 只能由单个消费者安装 处于读写模式 - 不允许同时写入。

    另一种解决方案是 Google Cloud Filestore,它是一种 NAS 产品。您可以在 Compute Engine 和 Kubernetes Engine 实例中挂载 Filestore。但是,Filestore 的问题在于它在设计时考虑了大型文件存储系统,并且最小容量为 1TB,这对于小型用例来说是昂贵的。

    解决此问题的一种廉价方法是在集群中设置由 ReadWriteOnce PV 备份的 NFS 服务器,然后使用此 NFS 服务器创建基于 NFS 的 PV(支持 ReadWriteMany)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 2022-09-22
      • 2021-08-20
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多