在k8s 中部署有状态服务MongoDB高可用集群详解(附带镜像)

发布于:2024-04-19 ⋅ 阅读:(26) ⋅ 点赞:(0)

🐇明明跟你说过:个人主页

🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅

🔖行路有良友,便是天堂🔖

目录

一、前言

 1、k8s简介

2、MongoDB介绍

3、为什么要使用MongoDB 

4、Mongodb高可用方案 

二、环境准备

1、k8s集群搭建

2、MongoDB镜像准备

3、NFS存储准备

4、PV准备

5、准备configmap文件

6、创建Service

三、创建MongoDB服务

1、导入镜像

2、初始化mongo集群

3、添加外部访问


一、前言

 1、k8s简介

 Kubernetes单词起源于希腊语, 是“舵手”或者“领航员、飞行员”的意思。

Kubernetes(简称K8s)的前世今生可以追溯到谷歌(Google)内部的一个项目,它起源于2003年,当时谷歌正面临着不断增长的应用程序和服务的管理挑战。这个项目最初被称为"Borg",是一个早期的容器编排系统。Borg 的成功经验成为 Kubernetes 开发的契机。

 有关k8s起源的介绍,请参考《初识K8s之前世今生、架构、组件、前景》这篇文章

Kubernetes的优点包括可移植性、可伸缩性和扩展性。它使用轻型的YAML清单文件实现声明性部署方法,对于应用程序更新,无需重新构建基础结构。管理员可以计划和部署容器,根据需要扩展容器并管理其生命周期。借助Kubernetes的开放源代码API,用户可以通过首选编程语言、操作系统、库和消息传递总线来构建应用程序,还可以将现有持续集成和持续交付(CI/CD)工具集成。

2、MongoDB介绍

MongoDB是一个基于分布式文件存储的数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富、最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

3、为什么要使用MongoDB 

  1. 灵活的数据模型:MongoDB采用文档型数据存储,文档以JSON格式存储,无需严格的预定义模式,使得数据存储更加灵活,适应数据模型的变化。
  2. 适用于大规模数据:MongoDB支持水平扩展和垂直扩展,可以处理大规模数据集,并提供高吞吐量和低延迟的查询性能。
  3. 高性能:MongoDB具有高效的查询引擎和索引机制,支持各种复杂的查询操作,并能够快速地返回结果,满足实时数据处理和分析的需求。
  4. 高可用性:MongoDB支持副本集和分片集群,提供自动故障转移和自动恢复功能,确保数据的持久性和可靠性,降低了系统的停机时间。
  5. 丰富的功能:MongoDB提供了丰富的功能和工具,包括复制、分片、索引、聚合框架、地理空间查询等,满足了各种数据管理和分析的需求。
  6. 易于部署和管理:MongoDB提供了简单易用的管理界面和命令行工具,支持各种部署方式,包括单节点部署、副本集部署和分片集群部署,便于开发人员快速构建和部署应用程序。
  7. 活跃的社区和生态系统:MongoDB拥有庞大的开发者社区和丰富的生态系统,提供了各种工具、驱动程序和扩展,支持开发人员快速构建和部署应用程序。

4、Mongodb高可用方案 

MongoDB的高可用方案主要包括复制集(Replica Set)和分片集群(Sharded Cluster)。

复制集:


复制集是MongoDB实现高可用性的基础方案。它由多个MongoDB实例组成,包括一个主节点(Primary)和多个从节点(Secondary)。主节点负责处理所有的写操作,并将数据变更的操作日志(Oplog)复制给从节点。从节点则复制主节点的数据,并可以处理读操作。当主节点发生故障时,从节点会通过选举产生新的主节点,确保服务的连续性。这种架构可以提供一定程度的数据冗余,防止数据丢失。但需要注意的是,复制集最多只能容忍一个节点的故障,当多个节点同时发生故障时,系统将无法正常运行。

分片集群:


分片集群是通过将数据划分为多个分片(Shard)存储在多台服务器上来实现高可用的方案。每个分片可以是一个独立的MongoDB副本集,包含主节点和从节点。应用程序通过路由器(Router)连接到分片集群,并根据分片键将数据路由到相应的分片。这种架构可以实现水平扩展,提高系统的吞吐量和存储能力。

二、环境准备

1、k8s集群搭建

这里我们使用的 k8s 集群的版本是 v1.23.1,如果还未搭建k8s集群,可以参考《在Centos中搭建 K8s 1.23 集群超详细讲解》这篇文章

2、MongoDB镜像准备

准备部署MongoDB所需的docker镜像,离线的镜像包我已经传到资源列表《mongo:4.2的docker镜像离线包》中了,大家可以自行下载,下载完成后,使用 docker load -i mongo.tar.gz 命令导入到work节点即可

3、NFS存储准备

