如何在 Kubernetes 中重新附加已发布的 PersistentVolume

Jas*_*rey 6 kubernetes statefulset

这是我的总体目标:

\n\n
    \n
  • 运行 MongoDB

  • \n
  • 通过 Pod 故障/更新等保留数据

  • \n
\n\n

我\xe2\x80\x99采取的方法:

\n\n
    \n
  • K8S提供商:数字海洋

  • \n
  • 节点:3

  • \n
  • 创建PVC

  • \n
  • 创建无头服务

  • \n
  • 创建一个 StatefulSet

  • \n
\n\n

这里\xe2\x80\x99是配置的简化版本:

\n\n
apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: some-pvc\nspec:\n  accessModes:\n  - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: do-block-storage\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: some-headless-service\n  labels:\n    app: my-app\nspec:\n  ports:\n  - port: 27017\n    name: my-app-database\n  clusterIP: None\n  selector:\n    app: my-app\n    tier: database\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n  name: my-app-database\n  labels:\n    app: my-app\n    tier: database\nspec:\n  serviceName: some-headless-service\n  replicas: 1\n  selector:\n    matchLabels:\n      app: my-app\n      tier: database\n  template:\n    metadata:\n      labels:\n        app: my-app\n        tier: database\n    spec:\n      containers:\n      - name: my-app-database\n        image: mongo:latest\n        volumeMounts:\n        - name: some-volume\n          mountPath: /data\n        ports:\n        - containerPort: 27017\n          name: my-app-database\n      volumes:\n      - name: some-volume\n        persistentVolumeClaim:\n          claimName: some-pvc\n
Run Code Online (Sandbox Code Playgroud)\n\n

这按预期工作。我可以将副本旋转到 0:

\n\n

kubectl scale \xe2\x80\x94replicas=0 statefulset/my-app-database

\n\n

将其旋转回来:

\n\n

kubectl scale \xe2\x80\x94replicas=1 statefulset/my-app-database

\n\n

并且数据将持续存在..

\n\n

但是有一次,当我通过上下缩放有状态集来搞乱时,我遇到了这个错误:

\n\n
Volume is already exclusively attached to one node and can\'t be attached to another\n
Run Code Online (Sandbox Code Playgroud)\n\n

作为 k8s 新手,我删除了 PVC 和 \xe2\x80\x9crecreated\xe2\x80\x9d 相同的:

\n\n
kubectl delete pvc some-pvc\nkubectl apply -f persistent-volume-claims/\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用新的 PV旋转备份,并按照默认设置statefulset删除旧的 PV 。persistentVolumeReclaimPolicyDelete

\n\n

我将这个新的PV设置persistentVolumeReclaimPolicyRetain确保数据不会被自动删除..并且我意识到:我\xe2\x80\x99m不确定我\xe2\x80\x99d如何回收该PV。早些时候,为了解决 \xe2\x80\x9cvolumeattachment\xe2\x80\x9d 错误,我删除了 PVC,这只会使用我的设置创建另一个新的 PV,现在我\xe2\x80\x99m 留下了我的该 PV 中的数据Released

\n\n

我的主要问题是:

\n\n
    \n
  • 总体而言,这听起来是实现我的目标的正确方法吗?

  • \n
  • 我是否应该考虑添加 aclaimRef到动态创建的 PV,然后使用该 ClaimRef 重新创建一个新的 PVC,如此处所述:Can a PVC be bond to a certain PV?

  • \n
  • 我应该尝试让新鲜的statefulsetPVC 真正使用旧的 PV 吗?

  • \n
  • 尝试将旧 PV 重新连接到正确的节点是否有意义,我将如何做到这一点?

  • \n
\n

men*_*nya 1

如果您想使用StatefulSet可扩展性,您的存储也应该支持这一点,有两种方法可以处理这个问题:

  • 如果do-block-storage存储类别为 support ReadWriteMany,则将所有 pod 的数据放在单个卷中。

  • 每个 pod 使用不同的卷,添加volumeClaimTemplate到您的StatefulSet.spec,然后 k8s 将some-pvc-{statefulset_name}-{idx}自动创建 PVC,如下所示:

spec:
  volumeClaimTemplates:
  - metadata:
      name: some-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
      storageClassName: do-block-storage
Run Code Online (Sandbox Code Playgroud)

更新:

StatefulSet副本必须使用mongodb 复制进行部署,然后每个 pod 都StatefulSet将具有相同的数据存储。

所以当容器运行mongod命令时,必须添加 option --replSet={name}。当所有 pod 启动后,执行命令rs.initiate()告诉 mongodb 如何处理数据复制。当你放大或缩小时StatefulSet,执行命令rs.add()rs.remove()告诉mongodb成员发生了变化。