问题描述
在部署副本集模式的mongodb的时候,当启用认证后,执行rs.status()后,变成了如下状态:
{
"set" : "mytest",
"date" : ISODate("2019-12-24T02:24:30.510Z"),
"myState" : 3,
"term" : NumberLong(6),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastCommittedWallTime" : ISODate("1970-01-01T00:00:00Z"),
"appliedOpTime" : {
"ts" : Timestamp(1577154202, 1),
"t" : NumberLong(6)
},
"durableOpTime" : {
"ts" : Timestamp(1577154202, 1),
"t" : NumberLong(6)
},
"lastAppliedWallTime" : ISODate("2019-12-24T02:23:22.046Z"),
"lastDurableWallTime" : ISODate("2019-12-24T02:23:22.046Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1577154202, 1),
"lastStableCheckpointTimestamp" : Timestamp(1577154202, 1),
"members" : [
{
"_id" : 0,
"name" : "10.38.160.174:27017",
"ip" : "10.38.160.174",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING",
"uptime" : 54,
"optime" : {
"ts" : Timestamp(1577154202, 1),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2019-12-24T02:23:22Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "10.38.160.174:27027",
"ip" : "10.38.160.174",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2019-12-24T02:24:30.466Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"authenticated" : false,
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 2,
"name" : "10.38.160.174:27037",
"ip" : "10.38.160.174",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2019-12-24T02:24:30.466Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"authenticated" : false,
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
}
],
"ok" : 1
}
具体的表现就是,当前登录的节点变成了RECOVERING
的状态,其他节点变成了 (not reachable/healthy)
的状态。
问题原因
原因就是当启用认证后,不仅客户端连接需要认证,服务内部不同节点之间,也是需要相互认证的,如果仅仅是启用认证方式,不设定服务内部之间的认证参数,则服务内部各节点之间是无法成功通信的,就造成了当前登录节点一直是恢复中的状态,而其他节点应该是 not reachable
的状态,所以会显示为 not reachable/healthy
。
问题解决
只需要在启用认证的时候,加上节点内容认证参数即可,mongodb提供了两种方式:一种是 keyfile的方式,一种是证书方式,详细内容参见:Internal/Membership Authentication
我采用的是简单的keyfile的方式,只需要在启动的时候,加上 --keyFile=key/file/path 即可