后端存储我们使用网络存储NFS,这样,即使Pod漂移或被误删除,数据依然还在,不会丢失,NFS Server 的搭建请参考《搭建NFS服务器,部署k8s集群,并在k8s中使用NFS作为持久化储存》这篇文章

安装完成后,在NFS服务器上,创建3个数据目录,供Mongo集群使用

[root@nfs data]# mkdir /data/mongo-1 -p && mkdir /data/mongo-2 -p && mkdir /data/mongo-3 -p
[root@nfs data]# mkdir /data/mongo-1/data -p && mkdir /data/mongo-2/data -p && mkdir /data/mongo-3/data -p
[root@nfs data]# mkdir /data/mongo-1/key -p && mkdir /data/mongo-2/key -p && mkdir /data/mongo-3/key -p

添加权限

[root@nfs data]# vim /etc/exports
#添加如下内容
/data/ *(rw,sync,no_root_squash)

[root@nfs data]# exportfs -arv
exporting *:/data

4、PV准备

上面在NFS服务器上创建了3个数据目录,用于存储mongo的数据,接下来创建3个PV。调用上面的NFS存储

在k8s Master节点上编辑创建PV的YAML文件

[root@master1 mongo]# vim pv.yaml
# 添加以下内容
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongo-pv-1
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  nfs:
    path: /data/mongo-1
    readOnly: false
    server: 192.168.40.179
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongo-pv-2
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  nfs:
    path: /data/mongo-2
    readOnly: false
    server: 192.168.40.179
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongo-pv-3
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  nfs:
    path: /data/mongo-3
    readOnly: false
    server: 192.168.40.179
[root@master1 mongo]# kubectl apply -f  pv.yaml
persistentvolume/mongo-pv-1 created
persistentvolume/mongo-pv-2 created
persistentvolume/mongo-pv-3 created

5、准备configmap文件

[root@master1 mongo]# vim config.yaml
# 添加如下内容
apiVersion: v1
data:
  mongod.conf: |-
    dbpath=/mongo/data
    #logpath=/mongo/log/mongodb.log
    pidfilepath=/mongo/key/master.pid
    directoryperdb=true
    logappend=true
    bind_ip=0.0.0.0
    port=27017
kind: ConfigMap
metadata:
  name: mongodb-conf
  namespace: mongo
[root@master1 mongo]# kubectl apply -f  config.yaml

6、创建Service

在k8s Master节点上编写创建Service所需的YAML文件

[root@master1 mongo]# vim service.yaml
#输入以下内容
apiVersion: v1
kind: Service
metadata:
  namespace: mongo
  name: mongo-1 #需要与podname同名
  labels:
    name: mongo
spec:
  ports:
  - name: mongo-port
    port: 27017
  clusterIP: None
  selector:
    name: mongo-1
---
apiVersion: v1
kind: Service
metadata:
  namespace: mongo
  name: mongo-2 #需要与podname同名
  labels:
    name: mongo
spec:
  ports:
  - name: mongo-port
    port: 27017
  clusterIP: None
  selector:
    name: mongo-2
---
apiVersion: v1
kind: Service
metadata:
  namespace: mongo
  name: mongo-3 #需要与podname同名
  labels:
    name: mongo
spec:
  ports:
  - name: mongo-port
    port: 27017
  clusterIP: None
  selector:
    name: mongo-3
[root@master1 mongo]# kubectl apply -f  service.yaml

三、创建MongoDB服务

1、导入镜像

在k8s 各work节点上,导入mongo的镜像

[root@node1 ~]# docker load -i mongo.tar.gz

2、编辑创建mongo的YAML文件

[root@master1 mongo]# vim mongo-sts.yaml
#添加如下内容
apiVersion: apps/v1
kind: StatefulSet
metadata: 
  namespace: mongo
  name: mongo-1
spec: 
  selector: 
    matchLabels: 
      name: mongo-1
  serviceName: "mongo-1"
  replicas: 1
  podManagementPolicy: Parallel
  template: 
    metadata: 
      labels: 
        name: mongo-1
        app: mongo-cluster
    spec: 
      containers: 
      - name: mongo
        image: mongo:4.2
        imagePullPolicy: IfNotPresent
        command:  
        - mongod 
        - "-f"
        - "/etc/mongod.conf"
        - "--bind_ip_all"
        - "--replSet"
        - rs0
        ports: 
        - containerPort: 27017
        volumeMounts: 
        - name: mongo-cnf-volume
          mountPath: /etc/mongod.conf/
          subPath: mongod.conf
        - name: mongo-dir 
          mountPath: /mongo
      volumes:
        - name: mongo-cnf-volume     #映射configMap信息
          configMap:
            name: mongodb-conf
            items:
              - key: mongod.conf
                path: mongod.conf

  volumeClaimTemplates:
  - metadata:
      name: mongo-dir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata: 
  namespace: mongo
  name: mongo-2
