繁体   English   中英

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

[英]How do you set-up Mongo replica set on Kubernetes?

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

我应该开始三个pod,每个都有Mongo,并使用该服务指向主要的? 或者我应该以某种方式使用复制控制器?

这个答案已经过时了。 在这里使用更新的方法编写了详细的分步教程。 我强烈建议您阅读所有内容。

简而言之,您运行一个sidecar应用程序为您配置副本集,并为每个实例使用一个服务或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创建服务

通常情况下,建立一个集群节点集像复制品套蒙戈,你将创建一个Service跟踪的服务名下的吊舱(所以例如,创建一个标签的MongoDB的复制控制器mongodbService跟踪的情况下,然后可以为其成员查询服务(使用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是服务名称的选择器。

返回带有一堆字段的JSON对象,所以很容易解析这些是使用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脚本中创建副本集。 显然,这意味着您需要首先启动Service ,您的启动脚本需要等待所有节点启动并注册服务,然后您可以继续。 如果您使用一个图像,使用一个脚本,它将在每个节点上运行n,因此您需要检查副本集是否已存在或处理错误。 要注册的第一个pod应该完成工作。 另一种选择是将所有节点作为单个节点运行,然后运行一个单独的引导脚本来创建副本集。

最后,然后调用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中,创建服务地址,然后控制器和replicaset启动可以很容易地生成.... https://www.mongodb.com/blog/post/running-mongodb-as-a-microservice-with-docker-和kubernetes

@Stephen Nguyen

我只是复制你的案例并为它创建名称空间测试(我相应地更改你的yaml文件),并通过以下方式初始化我的mongo:

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上配置MongoDB的一些关键生产设置
  3. 在Kubernetes上使用企业版的MongoDB
  4. 使用Kubernetes StatefulSets部署MongoDB Sharded Cluster

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

我正在使用它作为解决方案。 尚未准备就绪。

设置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:创建无头服务以自动发现节点并初始化复制集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM