前言
Kubernetes 是目前最流行的容器编排平台,而 MongoDB 是最流行的 NoSQL 数据库之一。将 MongoDB 部署在 Kubernetes 上,可以在保持高可用性和可伸缩性的同时,减少运维的复杂性。本篇文章将介绍在 Kubernetes 上运行 MongoDB 的最佳实践。
环境准备
在开始部署 MongoDB 前,需要准备以下环境:
- Kubernetes 集群
- 持久化存储(例如,nfs、ceph 等)
- TLS 证书(可选)
部署 MongoDB
- 创建一个 StatefulSet
Kubernetes 提供了 StatefulSet API 对有状态的应用进行管理。一个 MongoDB 部署通常包含多个节点组成的复制集,因此我们将创建一个 StatefulSet,每个 pod 中运行一个 MongoDB 实例。以下是一个 StatefulSet 的 YAML 配置示例:
apiVersion: apps/v1 kind: StatefulSet metadata: name: mongodb spec: serviceName: "mongodb" replicas: 3 # 副本数 selector: matchLabels: app: mongodb template: metadata: labels: app: mongodb spec: containers: - name: mongodb image: mongo command: - mongod args: - "--bind_ip" - "0.0.0.0" - "--replSet" - "rs0" ports: - containerPort: 27017 volumeMounts: - name: mongodb-persistent-storage mountPath: /data/db volumeClaimTemplates: - metadata: name: mongodb-persistent-storage spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 100Gi
- 创建能够自动加入复制集的 ConfigMap
在复制集中,每个实例需要知道其他实例的信息,因此我们需要为每个实例创建一个配置文件。我们可以为每个实例生成一个单独的 YAML 文件,或者创建一个 ConfigMap。
apiVersion: v1 kind: ConfigMap metadata: name: mongodb-config data: mongodb-node1.yml: |- storage: dbPath: /data/db net: port: 27017 bindIp: mongodb-0.mongodb.default.svc.cluster.local replication: replSetName: rs0 mongodb-node2.yml: |- storage: dbPath: /data/db net: port: 27017 bindIp: mongodb-1.mongodb.default.svc.cluster.local replication: replSetName: rs0 mongodb-node3.yml: |- storage: dbPath: /data/db net: port: 27017 bindIp: mongodb-2.mongodb.default.svc.cluster.local replication: replSetName: rs0
在以上示例中,我们使用了 ConfigMap 来存储复制集的配置信息,并指定了每个实例的 YAML 配置文件。
- 创建一个 Service
apiVersion: v1 kind: Service metadata: name: mongodb spec: selector: app: mongodb ports: - name: mongo port: 27017 targetPort: 27017 clusterIP: None
以上配置创建了一个 headless service,它不会创建负载均衡器,因为我们直接访问每个 pod 的 IP 地址。我们将通过 Service Name(即 mongodb)进行访问。
- 初始化复制集
在 StatefulSet 中创建的 MongoDB 实例还没有加入复制集,需要手动初始化。可以在其中一个实例上执行以下命令:
$ kubectl exec mongodb-0 -- sh -c 'echo "rs.initiate({_id: \"rs0\", members: [{ _id: 0, host: \"mongodb-0.mongodb.default.svc.cluster.local:27017\" },{ _id: 1, host: \"mongodb-1.mongodb.default.svc.cluster.local:27017\" },{ _id: 2, host: \"mongodb-2.mongodb.default.svc.cluster.local:27017\" }]})"|mongo'
以上命令将初始化一个名为 rs0 的复制集,并添加所有实例作为成员。
至此,我们已经成功地在 Kubernetes 中部署了 MongoDB 集群。但这仅仅是一个简单的示例,我们还需要完善它。
使用 TLS
如果您的 MongoDB 数据库包含敏感数据,建议使用 TLS 来加密客户端和服务器之间的通信。以下是一些简单的步骤来为 MongoDB 添加 TLS:
- 创建带有自签名证书的 Secret
$ openssl genrsa -out mongodb.key 2048 $ openssl req -new -key mongodb.key -out mongodb.csr # 填写 CSR 中的信息 $ openssl x509 -req -in mongodb.csr -signkey mongodb.key -out mongodb.crt $ kubectl create secret tls mongodb-tls --key mongodb.key --cert mongodb.crt
以上命令将生成一个自签名证书,然后用它创建一个 Secret。
- 更新 StatefulSet 配置
apiVersion: apps/v1 kind: StatefulSet metadata: name: mongodb spec: serviceName: mongodb replicas: 3 selector: matchLabels: app: mongodb template: metadata: labels: app: mongodb spec: containers: - name: mongodb image: mongo command: - mongod args: - "--bind_ip" - "0.0.0.0" - "--replSet" - "rs0" - "--sslMode" - "requireSSL" - "--sslPEMKeyFile" - "/etc/ssl/mongodb.pem" ports: - containerPort: 27017 volumeMounts: - name: mongodb-persistent-storage mountPath: /data/db - name: mongo-tls mountPath: /etc/ssl volumeClaimTemplates: - metadata: name: mongodb-persistent-storage spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 100Gi volumeMounts: - name: mongo-tls readOnly: true mountPath: /etc/ssl
在以上配置中,我们添加了一些参数来开启 TLS,并挂载了创建的 Secret。
- 更新 Service 配置
apiVersion: v1 kind: Service metadata: name: mongodb spec: selector: app: mongodb ports: - name: mongo port: 27017 targetPort: 27017 protocol: TCP clusterIP: None type: LoadBalancer loadBalancerIP: 10.0.0.25 tls: - secretName: mongodb-tls hosts: - mongodb.example.com
在以上配置中,我们添加了以下参数:
type
:指定 LoadBalancer 类型。loadBalancerIP
:指定 LoadBalancer 的 IP 地址。tls
:指定使用的 Secret 和主机名。
总结
本篇文章介绍了如何在 Kubernetes 上运行 MongoDB,并添加了 TLS 加密。以上内容只是一个示例,实际场景可能需要更多的配置。通过使用 Kubernetes 和 MongoDB,可以更轻松地管理和扩展数据库,从而提高系统的可用性和灵活性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ab1ed3add4f0e0ff4b9777