3

这是我的总体目标:

  • 运行 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

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

我的主要问题是:

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

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

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

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

4

1 回答 1

1

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

  • 如果do-block-storagestorage class supprt 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

更新:

StatefulSetreplicas必须使用mongodb replication部署,然后每个 podStatefulSet将具有相同的数据存储。

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

于 2019-05-30T09:30:52.090 回答