Akemi

k8s部署MongoDB主从集群

2024/06/13

Mongodb概述

MongoDB是一款为web应用程序和互联网基础设施设计的数据库管理系统。是NoSQL类型的数据库。

特点

(1)MongoDB提出的是文档、集合的概念,使用BSON(类JSON)作为其数据模型结构,使用这样的数据模型,使得MongoDB能在生产环境中提供高读写的能力,吞吐量较于mysql等SQL数据库大大增强。
(2)易伸缩,自动故障转移。易伸缩指的是提供了分片能力,能对数据集进行分片,数据的存储压力分摊给多台服务器。自动故障转移是副本集的概念,MongoDB能检测主节点是否存活,当失活时能自动提升从节点为主节点,达到故障转移。
(3)数据模型因为是面向对象的,所以可以表示丰富的、有层级的数据结构,比如博客系统中能把“评论”直接怼到“文章“的文档中,而不必像myqsl一样创建三张表来描述这样的关系。

MongoDB高可用方案

主从

优点:将读写分离,在不同的DB上操作,可以有效降低数据库的压力,而且还能实现数据的备份
缺点:master节点故障的时候,不能及时的自动的切换到slaves节点,需要手动干预

副本集

优点:实现了主从模式的读写分离,没有固定的“主节点;整个副本集会选出一个节点作为“主节点”,当其挂掉后,再在剩下的从节点中选举一个节点成为新的“主节点”,在副本集中总有一个主节点(primary)和一个或多个备份节点(secondary)。
缺点:由于数据没有shard,每个节点都是一个完整的备份,则不能使用MongoDb的分布式计算功能,当然,也可以通过程序自己来实现(成本很高)

分片

优点:可以将数据自动的分解成多个块,存储在不同的节点上,每个被差分的块都有三个副本集,这样是为了数据备份和恢复,而且数据分片以后,可以利用多台廉价的存储和CPU的计算构建一个水平可扩展的计算架构,这就是我们的分布式计算

常用版本:4.0,4.2,4.4 LTS

主从方式部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
环境:
k8s 1.28.1
MongoDB版本4.2

1.用nfs供应商提供持久化存储
创建的存储类名称为nfs
到时候用卷申请模板来申请

2.创建MongoDB的配置文件
cat config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-conf
namespace: default
data:
mongod.conf: |-
dbpath=/mongo/data # 数据目录
pidfilepath=/mongo/key/master.pid #pid文件位置
directoryperdb=true # 是否为每个数据库创建单独的目录
logappend=true # 日志文件是否追加
bind_ip=0.0.0.0 # 监听所有网络接口
port=27017 # 监听端口号27017

3.创建无头服务
创建两个,分别给主从节点
cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: mongo-1
labels:
name: mongo-1
spec:
ports:
- name: mongo-port
port: 27017
clusterIP: None
selector:
name: mongo-1
---
apiVersion: v1
kind: Service
metadata:
name: mongo-2
labels:
name: mongo-2
spec:
ports:
- name: mongo-port
port: 27017
clusterIP: None
selector:
name: mongo-2

4.创建statefulset部署MongoDB
cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: default
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: 192.168.10.130/library/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" ]
storageClassName: nfs
resources:
requests:
storage: 5Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: default
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: 192.168.10.130/library/mongo:4.2
imagePullPolicy: IfNotPresent
command:
- mongod
- "-f"
- "/etc/mongod.conf"
- "--bind_ip_all"
- "--replSet"
- rs0
ports:
- containerPort: 27017
lifecycle:
postStart:
exec:
command:
- /bin/bash
- -c
- mkdir /mongo/key && touch /mongo/key/master.pid
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" ]
storageClassName: nfs
resources:
requests:
storage: 5Gi

**报错解决**
ERROR: Cannot write pid file to /mongo/key/master.pid: No such file or directory
解决方法:在/mongo下创建key文件夹和master.pid文件
(我使用的是nfs存储,目录在/data/v1/default-mongo-dir-mongo-1-0-pvc-c59a24cc-dd18-41da-b60f-a3aa71bf6622
在这里创建key文件夹就行了)

NonExistentPath: Data directory /mongo/data not found
解决方法:在/mongo下创建data目录

Sessions collection is not set up; waiting until next sessions reap interval: config.system.sessions does not exist
MongoDB 正在使用默认的会话缓存行为,但由于还没有创建 config.system.sessions 集合
它当前无法缓存逻辑会话

正常运行:
kubectl get pods
NAME READY STATUS RESTARTS AGE
mongo-1-0 1/1 Running 2 (5m10s ago) 5m11s
mongo-2-0 1/1 Running 2 (5m10s ago) 5m11s

集群初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
1.进入刚刚部署好的一个mongo-1
kubectl exec -it mongo-1-0 -- /bin/bash

#连接mongo数据库
mongo
#初始化集群
rs.initiate({ _id:"rs0", // replSet指定的名称
members:[{ _id:0, host:"mongo-1.default.svc.cluster.local:27017" // 主节点ip与端口,
}]
})
# { "ok" : 1 }

#mongo-2加入集群
rs.add("mongo-2.default.svc.cluster.local:27017")// 将mongo-2加入集群

#{
# "ok" : 1,
# "$clusterTime" : {
# "clusterTime" : Timestamp(1718255862, 1),
# "signature" : {
# "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
# "keyId" : NumberLong(0)
# }
# },
# "operationTime" : Timestamp(1718255862, 1)
#}

6、把mongo映射到外部,通过外部访问
vim nodeport-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mongo-1-front-service # 主节点
labels:
name: mongo-1
namespace: default
spec:
selector:
name: mongo-1
type: NodePort
externalTrafficPolicy: Cluster
ports:
- name: mongo-http
nodePort: 30882
port: 27017
protocol: TCP
targetPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongo-2-front-service # 从节点
labels:
name: mongo-2
namespace: default
spec:
selector:
name: mongo-2
type: NodePort
externalTrafficPolicy: Cluster
ports:
- name: mongo-http
nodePort: 30883
port: 27017
protocol: TCP
targetPort: 27017

部署完成之后
开发要连接mango的时候直接使用192.168.10.121:30882和192.168.10.121:30883就能连接

CATALOG
  1. 1. Mongodb概述
  2. 2. MongoDB高可用方案
  3. 3. 主从方式部署
    1. 3.1. 集群初始化