如何在Kubernetes上设置Mongo副本集?

我想在Kubernetes上设置Mongo副本。 我想有三个副本。 这意味着我需要启动3个实例。

我是否应该启动三个豆荚,每个豆荚都配有Mongo,并使用该服务指向小学? 或者我应该使用复制控制器?

这个答案已经过时了。 我使用更新的方法在这里写了一个详细的分步教程。 我强烈build议阅读一切。

简而言之,您可以运行sidecar应用程序为您configuration副本集,并使用每个实例的服务或ping K8s API获取Pod IP地址。

例如:这只适用于Google Cloud。 您需要对其他平台进行修改,特别是在卷的周围:

  1. 请按照https://github.com/leportlabs/mongo-k8s-sidecar.git中的示例进行操作
    • git clone https://github.com/leportlabs/mongo-k8s-sidecar.git
    • cd mongo-k8s-sidecar/example/
    • make add-replica ENV=GoogleCloudPlatform (这样做三次)
  2. 通过服务连接到副本集。
    • mongodb://mongo-1,mongo-2,mongo-3:27017/dbname_?
  3. 您也可以使用原始Pod的IP地址,而不是为每个Pod创build服务

通常情况下,要build立一个像mongo这样的节点集合和复制集合,你需要创build一个Service来跟踪服务名称下的pod(例如,创build一个带有mongodb标签的MongoDB复制控制器,以及一个跟踪这些实例的Service )然后可以查询服务的成员(使用API​​服务器,您可以查找节点

curl -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://kubernetes/api/v1/namespaces/default/endpoints/mongodb

mongodb是你select服务的名字。

返回一个JSON对象与一堆领域,所以一个很好的方法来parsing这些很容易的是使用jq https://stedolan.github.io/jq/

将curl命令滚动到一个jq查询中

jq '.subsets[].addresses[]' | jq '{ip: .ip, host:.targetRef.name}' jq '.subsets[].addresses[]' | jq '{ip: .ip, host:.targetRef.name}'将返回群集中mongodb实例的IP和主机名。

所以现在你知道谁在群集中,你可以在init脚本中创build副本集。 显然,这意味着你需要首先启动Service ,启动脚本需要等待所有的节点启动并注册服务,然后才能继续。 如果您使用一个脚本,使用一个脚本,它将在每个节点上运行,因此您需要检查副本集是否已经存在或处理错误。 第一个注册应该做的工作。 另一种select是将所有节点作为单个节点运行,然后运行一个单独的引导脚本来创build副本集。

最后,你调用mongodb集群,你需要确保你指定了带有副本集名称的url作为选项:

mongodb://mongodb:27017/database?replicaSet=replicaSetName

由于您不知道主服务器的IP,您可以通过服务mongodb来调用服务器,这会将请求负载平衡到其中一个节点,如果您不指定副本集名称,则最终会连接错误,因为只有主人可以得到写入请求。

显然这不是一步一步的教程,但我希望能让你开始。

这是我目前正在运行的示例。

 apiVersion: v1 kind: Service metadata: labels: name: mongo name: mongo-svc1 spec: ports: - port: 27017 targetPort: 27017 selector: type: mongo-rs-A --- apiVersion: v1 kind: Service metadata: labels: name: mongo name: mongo-svc2 spec: ports: - port: 27017 targetPort: 27017 selector: type: mongo-rs-B --- apiVersion: v1 kind: Service metadata: labels: name: mongo name: mongo-svc3 spec: ports: - port: 27017 targetPort: 27017 selector: type: mongo-rs-C --- apiVersion: v1 kind: ReplicationController metadata: name: mongo spec: replicas: 1 selector: name: mongo-nodea role: mongo environment: test template: metadata: labels: name: mongo-nodea role: mongo environment: test type: mongo-rs-A spec: containers: - name: mongo-nodea image: mongo command: - mongod - "--replSet" - rsABC - "--smallfiles" - "--noprealloc" ports: - containerPort: 27017 volumeMounts: - name: mongo-persistent-storage mountPath: /data/db volumes: - name: mongo-persistent-storage flocker: datasetName: FlockerMongoVolSetA --- apiVersion: v1 kind: ReplicationController metadata: name: mongo-1 spec: replicas: 1 selector: name: mongo-nodeb role: mongo environment: test template: metadata: labels: name: mongo-nodeb role: mongo environment: test type: mongo-rs-B spec: containers: - name: mongo-nodeb image: mongo command: - mongod - "--replSet" - rsABC - "--smallfiles" - "--noprealloc" ports: - containerPort: 27017 volumeMounts: - name: mongo-persistent-storage mountPath: /data/db volumes: - name: mongo-persistent-storage flocker: datasetName: FlockerMongoVolSetB --- apiVersion: v1 kind: ReplicationController metadata: name: mongo-2 spec: replicas: 1 selector: name: mongo-nodec role: mongo environment: test template: metadata: labels: name: mongo-nodec role: mongo environment: test type: mongo-rs-C spec: containers: - name: mongo-nodec image: mongo command: - mongod - "--replSet" - rsABC - "--smallfiles" - "--noprealloc" ports: - containerPort: 27017 volumeMounts: - name: mongo-persistent-storage mountPath: /data/db volumes: - name: mongo-persistent-storage flocker: datasetName: FlockerMongoVolSetC kubectl --kubeconfig=clusters/k8s-mongo/kubeconfig get po,svc -L type,role,name NAME READY STATUS RESTARTS AGE TYPE ROLE NAME mongo-1-39nuw 1/1 Running 0 1m mongo-rs-B mongo mongo-nodeb mongo-2-4tgho 1/1 Running 0 1m mongo-rs-C mongo mongo-nodec mongo-rk9n8 1/1 Running 0 1m mongo-rs-A mongo mongo-nodea NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE TYPE ROLE NAME kubernetes 10.3.0.1 <none> 443/TCP <none> 21h <none> <none> <none> mongo-svc1 10.3.0.28 <none> 27017/TCP type=mongo-rs-A 1m <none> <none> mongo mongo-svc2 10.3.0.56 <none> 27017/TCP type=mongo-rs-B 1m <none> <none> mongo mongo-svc3 10.3.0.47 <none> 27017/TCP type=mongo-rs-C 1m <none> <none> mongo 

在主节点上,我将进入mongo shell

rs.status()rs.initiate()rs.add(“10.3.0.56:27017”)

我目前遇到这个问题,我陷入了辅助和启动状态的两个节点没有主。

 rs.status() { "set" : "rsABC", "date" : ISODate("2016-01-21T22:51:33.216Z"), "myState" : 2, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "mongo-rk9n8:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 242, "optime" : { "ts" : Timestamp(1453416638, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-01-21T22:50:38Z"), "infoMessage" : "could not find member to sync from", "configVersion" : 2, "self" : true }, { "_id" : 1, "name" : "10.3.0.56:27017", "health" : 1, "state" : 0, "stateStr" : "STARTUP", "uptime" : 45, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2016-01-21T22:51:28.639Z"), "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"), "pingMs" : NumberLong(40), "configVersion" : -2 } ], "ok" : 1 } 

看看下面的链接。 在kubernetes中,创build服务地址,然后控制器和复制组启动可以很容易地生成…. https://www.mongodb.com/blog/post/running-mongodb-as-a-microservice-with-docker-和kubernetes

@Stephen Nguyen

我只是复制你的情况,并为其创build命名空间testing(我相应地更改你的yaml文件),并初始化我的mongo rs:

 rs.initiate({ "_id" : "rsABC", "members" : [ { "_id" : 0, "host" : "mongo-svc1.test:27017", "priority" : 10 }, { "_id" : 1, "host" : "mongo-svc2.test:27017", "priority" : 9 }, { "_id" : 2, "host" : "mongo-svc3.test:27017", "arbiterOnly" : true } ] }) 

它似乎工作:

 > rs.status() { "set" : "rsABC", "date" : ISODate("2016-05-10T07:45:25.975Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "mongo-svc1.test:27017", "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "mongo-svc1.test:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 657, "optime" : { "ts" : Timestamp(1462865715, 2), "t" : NumberLong(2) }, "optimeDate" : ISODate("2016-05-10T07:35:15Z"), "lastHeartbeat" : ISODate("2016-05-10T07:45:25.551Z"), "lastHeartbeatRecv" : ISODate("2016-05-10T07:45:25.388Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1462865715, 1), "electionDate" : ISODate("2016-05-10T07:35:15Z"), "configVersion" : 1 }, { "_id" : 1, "name" : "mongo-svc2.test:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 1171, "optime" : { "ts" : Timestamp(1462865715, 2), "t" : NumberLong(2) }, "optimeDate" : ISODate("2016-05-10T07:35:15Z"), "syncingTo" : "mongo-svc1.test:27017", "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "mongo-svc3.test:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 657, "lastHeartbeat" : ISODate("2016-05-10T07:45:25.549Z"), "lastHeartbeatRecv" : ISODate("2016-05-10T07:45:23.969Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 } 

我通过服务名称添加mongo节点。

就像单挑一样。 在生产中不要使用mongo-k8s-sidecar方法,因为它有潜在的危险后果。 有关使用MongoDB和k8s StatefulSets的更新方法,请参阅:

  1. 将MongoDB副本集部署为Kubernetes StatefulSet
  2. 在Kubernetes上configurationMongoDB的一些关键生产设置
  3. 在Kubernetes上使用MongoDB的企业版本
  4. 使用Kubernetes StatefulSets部署MongoDB Sharded集群

有关MongoDB和Kubernetes的更多信息,请访问: http ://k8smongodb.net/

我正在使用这个解决scheme。 它尚未准备好。

安装MongoDB复制

获取所有MongoDB pod IP kubectl describe pod <PODNAME> | grep IP | sed -E 's/IP:[[:space:]]+//' kubectl describe pod <PODNAME> | grep IP | sed -E 's/IP:[[:space:]]+//'

和…

运行kubectl exec -i <POD_1_NAME> mongo

和…

 rs.initiate({ "_id" : "cloudboost", "version":1, "members" : [ { "_id" : 0, "host" : "<POD_1_IP>:27017", "priority" : 10 }, { "_id" : 1, "host" : "<POD_2_IP>:27017", "priority" : 9 }, { "_id" : 2, "host" : "<POD_3_IP>:27017", "arbiterOnly" : true } ] }); 

例如 :

 rs.initiate({ "_id" : "cloudboost", "version":1, "members" : [ { "_id" : 0, "host" : "10.244.1.5:27017", "priority" : 10 }, { "_id" : 1, "host" : "10.244.2.6:27017", "priority" : 9 }, { "_id" : 2, "host" : "10.244.3.5:27017", "arbiterOnly" : true } ] }); 

请注意:您的群集的IP可能会有所不同。

TODO:创build一个无头服务来自动发现节点并初始化一个复制集。