首页 > 解决方案 > mongodb 副本集 kubernetes 读取查询服务

问题描述

我创建了一个 3 节点集群,在同一个网络中有 3 台物理机。我用这段代码创建了一些持久卷和一个存储类:

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



---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: local1-1pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes1
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local1-2pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes1
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local1-3pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol3
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes1
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local2-1pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes2
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local2-2pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes2
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local2-3pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol3
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes2
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local3-1pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes3
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local3-2pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes3
---

kind: PersistentVolume
apiVersion: v1
metadata:
  name: local3-3pv
  labels:
    type: local
spec:
  storageClassName: localstorage
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /mnt/disk/vol3
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kubernetes3
---

然后我创建了我的 mongo 实例,作为有状态的副本集:

---
apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    app: mongo
spec:
  ports:
  - name: mongo
    port: 27017
    targetPort: 27017
  clusterIP: None
  selector:
    app: mongo

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
       app:  mongo
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        app: mongo
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mongo
        image: mongo
        command:
        - mongod
        - "--replSet"
        - rs0
        - "--bind_ip_all"
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongo-persistent-storage
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 20Gi
      storageClassName: "localstorage"

首先,我使用以下命令初始化我的副本集:

rs.initiate({_id: "rs0", version: 1, members: [
{ _id: 0, host : "mongo-0.mongo:27017" },
{ _id: 1, host : "mongo-1.mongo:27017" },
{ _id: 2, host : "mongo-2.mongo:27017" }
]});

所以现在我要做的是创建一个额外的服务来负责读取查询。我怎样才能做到这一点?最好的情况是我的查询由三个副本集之一自动提供。首先检查主副本,如果不可用,则从辅助副本获取。这容易吗?先感谢您。

标签: mongodbkubernetes

解决方案


如果您想从 mongodb 辅助副本中读取(作为主副本不可用时的替代方案),则不需要任何特殊设置。

您需要做的就是将read-preference参数从primary(默认)更改为primaryPrefered您使用的任何 mongodb 客户端库(它在所有官方库中都支持,我不能保证在非官方库中支持)。

来自文档:

首选

在大多数情况下,操作从主要成员读取,但如果它不可用,则从次要成员读取操作。

如果您想了解 read-preference 参数的其他可能值,请查看mongodb 文档。


推荐阅读