0

我正在尝试使用 Minikube 中的 MongoDB Community Kubernetes Operator 部署 MongoDB 副本集。
我按照官方 GitHub 上的说明进行操作,所以:

  • 安装 CRD
  • 安装必要的角色和角色绑定
  • 安装 Operator 部署 Replicaset

默认情况下,operator 将创建三个 pod,每个 pod 都自动链接到一个新的持久卷声明,该声明绑定到一个由 operator 创建的新持久卷(到目前为止一切都很好)。

但是,我希望将数据保存在特定的卷中,并安装在特定的主机路径中。因此,为了我需要创建三个持久卷,每个都安装到特定的主机路径,然后我想自动配置副本集,以便每个 pod 连接到其各自的持久卷(可能使用 matchLabels 选择器)。所以我通过应用以下文件创建了三个卷:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv-00
  namespace: $NAMESPACE
  labels: 
    type: local
    service: mongo
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  hostPath: 
    path: "/mnt/mongodata/00"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv-01
  namespace: $NAMESPACE
  labels: 
    type: local
    service: mongo
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  hostPath: 
    path: "/mnt/mongodata/01"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv-02
  namespace: $NAMESPACE
  labels: 
    type: local
    service: mongo
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  hostPath: 
    path: "/mnt/mongodata/02"

然后我通过以下方式设置副本集配置文件,但仍然无法将 Pod 连接到卷:

apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: mongo-rs
  namespace: $NAMESPACE
spec:
  members: 3
  type: ReplicaSet
  version: "4.4.0"
  persistent: true
  podSpec:
    persistence:
      single: 
        labelSelector: 
          matchLabels:
            type: local
            service: mongo
        storage: 5Gi
        storageClass: manual
  statefulSet:
    spec:
      volumeClaimTemplates:
        - metadata:
            name: data-volume
          spec:
            accessModes: [ "ReadWriteOnce", "ReadWriteMany" ]
            resources:
              requests:
                storage: 5Gi
            selector:
              matchLabels:
                type: local
                service: mongo
            storageClassName: manual
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - ...
  additionalMongodConfig:
    storage.wiredTiger.engineConfig.journalCompressor: zlib

我在网上找不到任何文档,除了mongodb.com_v1_custom_volume_cr.yaml,以前有人遇到过这个问题吗?我怎样才能让它工作?

4

1 回答 1

2

我认为您可能对使用本地类型的卷感兴趣。它的工作原理是这样的:

首先,为本地卷创建一个存储类。类似于以下内容:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

由于它有no-provisioner,因此只有在您手动创建本地 PV 时才能使用。WaitForFirstConsumer相反,将阻止将 PV 附加到无法在 PV 可用的主机上调度的 Pod 的 PVC。

其次,创建本地 PV。与您在示例中创建它们的方式类似,如下所示:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  local:
    path: /path/on/the/host
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - the-node-hostname-on-which-the-storage-is-located

注意定义,它告诉主机上的路径,容量......然后它解释了在集群的哪个节点上可以使用这样的 PV(使用 nodeAffinity)。它还将它们链接到我们早期创建的存储类。因此,如果有人(声明模板)需要该类的存储,它现在会找到这个 PV。

您可以在 3 个不同的节点上创建 3 个 PV。或者在不同路径的同一节点上创建 3 个 PV,您可以根据需要组织事物。

第三,您现在可以使用local-storage声明模板中的类。声明模板可能与此类似:

volumeClaimTemplates:
  - metadata:
      name: the-name-of-the-pvc
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "local-storage"
      resources:
        requests:
          storage: 5Gi

StatefulSet 的每个 Pod 都会尝试在有local-storagePV 可用的节点上调度。


请记住,对于本地存储,或者一般来说,对于使用主机路径的卷。您可能希望将应用程序的各种 Pod 分布在不同的节点上,以便应用程序可以自行抵抗单个节点的故障。


如果您希望能够决定哪个 Pod 链接到哪个卷,最简单的方法是一次创建一个 PV,然后等待 PodBound使用它......在创建下一个之前。这不是最佳的,但它是最简单的方法。

于 2021-07-13T17:41:00.733 回答