当我们在 kubernetes 中使用一个 pvc 创建具有多个副本的有状态集时会发生什么?

What happens when we create stateful set with many replicas with one pvc in kubernetes?

我是 kubernetes 的新手,这个话题让我很困惑。我了解到有状态集不共享 PV,每个副本都有自己的 PV。另一方面,我看到了在有多个副本的有状态集中使用一个 pvc 的示例。所以我的问题是那会发生什么?由于 PVC 到 PV 是绑定的 1:1 所以一个 pvc 只能绑定到一个 pv,但是每个副本都应该有自己的 PV 那么在这种情况下如何在有状态集中拥有一个 pvc?

我不确定您遵循的是哪个示例并检查了该场景但是是的 PV 和 PVC 是 1:1 映射。

通常,PVC 以 ReadWriteOnly 访问模式附加到 POD,这意味着只有一个 pod 可以执行 ReadWrite.

您可能看到的场景可能是单个 PVC 和单个 PV 附加到多个副本,这可能是由于 ReadWriteMany.

A PersistentVolumeClaim (PVC) is a request for storage by a user. It is similar to a Pod. Pods consume node resources and PVCs consume PV resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g., they can be mounted ReadWriteOnce, ReadOnlyMany or ReadWriteMany, see AccessModes).

在此处阅读有关访问模式的更多信息:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

NFS、EFS等存储类型支持ReadWriteMany访问模式。

When I deploy e.g. nginx as SS and I use one PVC only one PV is created and storage is shared between all replicas.

您的实验是正确的,这是可能的,因为由于对 PV 的依赖,调度程序已将所有 pods 分配到同一节点上。如果节点资源耗尽导致一个 pod 在另一个节点上得到调度,则该 pod 将进入 pending 状态。

您通常应该将 volume claim template 与 StatefulSet 一起使用。正如您在问题中所指出的,这将为每个副本创建一个新的 PersistentVolumeClaim(和一个新的 PersistentVolume)。数据不共享,除非容器进程知道如何在其副本之间复制数据。如果一个 StatefulSet Pod 被删除并重新创建,它将返回相同的底层 PVC 和相同的数据,即使它是在不同的节点上重新创建的。

spec:
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ReadWriteOnce]
        resources:
          requests:
            storage: 1Gi
  template:
    spec:
      containers:
        - name: name
          volumeMounts:
            - name: data
              mountPath: /data

您可以手动创建 PVC 并将其附加到 StatefulSet Pods

# not recommended -- one PVC shared across all replicas
spec:
  template:
    spec:
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: manually-created-pvc
      containers:
        - name: name
          volumeMounts:
            - name: data
              mountPath: /data

但在这种情况下,单个 PVC/PV 将在所有副本之间共享。这通常效果不佳:数据库容器之类的东西会明确检查其存储是否共享,并且这样做可能会出现一系列并发问题。这也可以防止 pods 从 volume types that are straightforward to get generally only support a ReadWriteOnce access mode 开始启动;要获得 ReadWriteMany,您需要在集群外额外配置类似 NFS 服务器的东西。