spec: 
  selector: 
    matchLabels: 
      name: mongo-2
  serviceName: "mongo-2"
  replicas: 1
  podManagementPolicy: Parallel
  template: 
    metadata: 
      labels: 
        name: mongo-2
        app: mongo-cluster
    spec: 
      containers: 
      - name: mongo
        image: mongo:4.2
        imagePullPolicy: IfNotPresent
        command:  
        - mongod 
        - "-f"
        - "/etc/mongod.conf"
        - "--bind_ip_all"
        - "--replSet"
        - rs0
        ports: 
        - containerPort: 27017
        volumeMounts: 
        - name: mongo-cnf-volume
          mountPath: /etc/mongod.conf/
          subPath: mongod.conf
        - name: mongo-dir
          mountPath: /mongo
      volumes:
        - name: mongo-cnf-volume     #映射configMap信息
          configMap:
            name: mongodb-conf
            items:
              - key: mongod.conf
                path: mongod.conf

  volumeClaimTemplates:
  - metadata:
      name: mongo-dir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata: 
  namespace: mongo
  name: mongo-3
spec: 
  selector: 
    matchLabels: 
      name: mongo-3
  serviceName: "mongo-3"
  replicas: 1
  podManagementPolicy: Parallel
  template: 
    metadata: 
      labels: 
        name: mongo-3
        app: mongo-cluster
    spec: 
      containers: 
      - name: mongo
        image: mongo:4.2
        imagePullPolicy: IfNotPresent
        command:  
        - mongod 
        - "-f"
        - "/etc/mongod.conf"
        - "--bind_ip_all"
        - "--replSet"
        - rs0
        ports: 
        - containerPort: 27017
        volumeMounts: 
        - name: mongo-cnf-volume
          mountPath: /etc/mongod.conf/
          subPath: mongod.conf
        - name: mongo-dir
          mountPath: /mongo
      volumes:
        - name: mongo-cnf-volume     #映射configMap信息
          configMap:
            name: mongodb-conf
            items:
              - key: mongod.conf
                path: mongod.conf

  volumeClaimTemplates:
  - metadata:
      name: mongo-dir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
[root@master1 mongo]# kubectl apply -f  mongo-sts.yaml 
[root@master ~]# kubectl exec -it mongo-1-0 -n mongo -- /bin/bash

2、初始化mongo集群

进入到第一个pod中

[root@master ~]# kubectl exec -it mongo-1-0 -n mongo -- /bin/bash
root@mongo-1-0:/# mongo

初始化集群

rs.initiate({  _id:"rs0", // replSet指定的名称
  members:[{    _id:0,    host:"mongo-1.mongo.svc.cluster.local:27017" // 主节点ip与端口,
  }]
})

将mongo-2和mongo-3加入到集群

rs0:PRIMARY> rs.add("mongo-2.mongo.svc.cluster.local:27017")
rs0:PRIMARY> rs.add("mongo-3.mongo.svc.cluster.local:27017")

3、添加外部访问

[root@master mongo]# vim nodeport.yaml
#添加如下内容
#master nodeport service
apiVersion: v1
kind: Service
metadata:
  name: mongo-1-front-service
  labels:
    name: mongo-1
  namespace: mongo
spec:
  selector:
    name: mongo-1
  type: NodePort
  externalTrafficPolicy: Cluster
  ports:
    - name: mongo-http
      nodePort: 30882
      port: 27017
      protocol: TCP
      targetPort: 27017
---
#slave nodeport service
apiVersion: v1
kind: Service
metadata:
  name: mongo-2-front-service
  labels:
    name: mongo-2
  namespace: mongo
spec:
  selector:
    name: mongo-2
  type: NodePort
  externalTrafficPolicy: Cluster
  ports:
    - name: mongo-http
      nodePort: 30883
      port: 27017
      protocol: TCP
      targetPort: 27017
---
#slave nodeport service
apiVersion: v1
kind: Service
metadata:
  name: mongo-3-front-service
  labels:
    name: mongo-3
  namespace: mongo
spec:
  selector:
    name: mongo-3
  type: NodePort
  externalTrafficPolicy: Cluster
  ports:
    - name: mongo-http
      nodePort: 30883
      port: 27017
      protocol: TCP
      targetPort: 27017
[root@master mongo]# kubectl  apply -f  nodeport.yaml

至此,mongo集群部署完成,通过nodeport即可外部访问使用

💕💕💕每一次的分享都是一次成长的旅程,感谢您的陪伴和关注。希望这些关于Kubernetes的文章能陪伴您走过技术的一段旅程,共同见证成长和进步!😺😺😺

🧨🧨🧨让我们一起在技术的海洋中探索前行,共同书写美好的未来!!!


网站公告

今日签到

点亮在社区的每一天
去签到