问题描述
我正在尝试通过 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 模块如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!