我正在使用 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 并添加成员,这不是我想要的。
您不必修改配置文件。您可以直接使用
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 != ''