如何在Kubernetes中重新连接已释放的PersistentVolume

如何在Kubernetes中重新连接已释放的PersistentVolume,kubernetes,statefulset,Kubernetes,Statefulset,以下是我的总体目标: 运行MongoDB 通过pod故障/更新等保持数据 我采取的方法是: K8S提供商:数字海洋 节点:3 创建一个PVC 创建无头服务 创建一个StatefulSet 下面是一个简化版的配置: apiVersion: v1 kind: PersistentVolumeClaim metadata: name: some-pvc spec: accessModes: - ReadWriteOnce resources: requests:

以下是我的总体目标:

  • 运行MongoDB

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

我采取的方法是:

  • K8S提供商:数字海洋

  • 节点:3

  • 创建一个PVC

  • 创建无头服务

  • 创建一个StatefulSet

下面是一个简化版的配置:

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数据库

将其旋转起来:

kubectl scale-replicas=1 statefulset/my-app数据库

数据将持续存在

但是有一次,当我在扩展StatefleSet和down时,我遇到了这个错误:

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被删除,因为
persistentVolumeClaIncolicy
被设置为
Delete

我将这个新的PV
persistentVolumeClaimpolicy
设置为
Retain
,以确保数据不会被自动删除。。我意识到:我不知道我该如何回收这一PV。早些时候,为了解决“卷附件”错误,我删除了PVC,这将使用我的设置创建另一个新的PV,现在我只剩下发布的
PV中的数据

我的主要问题是:

  • 这听起来像是实现我目标的正确方法吗

  • 我是否应该考虑向动态创建的PV添加
    claimRef
    ,然后使用该claimRef重新创建一个新的PVC,如下所述:

  • 我应该试着让新的
    statefulset
    PVC实际使用旧的PV吗

  • 尝试将旧PV重新连接到正确的节点有意义吗?我该如何做


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

  • 如果
    do block storage
    存储类支持
    ReadWriteMany
    ,则将所有pod数据放在单个卷中

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

更新:

StatefulSet
replicas必须使用部署,然后
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
及其所有副本将其视为一个源。。这就是它的工作原理吗?
副本
只向每个pod发出服务
负载平衡
请求,因此它与数据复制不同。要进行数据复制,应使用mongodb复制。有关更多详细信息,请参见更新。
spec:
  volumeClaimTemplates:
  - metadata:
      name: some-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
      storageClassName: do-block-storage