本文介绍了ansible mongodb_user,mongodb_replicaset 模块如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 ansible 自动化 MongoDB 安装和复制设置.因此,作为其中的一部分,我想利用 ansible 模块 mongodb_user、mongodb_replicaset.使用此模块时,我遇到了一些问题.所以需要对此有所了解

I'm trying to automate MongoDB installation along with replication setup via ansible. So as part of that, I want to utilize ansible modules mongodb_user,mongodb_replicaset. When using this module I'm facing some issues. So need some light on this

问题 - 1:当我使用 mongodb_user 创建管理员用户时,出现以下错误

Issue - 1:when I create an admin user using mongodb_user I'm getting the below error

  - name: Create MongoDB root user admin
    mongodb_user:
        login_port: "{{ mongod_port }}"
        database: "{{ mongodb_db_name }}"
        name: "{{ mongodb_admin_user }}"
        password: "{{ mongodb_admin_password }}"
        roles: "root"

出现如下错误

 "msg": "Unable to add or update user: not master, full error: {'topologyVersion': {'processId': ObjectId('60c0f9ebe9bf9941528836df'), 'counter': 0}, 'ok': 0.0, 'errmsg': 'not master', 'code': 10107, 'codeName': 'NotWritablePrimary', '$gleStats': {'lastOpTime': Timestamp(0, 0), 'electionId': ObjectId('000000000000000000000000')}, 'lastCommittedOpTime': Timestamp(0, 0)}"
    }

从错误中,我可以理解它只有在进行 MongoDB 初始化后才能工作

From the error, I can understand it will work only after do the MongoDB initialization

所以我是这样做的

- name: Initiate the Replicaset
  command: "mongo --host 127.0.0.1 --port {{mongod_port}} --eval 'printjson(rs.initiate())'"

之后我就可以成功创建用户

After that I'm able to create user successfully

现在我正在尝试使用下面的模块添加副本集,但不幸的是,它没有添加,也没有抛出任何错误.没有发生任何变化

Now I'm trying to add replica set using below module but unfortunately, it is not added and not thrown any error.No changes happened

- name: Ensure replicaset Shard_0 exists
  mongodb_replicaset:
    login_host: localhost
    login_user: xxxxx
    login_password: yyyyy
    replica_set: configRS
    #members: "{{ groups['MongoC'] }}"
    members: "{{ groups['MongoC'] | map('extract', hostvars, ['ansible_host']) | join(':27017,') }}:27017"
  when: (groups['MongoC']|sort())[0] == inventory_hostname

输出:

ok: [MongoC-1] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "arbiter_at_index": null,
            "auth_mechanism": null,
            "chaining_allowed": true,
            "connection_options": null,
            "election_timeout_millis": 10000,
            "heartbeat_timeout_secs": 10,
            "login_database": "admin",
            "login_host": "localhost",
            "login_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "login_port": 27017,
            "login_user": "xxxxx",
            "members": [
                "10.0.1.141:27017",
                "10.0.2.229:27017",
                "10.0.3.30:27017"
            ],
            "protocol_version": 1,
            "replica_set": "configRS",
            "ssl": false,
            "ssl_ca_certs": null,
            "ssl_cert_reqs": "CERT_REQUIRED",
            "ssl_certfile": null,
            "ssl_crlfile": null,
            "ssl_keyfile": null,
            "ssl_pem_passphrase": null,
            "validate": true
        }
    },
    "replica_set": "configRS"
}

我是否以正确的方式使用这些模块?

Am I using the modules in the right way?

尝试使用 rs.initiate 而不是下面的 ansible 模块

Tried rs.initiate instead of ansible module like below

replicaset.js

replicaset.js

rs.initiate({
 _id: "configRS",
 configsvr: true,
 members: [
  { _id: 1, host : "10.0.1.73:27017" },
  { _id: 2, host : "10.0.2.144:27017" },
  { _id: 3, host : "10.0.3.18:27017" },
  ]
 }
);

命令:

"mongo --port 27017 replicaset.js"

出现如下错误:

\t\"errmsg\" : \"not authorized on admin to execute command { replSetGetConfig: 1.0, lsid: { id: UUID(\\\"788e7cff-218c-4605-ab68-b3b6751634ca\\\") }, $db: \\\"admin\\\" }\",",
        "\t\"code\" : 13,",
        "\t\"codeName\" : \"Unauthorized\",",

推荐答案

代替 printjson(rs.initiate()) try

rs.initiate(
  {
    _id: "configRS",
    configsvr: true,
    members: [
      { _id: 0, host: "10.0.1.141:27017" },
      { _id: 1, host: "10.0.2.229:27017" },
      { _id: 2, host: "10.0.3.30:27017" }
    ]
  }
);
rs.status();
while (! db.isMaster().ismaster ) { sleep(1000) }

那么你就不需要添加任何成员了.

Then you don't need to add any member.

对于CSRS,我使用这样的剧本:

