MongoDB 社区 Kubernetes 运算符(operator)和自定义持久卷

标签 mongodb kubernetes kubernetes-operator

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

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

默认情况下,运算符(operator)将创建三个 pod,每个 pod 自动链接到一个新的持久卷声明,该声明绑定(bind)到一个新的持久卷声明,该卷声明也由运算符(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 , 有没有人遇到过这个问题?我怎样才能让它发挥作用?

最佳答案

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

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

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

因为它有no-provisioner,只有当你手动创建本地 PV 时它才可用。 WaitForFirstConsumer 将阻止将 PV 附加到 Pod 的 PVC,而该 Pod 无法在 PV 可用的主机上进行调度。

其次,您创建本地 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-storage PV 的节点上。


请记住,对于本地存储或通常使用主机路径的卷...您可能希望将应用程序的各种 Pod 分布在不同的节点上,以便应用程序可以抵抗其上单个节点的故障拥有。


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

关于MongoDB 社区 Kubernetes 运算符(operator)和自定义持久卷,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68366456/

相关文章:

kubernetes - K8s : StatefulSet how to increase time between resatrt of pod in case fails

Elasticsearch 7.2.0 : master not discovered or elected yet, 一次选举至少需要X个节点

mongodb - Grails - MongoDB 和自定义脏检查

go - 在kubernetes node infomation中添加location,让kubectl打印出来

docker - 有没有办法在 Kubernetes 上缓存加载的图像

kubernetes - 如何更新K8S Pod的DNS配置

docker - 无法使用 RabbitMQ 集群 Kubernetes operator 创建 RabbitMQ 实例

javascript - Mongodb 对每个文档数组中的所有相同字段求和 - Map-Reduce

java - 使用 Java-Hadoop 连接器更新 MongoDB 中的现有集合

php - MongoDB - 存储和读取数据的最佳方式