MongoDB 社区 Kubernetes Operator 和自定义持久卷

MongoDB Community Kubernetes Operator and Custom Persistent Volumes

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

默认情况下,操作员会创建三个 pods,每个都自动链接到一个新的持久卷声明,绑定到一个新的持久卷声明,该卷声明也由操作员创建(到目前为止一切正常)。

但是,我希望将数据保存在特定的卷中,安装在特定的主机路径中。因此,为了我需要创建三个持久卷,每个都挂载到特定的主机路径,然后我想自动配置副本集,以便每个 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"

然后我按照以下方式设置副本集配置文件,但它仍然无法将 pods 连接到卷:

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,以前有人遇到过这个问题吗?我怎样才能让它发挥作用?

我想您可能会对使用本地类型的卷感兴趣。它的工作原理如下:

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

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)。它还将它们 link 存储到我们早先创建的存储空间 class 中。这样,如果有人(声明模板)需要使用该存储空间 class,它现在会找到该 PV。

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

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

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

并且 StatefulSet 的每个 Pod 将尝试调度到具有 local-storage 可用 PV 的节点上。


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


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