导致错误的 Ansible mongodb_replicaset 模块

问题描述 投票:0回答:1

我正在使用 ansible 部署 mongodb-cluster

我连接到 primary_node 并在管理数据库中创建了管理员用户:

然后更新 /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 进程重启后。

现在我可以使用管理员/登录凭据登录,我可以运行命令来启动 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

默认模块使用管理数据库和默认端口,这正是我已经设置的。

但是当我运行这个任务时我得到一个错误:

“消息”:“无法创建副本集:一些问题未授权 管理员执行命令

但是如果我使用相同的凭据直接登录到 mogo shell,我可以做同样的事情。请帮助。

admin 角色是具有最高权限的 root。

我正在使用 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 接收到客户端元数据:{ 驱动程序:{ 名称:“PyMongo”,版本:“4.3.3” } ,操作系统:{类型:“Linux”,名称:“Linux”,体系结构:“x86_64”,版本:“4.14.311-233.529.amzn2.x86_64”},平台:“CPython 3.8.16.final.0”} 2023-04-14T00:58:06.144+0000 I ACCESS [conn19] 未授权:未授权管理员执行命令 { replSetInitiate: { _id: "s0", protocolVersion: 1, members: [ { _id: 0, host: " stage-mongoprimary0.server.loc:27017", priority: 2 }, { _id: 1, host: "stage-mongosecondary1.server.loc:27017", priority: 1 }, { _id: 2, 主机: "stage- mongosecondary2.server.loc:27017", priority: 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 并添加成员,这不是我想要的。

mongodb replicaset
1个回答
0
投票

您不必修改配置文件。您可以直接使用

mongod
开始
security.authorization: enabled
。如果管理员用户不存在,那么您可以使用 localhost exception 进行连接。一旦创建了第一个管理员用户,授权就生效了。

根据使用密钥文件身份验证部署副本集你首先需要启动副本集,然后你可以创建管理员用户。

我没有使用

community.mongodb.mongodb_replicaset
插件,我是这样手动操作的:

- name: Check if authentication is enabled
  shell: 
    cmd: "/usr/bin/mongosh 'mongodb://admin:{{ password | urlencode() }}@{{ member }}/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 '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 '{{ 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 '{{ (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 '{{ (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 != ''
© www.soinside.com 2019 - 2024. All rights reserved.