Ansible mongodb_replicaset模块导致错误

bkhjykvo  于 2023-04-20  发布在  Go
关注(0)|答案(1)|浏览(178)

我正在使用ansible部署mongodb-cluster
我连接到primary_node并在admin数据库中创建了admin用户:
然后更新**/etc/mongo.conf**如下:

net:
  port: 27017
  bindIpAll: true

systemLog:
  destination: file
  logAppend: true
  path: /log/mongod.log

storage:
  dbPath: /data
  journal:
    enabled: true

security:
  authorization: enabled
  keyFile: /mongo_auth/mongodb.key

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo

replication:
  replSetName: s0

在此之后,Mongod进程重新启动。
现在,我可以使用admin/login凭据登录,并可以运行命令来启动replicaSet

rs.initiate({ _id: "s0", version: 1, members: [{ _id: 0, host: "stage-mongoprimary0.server.loc:27017", priority: 2 }, { _id: 1, host: "stage-mongosecondary1.server.loc:27017", priority: 1 }, { _id: 2, host: "stage-mongosecondary2.server.loc:27017", priority: 1 }] })

一切都很好。但是由于某些原因,我不能用ansible模块完成同样的工作。这是我的任务

- name: Initialize MongoDB replica set
  community.mongodb.mongodb_replicaset:
    login_user: admin
    login_password: "{{ admin_password }}"
    replica_set: s0
    members:
      - _id: 0
        host: stage-mongoprimary0.server.loc
        priority: 2
      - _id: 1
        host: stage-mongosecondary1.server.loc
        priority: 1
      - _id: 2
        host: stage-mongosecondary2.server.loc
        priority: 1
  when: inventory_hostname == mongo_primary

默认模块使用管理数据库和默认端口,这正是我已经设置。
但是当我运行这个任务时,我得到一个错误:
“msg”:“无法创建副本集:管理员未授权执行命令的一些问题
但是如果我使用相同的creds直接登录mogo shell,我也可以这样做。请帮助。
admin角色是具有highet权限的root用户。
我使用的是mongodb 3.6.23、pymongo 4.3.3和Python3.8、ansible 2.9.23
这是我在日志中看到的:
2023-04-14T00:58:06.143+0000 I NETWORK [conn19]从xx.xx. xx.xx:52300 conn19:{ driver:{ name:“PyMongo”,版本:“4.3.3”},操作系统:{ type:“Linux”,name:“Linux”,体系结构:“x86_64”,版本:“4.14.311-233.529.amzn2.x86_64”},平台:“CPython 3.8.16.final.0”} 2023-04- 14 T00:58:06.144+0000 I ACCESS [conn 19]未授权:管理员未授权执行命令{ replSetInitiate:{ _id:“s0”,protocolVersion:1、会员:[ { _id:0,host:“stage-mongoprimary 0.server.loc:27017”,优先级:2 },{ _id:1,host:“stage-mongosecondary 1.server.loc:27017”,优先级:1 },{ _id:2,host:“stage-mongosecondary 2.server.loc:27017”,优先级:1 } ],设置:{ chainingAllowed:true,electionTimeoutMillis:10000 } },$db:“admin”,$readPreference:{ mode:“primaryPreferred”} }
已尝试分配以下角色:

- { db: "admin", role: "userAdminAnyDatabase" }
  - { db: "admin", role: "dbAdminAnyDatabase" }
  - { db: "admin", role: "clusterAdmin" }
  - { db: "admin", role: "readWriteAnyDatabase" }

甚至试过

- { db: "admin", role: "__system" }
  - { db: "admin", role: "root" }

还是一样
我可以启动ReplicaSet并添加成员,只有当我禁用安全性,这不是我正在寻找的。

1bqhqjot

1bqhqjot1#

不需要修改配置文件,直接用security.authorization: enabled启动mongod即可,如果不存在管理员用户,则可以用localhost exception连接,创建第一个管理员用户后,授权生效。
根据Deploy Replica Set With Keyfile Authentication,首先需要初始化副本集,然后可以创建管理员用户。
我没有使用community.mongodb.mongodb_replicaset插件,而是像这样手动操作:

- name: Check if authentication is enabled
  shell: 
    cmd: "/usr/bin/mongosh --norc --quiet 'mongodb://admin:{{ password | urlencode() }}@localhost/admin?&authSource=admin&readPreference=primaryPreferred' --eval 'db.getMongo()'"
    executable: /bin/bash
  register: authenticate
  failed_when: false
  changed_when: false
  check_mode: no

- name: Initialize ReplicaSet and create admin user
  shell: 
    cmd: "/usr/bin/mongosh --norc --quiet 'mongodb://localhost/admin?readPreference=primaryPreferred' --eval '{{ js }}'"
    executable: /bin/bash
  vars: 
    js: |
      rs.initiate({ _id: "{{ replica_set }}", members: [{ _id: 0, host: "{{ item.memberFQN | first }}" }]})
      while (! db.hello().isWritablePrimary) sleep(1000)
      db.getSiblingDB("admin").createUser({ user: "admin", pwd: "{{ password }}", roles: ["root"] })
      db.getSiblingDB("admin").auth("admin", "{{ password }}")
      {% for m in item.memberFQN[1:] %}
      rs.add({_id: {{loop.index}}, host: "{{ m }}" })
      {% endfor %}
  loop: "{{ members }}"
  when: authenticate.rc != 0

更高级的版本是这样的:

- hosts: all
  vars: 
    uriAuth: "mongodb://admin:{{ password | urlencode() }}@{{ inventory_hostname_short }}:27017/admin?authSource=admin"
    uriNoAuth: "mongodb://localhost:27017/admin"
  remote_user: mongod
  tasks:

  - name: Check if authentication is enabled
    shell: 
      cmd: "/usr/bin/mongosh --norc --quiet '{{ uriAuth }}' --eval 'db.getMongo()'"
      executable: /bin/bash
    register: authenticate
    failed_when: false
    changed_when: false
    check_mode: no

  - name: Check if Replicaset is initialized
    shell: 
      cmd: "/usr/bin/mongosh --norc --quiet '{{ (authenticate.rc == 0) | ternary(uriAuth, uriNoAuth) }}' --eval 'print(e.codeName)'"
      executable: /bin/bash
    register: initialized
    changed_when: false
    check_mode: no

  - name: Init Replicaset
    shell: 
      cmd: "/usr/bin/mongosh '{{ uriNoAuth }}&readPreference=primaryPreferred' --eval '{{ js }}'"
      executable: /bin/bash
    vars:
      js: |
        var ret = rs.initiate({{ rs_initiate | to_json }})
        if (ret.ok != 1) {
          print(EJSON.stringify(ret))
          quit(1)
        }
        while ( !db.hello().isWritablePrimary ) sleep(1000)
        print(rs.status().members.map(x => {return {name: x.name, stateStr: x.stateStr}}))
    register: ret_initconfig
    when: initialized.stdout == 'NotYetInitialized'

  - debug:
      msg: "{{ ret_initconfig.stdout_lines }}"
    when: (ret_initconfig.stdout | default('')) != ''

  - name: Create users and roles
    shell: 
      cmd: "/usr/bin/mongosh --norc --quiet '{{ (authenticate.rc == 0) | ternary(uriAuth, uriNoAuth) }}' --eval '{{ js }}'"
      executable: /bin/bash
    vars: 
      js: |
        const admin = db.getSiblingDB("admin")
        {% if authenticate.rc != 0 %}
        var ret = admin.createUser({ user: "admin", pwd: "{{ password }}", roles: ["root"] })
        if (ret.ok != 1) { print(EJSON.stringify(ret)); quit(1) }
        print(EJSON.stringify({user: "admin", ok: ret.ok}))
        let auth = admin.auth("admin", "{{ password }}")
        if (auth.ok != 1) { print(EJSON.stringify(auth)); quit(1) }
        {% endif %} 
        ... create other users and/or roles
    register: ret_createUser
    changed_when: ret_createUser.stdout != ''

相关问题