什么是 MongoDB 副本集?
MongoDB
副本集(Replica-Set
)是一个分布式数据库系统,它包含一个主节点和多个从节点。主节点负责处理所有写操作,从节点用于读取数据。当主节点发生故障时,从节点可以自动选举一个新的主节点。
副本集的主要目的是 提供高可用性和数据冗余
。如果主节点发生故障,系统仍然可用并且数据不会丢失。
接下来我们详细讲解如何在 k8s
中部署 MongoDB
副本集集群模式。
部署步骤
详细拆解 k8s
部署 mongodb
副本集(Replica-Set
)模式相关服务的执行步骤。
1. Secret
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: <base64-encoded-username>
mongo-root-password: <base64-encoded-password>
- 优化建议:确保
<base64-encoded-username>
和<base64-encoded-password>
已经正确编码为Base64
格式。 - 解释:
Secret
用于存储敏感信息,如用户名和密码,以保护这些信息不被直接暴露。
2. ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-init
data:
init-mongo.js: |
rs.initiate(
{
_id : "rs0",
members: [
{ _id: 0, host: "mongodb-replica-set-0.mongodb-replica-set:27017" },
{ _id: 1, host: "mongodb-replica-set-1.mongodb-replica-set:27017" },
{ _id: 2, host: "mongodb-replica-set-2.mongodb-replica-set:27017" }
]
}
)
- 优化建议:确保
init-mongo.js
脚本中的主机名和端口与StatefulSet
中的配置一致。 - 解释:
ConfigMap
用于存储配置文件或脚本,这里用于初始化MongoDB
的副本集。
3. StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb-replica-set
spec:
serviceName: "mongodb-replica-set"
replicas: 3
selector:
matchLabels:
app: mongodb-replica-set
template:
metadata:
labels:
app: mongodb-replica-set
spec:
containers:
- name: mongodb
image: mongo:7.0.14
ports:
- containerPort: 27017
volumeMounts:
- name: mongodb-data
mountPath: /data/db
- name: mongodb-init-scripts
mountPath: /docker-entrypoint-initdb.d
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
- name: MONGO_REPLICA_SET_NAME
value: rs0
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
volumes:
- name: mongodb-init-scripts
configMap:
name: mongodb-init
- 优化建议:
- 确保
volumeClaimTemplates
中的存储请求大小(storage: 20Gi
)符合实际需求。 - 确保
image: mongo:7.0.14
是否最新的稳定版本。
- 确保
- 解释:
StatefulSet
用于管理有状态的应用程序,如MongoDB
副本集。它确保每个Pod
有一个唯一的标识符,并且可以持久化存储数据。
4. Service for MongoDB
apiVersion: v1
kind: Service
metadata:
name: mongodb-replica-set
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: mongodb-replica-set
- 优化建议:确保
clusterIP: None
,这表示这是一个Headless Service
,适用于StatefulSet
。 - 解释:
Service
用于定义如何访问Pod
,Headless Service
不会分配集群IP
,而是通过DNS
解析Pod
的IP
地址。
5. Deployment for Mongo Express
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-express
spec:
replicas: 1
selector:
matchLabels:
app: mongo-express
template:
metadata:
labels:
app: mongo-express
spec:
containers:
- name: mongo-express
image: mongo-express:1.0.2-20-alpine3.19
ports:
- containerPort: 8081
env:
- name: ME_CONFIG_MONGODB_URL
value: "mongodb://<username>:<password>@mongodb-replica-set-0.mongodb-replica-set:27017,mongodb-replica-set-1.mongodb-replica-set:27017,mongodb-replica-set-2.mongodb-replica-set:27017/?replicaSet=rs0"
- name: ME_CONFIG_MONGODB_ENABLE_ADMIN
value: "true"
- name: ME_CONFIG_MONGODB_ADMINUSERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: ME_CONFIG_MONGODB_ADMINPASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
- 优化建议:
- 确保
ME_CONFIG_MONGODB_URL
中的<username>
和<password>
替换为实际的用户名和密码。 - 确保
image: mongo-express:1.0.2-20-alpine3.19
是最新的稳定版本。
- 确保
- 解释:
Deployment
用于管理无状态的应用程序,如Mongo Express
,它提供了一个Web
界面来管理和监控MongoDB
。
6. Service for Mongo Express
apiVersion: v1
kind: Service
metadata:
name: mongo-express
spec:
ports:
- port: 8081
targetPort: 8081
selector:
app: mongo-express
type: LoadBalancer
- 优化建议:确保
type: LoadBalancer
符合你的环境要求,如果你在本地开发环境中,可能需要改为NodePort
。 - 解释:
Service
用于定义如何访问mongo-express
,LoadBalancer
类型通常用于云环境中,提供外部访问。
应用配置
可将上述内容保存为一个文件(例如:k8s-mongodb-replicaset.yaml
):
---
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: <base64-encoded-username>
mongo-root-password: <base64-encoded-password>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-init
data:
init-mongo.js: |
rs.initiate(
{
_id : "rs0",
members: [
{ _id: 0, host: "mongodb-replica-set-0.mongodb-replica-set:27017" },
{ _id: 1, host: "mongodb-replica-set-1.mongodb-replica-set:27017" },
{ _id: 2, host: "mongodb-replica-set-2.mongodb-replica-set:27017" }
]
}
)
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb-replica-set
spec:
serviceName: "mongodb-replica-set"
replicas: 3
selector:
matchLabels:
app: mongodb-replica-set
template:
metadata:
labels:
app: mongodb-replica-set
spec:
containers:
- name: mongodb
image: mongo:7.0.14
ports:
- containerPort: 27017
volumeMounts:
- name: mongodb-data
mountPath: /data/db
- name: mongodb-init-scripts
mountPath: /docker-entrypoint-initdb.d
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
- name: MONGO_REPLICA_SET_NAME
value: rs0
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
volumes:
- name: mongodb-init-scripts
configMap:
name: mongodb-init
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-replica-set
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: mongodb-replica-set
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-express
spec:
replicas: 1
selector:
matchLabels:
app: mongo-express
template:
metadata:
labels:
app: mongo-express
spec:
containers:
- name: mongo-express
image: mongo-express:1.0.2-20-alpine3.19
ports:
- containerPort: 8081
env:
- name: ME_CONFIG_MONGODB_URL
value: "mongodb://<username>:<password>@mongodb-replica-set-0.mongodb-replica-set:27017,mongodb-replica-set-1.mongodb-replica-set:27017,mongodb-replica-set-2.mongodb-replica-set:27017/?replicaSet=rs0"
- name: ME_CONFIG_MONGODB_ENABLE_ADMIN
value: "true"
- name: ME_CONFIG_MONGODB_ADMINUSERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: ME_CONFIG_MONGODB_ADMINPASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
name: mongo-express
spec:
ports:
- port: 8081
targetPort: 8081
selector:
app: mongo-express
type: LoadBalancer
然后使用以下命令将其应用到 Kubernetes
集群中:
kubectl apply -f k8s-mongodb-replicaset.yaml
这样,你就可以在 Kubernetes
中部署一个高可用的 MongoDB
副本集(Replica-Set
)和一个用于管理和监控的 Mongo Express
。
MongoDB 副本集连接字符串
连接字符串是连接到 MongoDB
副本集的必要信息。它包含以下几个部分:
- 主机和端口:指定主节点的主机和端口号。
- 副本集名称:指定要连接的副本集的名称。
- 鉴权信息:如果需要用户名和密码进行身份验证,可以提供鉴权信息。
- 其他选项:其他可选参数,如
SSL
配置、连接超时等。
连接字符串示例
- 示例1:
mongo-express
连接字符串示例
通过上面 k8s-mongodb-replicaset.yaml
文件部署的 MongoDB
副本集连接字符串示例如下:
# 字符串格式
mongodb://username:password@host1:port1,host2:port2,host3:port3/database?replicaSet=myReplicaSet&ssl=true
# 集群部署式例
mongodb://<username>:<password>@mongodb-replica-set-0.mongodb-replica-set:27017,mongodb-replica-set-1.mongodb-replica-set:27017,mongodb-replica-set-2.mongodb-replica-set:27017/?replicaSet=rs0&ssl=true
在上面的示例中,我们提供了用户名<username>
和密码<password>
进行身份验证,并指定了三个主机和端口号以及要连接的副本集名称为 “rs0”
,并且还设置了 SSL
为 true
。
- 示例2:
假设我们有一个 MongoDB
副本集,包含一个主节点和两个从节点。主节点的主机和端口号为 “host1:27017″
,从节点分别为 “host2:27017”
和 “host3:27017″
。我们使用的副本集名称为 “myReplicaSet”
,需要使用用户名 “admin”
和密码 “password”
进行身份验证。
以下是一个示例的连接字符串:
mongodb://admin:password@host1:27017,host2:27017,host3:27017/test?replicaSet=myReplicaSet&ssl=true&authSource=admin
在上面的示例中,我们连接到了该副本集的主节点,使用了用户名 “admin”
和密码 “password”
进行身份验证,并将数据库设置为 “test”
。副本集的名称为 “myReplicaSet”
,启用了 SSL
连接,并且身份验证数据库为 “admin”
。
连接字符串选项
连接字符串中的选项可以根据需要进行配置。以下是一些常用的选项:
- authSource:指定用于身份验证的数据库,默认为
“admin”
。 - ssl:启用
SSL
连接。 - retryWrites:如果写操作失败,是否自动重试。
- readPreference:读操作的偏好设置,可以是
“primary”、”secondary” 或 “nearest”
。 - readConcern:读操作的一致性级别,可以是
“local”、”majority” 或 “linearizable”
。 - w:写操作的确认级别,可以是
数字或 “majority”
。
这些选项可以根据应用程序的需求进行配置。
总结
K8s
中的 YAML
文件部署说明:
Secret
和ConfigMap
确保了敏感信息和初始化脚本的安全性和正确性。StatefulSet
和Service
确保了MongoDB
副本集(Replica-Set
)的高可用性和数据持久化。Deployment
和Service
确保了Mongo Express
的正常运行和外部访问。
MongoDB
副本集连接字符串说明:
- 连接字符串包含了
必要的信息
,例如:主机和端口号、副本集名称以及身份验证信息
。我们还讨论了一些常用的连接字符串选项
,并给出了一个示例。 - 连接到
MongoDB
副本集可以提供高可用性和数据冗余
,确保系统在主节点故障时仍然可用。通过正确配置连接字符串
,我们可以灵活地管理MongoDB
副本集的连接和访问。