【问题标题】:How to reattach released PersistentVolume in Kubernetes如何在 Kubernetes 中重新附加已发布的 PersistentVolume
【发布时间】:2019-05-29 21:01:15
【问题描述】:

这是我的总体目标:

  • 运行 MongoDB

  • 通过 pod 故障/更新等保留数据

我采取的方法:

  • K8S 提供者:数字海洋

  • 节点:3

  • 创建 PVC

  • 创建无头服务

  • 创建有状态集

这是配置的简化版本:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: some-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: do-block-storage
---
apiVersion: v1
kind: Service
metadata:
  name: some-headless-service
  labels:
    app: my-app
spec:
  ports:
  - port: 27017
    name: my-app-database
  clusterIP: None
  selector:
    app: my-app
    tier: database
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-app-database
  labels:
    app: my-app
    tier: database
spec:
  serviceName: some-headless-service
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      tier: database
  template:
    metadata:
      labels:
        app: my-app
        tier: database
    spec:
      containers:
      - name: my-app-database
        image: mongo:latest
        volumeMounts:
        - name: some-volume
          mountPath: /data
        ports:
        - containerPort: 27017
          name: my-app-database
      volumes:
      - name: some-volume
        persistentVolumeClaim:
          claimName: some-pvc

这是按预期工作的。我可以将副本降速到 0:

kubectl scale —replicas=0 statefulset/my-app-database

把它转起来:

kubectl scale —replicas=1 statefulset/my-app-database

而且数据会持续存在..

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

Volume is already exclusively attached to one node and can't be attached to another

作为 k8s 的新手,我删除了 PVC 并“重新创建”了同一个:

kubectl delete pvc some-pvc
kubectl apply -f persistent-volume-claims/

statefulset 使用新 PV 重新启动,旧 PV 被删除,因为 persistentVolumeReclaimPolicy 默认设置为 Delete

我将这个新的 PV persistentVolumeReclaimPolicy 设置为 Retain 以确保数据不会被自动删除.. 我意识到:我不确定如何回收该 PV。之前为了解决“卷附件”错误,我删除了 PVC,它只会使用我的设置创建另一个新 PV,现在我的数据留在了那个 Released PV 中。

我的主要问题是:

  • 这听起来是否适合我的目标?

  • 我是否应该考虑将claimRef 添加到动态创建的 PV,然后使用该 claimRef 重新创建一个新 PVC,如此处所述:Can a PVC be bound to a specific PV?

  • 我是否应该尝试让那个新鲜的statefulset PVC 真正使用那个旧的 PV?

  • 尝试将旧 PV 重新附加到正确的节点是否有意义,我该怎么做?

【问题讨论】:

    标签: kubernetes statefulset


    【解决方案1】:

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

    • 如果 do-block-storage 存储类支持 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
    

    更新:

    StatefulSet副本必须使用mongodb replication部署,那么StatefulSet中的每个pod都将拥有相同的数据存储。

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

    【讨论】:

    • 目前 DigitalOcean do-block-storage StorageClass 仅支持 ReadWriteOnce (20190530)。我需要通过volumeClaimTemplates 阅读有关使用不同卷的更多信息,这让我感到困惑,我可以让 MongoDB 集合分布在不同的卷中,但StatefulSet 及其所有副本会将其视为一个来源......它是如何工作的?
    • Replicas 只向每个 pod 发出 service Load Balance 请求,所以它不同于数据复制。要进行数据复制,您应该使用 mongodb 复制。有关详细信息,请参阅更新
    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    相关资源
    最近更新 更多