For CSRS I use a playbook like this:

- hosts: config
  tasks:
  - name: Compose variables
    set_fact:
      rs_initiate: |      
        {% set members = [] %}
        {% for host in groups['config']  | sort %}
        {% set m = {'_id': loop.index0 } %}
        {% set _ = m.update({'host': host + '.' + ansible_domain + ':' + ports.config | string }) %}
        {% set _ = members.append(m) %}
        {% endfor %}
        {% set init = {'_id': replica_set.conf} %}
        {% set _ = init.update({'members': members}) %}
        {% set _ = init.update({'configsvr': true}) %}
        {{ init }}
      rs_members: |
        {% set members = [] %}
        {% for host in groups['config'] | sort %}
        {% set _ = members.append(host + '.' + ansible_domain + ':' + ports.config | string) %}
        {% endfor %}
        {{ members }}
      replicaSetURI: "mongodb://{{ groups['config'] | product([ports.config]) | map('join', ':') | join(',') }}/admin?authSource=admin&replicaSet={{ replica_set.conf }}" 

  - name: Check if Config Replicaset is initiated
    shell: 
      cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
      executable: /bin/bash
      stdin: "rs.status().codeName" 
    register: result
    changed_when: false
    check_mode: no
  
  
  - set_fact:
# Needed to ensure that the Config Server Replica Set (CSRS) is initiated only once
      rs: |
        {% set i = (result.stdout == 'NotYetInitialized') %}
        {% for host in ansible_play_hosts %}
        {% set i = i and (hostvars[host].result.stdout == 'NotYetInitialized') %}
        {% endfor %}
        {{ {'NotYetInitialized': i} }}
  
  
  
  - name: Initiate Config Replicaset
    shell: 
      cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
      executable: /bin/bash
      stdin: |
        var i = rs.initiate({{ rs_initiate | to_json }})
        if (i.ok != 1) print(i.errmsg)
        var _ = rs.status()
        while (! db.isMaster().ismaster ) sleep(1000)
        rs.status().members.map(x => x.name)
        if (i.ok == 1) {print(rs.status().ok)} else {print(0)}
    register: ret
    failed_when: ret.stdout_lines | last != "1"
    when: rs.NotYetInitialized and inventory_hostname_short == groups['config'] | sort | first)
  
  - debug:
      msg: "{{ ret.stdout_lines }}"
    when: not ansible_check_mode and rs.NotYetInitialized and inventory_hostname_short == (groups['config'] | sort | first) and ret.stdout != ''

为了将主机添加到现有的 CSRS,我使用了这个:

In order to add hosts to existing CSRS I use this one:

- hosts: config
  tasks:
  
  - meta: end_play
    when: ansible_check_mode or rs.NotYetInitialized | default(false)

  - name: Check current Config Server Replica Set members
    shell: 
      cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.config }}"
      executable: /bin/bash
      stdin: "rs.status().members.map(x => x.name)"
    register: result
    changed_when: false
    when: inventory_hostname_short == (groups['config'] | sort | first)

  - set_fact:
      current_members: "{{ result.stdout | from_json }}"
    when: inventory_hostname_short == (groups['config'] | sort | first)

  - name: Add host to Config Server Replica Set
    shell: 
      cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.config }}"
      executable: /bin/bash
      stdin: "rs.add('{{ item }}')"
    when: inventory_hostname_short == (groups['config'] | sort | first)
    loop: "{{ rs_members | difference(current_members) | sort }}"
    register: ret
    failed_when: ret.stdout != ""

我用这个剧本创建的用户

Users I create with this playbook

- hosts: application
  tasks:

  - name: Check if authentication is enabled
    shell: 
      cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.router }}"
      executable: /bin/bash
      stdin: exit 
    register: authenticate
    failed_when: false
    changed_when: false
    check_mode: no
    when: inventory_hostname_short == (groups['application'] | sort | first)

  - name: Create admin user
    shell: 
      cmd: "/usr/bin/mongo {{ (authenticate.rc == 0) | ternary('-u admin -p ' + password.admin + ' --authenticationDatabase admin', '') }} --norc --quiet localhost:{{ ports.router }}"
      executable: /bin/bash
      stdin: |
        const admin = db.getSiblingDB("admin")
        {% if authenticate.rc != 0 %}
        admin.createUser({ user: "admin", pwd: "{{ password.admin }}", roles: ["root"] })
        var _ = admin.auth("admin", "{{ password.admin }}")
        {% endif %}
        // Create more users if needed
    when: inventory_hostname_short == (groups['application'] | sort | first)
    register: ret_createUser
    changed_when: ret_createUser.stdout != ''

  - debug:
      msg: "{{ ret_createUser.stdout.split('\n') }}"
    when: not ansible_check_mode and inventory_hostname_short == (groups['application'] | sort | first) and ret_createUser.stdout != '' 

这篇关于ansible mongodb_user,mongodb_replicaset 模块如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 08:11