Kubernetes部署MongoDB集群(二):创建用户数据库(replicaset)

本文为系列第二部分,使用第一部分安装好的MongoDB Ops Manager创建用户数据库。

整个系列:

  1. 安装MongoDB Ops Manager
  2. 创建用户数据库(replicaset)
  3. 用户数据库服务配置公网访问
  4. openssl生成自签名CA证书和server证书
  5. 打开用户数据库TLS通信加密和Auth授权

所谓的Application Database是MongoDB Ops Manager的后端DB,并不能用来存放用户数据,所以我们需要用Ops Manager创建用户数据库。使用Ops Manager创建的MongoDB叫做Deployment,注意此DeploymentMongoDB Deployment,与kubernetes的Deployment不是一码事。

简单起见,本文以创建一个3实例的MongoDB userdb为例,Sharding Cluster由于组件复杂,server数量更多,配置比ReplicaSet要麻烦些,但配置过程基本一致。可参考: MongoDB Ops Manager部署Sharded Cluster

官方文档是要生成一个新的API Key创建用户数据库的,但后面会提到用这种方法可能会创建失败,采用ops-manager-admin-key进行创建可以绕过这个问题。因此下面提供两种方案。 Update 2020-12-23: 找到了问题,创建API Key Secret时使用的用户名要与上节 安装MongoDB Ops Managerops-manager-admin-secret保持一致(因为Key就是属于该用户的),否则会出现401 Unauthorized错误。

官方方案

生成Public API Key

用户数据库需要有权限访问Ops Manager,所以要生成一个Key。

“UserName -> Account -> Public API Access”,点页面最右上角的用户名,弹出菜单中有"Account"。 Generate Public API key

注意这个<apikey>只显示一次,妥善保存。

创建存储APIkey的secret

创建API Key Secret时使用的用户名user要与上节创建API Key的账户一致!

$ kubectl create secret generic om-user-credentials --from-literal="user=xxx@xxx.com" --from-literal="publicApiKey=<apikey>" -n mongodb
secret/om-user-credentials created

创建连接Ops Manager的ConfigMap

先找到Ops Manager的URL:

$ kubectl get om ops-manager -o jsonpath='{.status.opsManager.url}' -n mongodb
http://ops-manager-svc.mongodb.svc.cluster.local:8080

创建ops-manager-connection ConfigMap,写入上面得到的URL:

$ kubectl create configmap ops-manager-connection --from-literal="baseUrl=http://ops-manager-svc.mongodb.svc.cluster.local:8080"  -n mongodb
configmap/ops-manager-connection created

创建用户数据库userdb

可惜的是,创建用户数据库并不方便通过界面直接完成,如果你先新建一个Project,再创建Deployment,则在界面中需要你手动配置各种参数,而且由于Deployment对应的Server还没有创建,会出现找不到Agents的情况。这也是目前Ops Manager使用起来比较尴尬的地方:并不是所有操作都可以通过界面完成。原因应该是因为配置参数比较多,用配置文件管理更简单直接。不知道后续Ops Manager版本是否会改进此问题。

所以还是需要通过kubectl命令行创建用户数据库,编辑userdb.yaml如下,将opsManager部分的credential和configMap填入:

apiVersion: mongodb.com/v1
kind: MongoDB
metadata:
  name: userdb
  namespace: mongodb
spec:
  members: 3
  version: 4.2.2-ent
  type: ReplicaSet

  opsManager:
    configMapRef:
      name: ops-manager-connection
  credentials: om-user-credentials

$ kubectl apply -f userdb.yaml -n mongodb
mongodb.mongodb.com/userdb created

简单方案(不推荐)

请使用上面的官方方案。

上一步按照官方文档做法apply之后可能会失败:

$ kubectl get mdb -n mongodb
NAME     TYPE         STATE    VERSION     AGE
userdb   ReplicaSet   Failed   4.2.2-ent   86s
$ kubectl describe mdb -n mongodb
Name:         userdb
Namespace:    mongodb
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"mongodb.com/v1","kind":"MongoDB","metadata":{"annotations":{},"name":"userdb","namespace":"mongodb"},"spec":{"credentials":...
API Version:  mongodb.com/v1
Kind:         MongoDB
Metadata:
  Creation Timestamp:  2020-12-10T08:19:02Z
  Generation:          1
  Resource Version:    52201207
  Self Link:           /apis/mongodb.com/v1/namespaces/mongodb/mongodb/userdb
  UID:                 8c04df70-5249-4c3b-8a28-3907890e4eb8
Spec:
  Credentials:  om-user-credentials
  Members:      3
  Ops Manager:
    Config Map Ref:
      Name:  ops-manager-connection
  Type:      ReplicaSet
  Version:   4.2.2-ent
Status:
  Last Transition:      2020-12-10T08:20:33Z
  Message:              Failed to prepare Ops Manager connection: Error reading or creating project in Ops Manager: Status: 401 (Unauthorized), Detail: You are not authorized for this resource.
  Observed Generation:  1
  Phase:                Failed
  Version:
Events:                 <none>

401 (Unauthorized)错误,也就是说生成的API Key无效。

没有想到特别好的方法,但在Public API access页面中发现默认是有一个API Key的,虽然在Ops Manager中不显示,但可以从kubernetes dashboard的secret中找到:ops-manager-admin-key,也就是说不必生成新的APIkey和创建om-user-credentials了。查看ops-manager-admin-key的最末几位: OpsManager Public API Key

修改userdb.yaml如下(只修改最后一行):

apiVersion: mongodb.com/v1
kind: MongoDB
metadata:
  name: userdb
  namespace: mongodb
spec:
  members: 3
  version: 4.2.2-ent
  type: ReplicaSet

  opsManager:
    configMapRef:
      name: ops-manager-connection
  credentials: ops-manager-admin-key
然后再apply即可创建成功。

创建结果

之后一个新的statefulset userdb会创建,等待它创建完毕即可:

$ kubectl get mdb -n mongodb
NAME     TYPE         STATE     VERSION     AGE
userdb   ReplicaSet   Running   4.2.2-ent   13m

命令执行完毕之后,刷新All Clusters界面就有两个cluster了,同时对应的context和Project也自动创建好了,其中userdb就是创建好的用户数据库: MongoDB Ops Manager All Clusters

查看userdb processes: UserDB Processes 发现TLS和AUTH都是Disabled。也就是说DB的通信没有加密,访问也没有用户名密码。

查看userdb servers: UserDB Servers 注意三个server的地址都是类似:userdb-0.userdb-svc.mongodb.svc.cluster.local,也就是内网地址,因此此时我们并不能通过mongo client连接到这些MongoDB Instance。

不过现在用户数据库已经创建完成!

下一部分我们会暴露UserDB Service使其可以从公网访问。 Kubernetes部署MongoDB集群(三):用户数据库服务配置公网访问