繁体   English   中英

ansible mongodb_user,mongodb_replicaset 模块如何工作?

[英]How ansible mongodb_user,mongodb_replicaset modules working?

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

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

  - 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 初始化后才能工作

所以我做了如下

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

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

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

- 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

output:

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"
}

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

尝试 rs.initiate 代替 ansible 模块,如下所示

复制集.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())尝试

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) }

然后你不需要添加任何成员。

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

- 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,我使用了这个:

- 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 != ""

我用这个剧本创建的用户

- 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 != '' 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM