MongoDb 的基础概念和部署(基于Docker)
本文主打一个超详细的介绍,跟着做一定 ok。MongoDb 是非关系数据库中最像关系数据库的,MongoDb 是面向文档储存的数据库,操作起来较为简单。刚开始学习 MongoDb 的地方在于它的用户权限认证,我会在此文尽量简单的说明它,并且使用 Dokcer 来部署和使用它。
本文需要你掌握:Dokcer,Docker-compose,Navicat
舞台布置
在下的舞台环境如下:
- Ubuntu 22.04.2-Server
- Docker 24.0.2
- Docker-compose 2.18.1
- MongoDB 5.0.5 (基于 mongo 最新镜像)
安装 mongo
在 /home/docker/mongo 下建立 docker-compose.yml:
version: "3.7"
services:
mongo:
container_name: mongo
image: mongo
restart: always
ports:
- 27017:27017
environment:
# 设置时区
TZ: CST-8
进入 /home/docker/mongo 目录,执行命令:
docker-compose up -d
执行命令成功后即可安装成功:
使用 navicat 连接它:
这个时候打开连接,会发现其中有三个数据库:
如果你的 navicat 没有显示这三个数据库,那有可能是隐藏了,在菜单栏->查看->显示隐藏项目打开就行:
这三个数据库是 mongo 内置的,运行所必须的,他们的作用如下:
- admin:是 MongoDB 的默认管理数据库,它用于管理 MongoDB 实例和执行一些系统级别的操作。在 admin 数据库中,可以进行用户管理、权限设置、备份和恢复操作以及监控数据库状态等管理任务。
- local:主要用于存储与单个 MongoDB 实例相关的本地数据。它通常包含复制集中的操作日志(oplog),用于支持数据复制和故障恢复。此外,一些临时数据也可以存储在 local 数据库中。
- config:是MongoDB的分片配置数据库,用于存储与分片集群相关的元数据信息。当 MongoDB 部署为分片集群时,config 数据库记录了分片集群的配置信息,包括分片键、分片的位置、副本集配置等。
这个时候或许你会抛出一个疑问:连接 mongo 不需要用户认证吗?还真就是,mongo 和 redis 一样,默认是不需要用户认证的。但在实际的业务中,mongo 还是要设置用户认证的,不然岂不是知道了 IP 和端口就能为所欲为了。当然,这里有句题外话,数据库的端口最好不要暴露在公网上,否则将带来巨大的安全隐患。
用户权限和角色权限
在正式使用 mongo 之前,我们先来认识一下它如何开启用户认证、如何创建用户。mongo 的用户权限较为复杂,笔者这里会尽量的简化它,等到对 mongo 整体有了清晰的认识后,再回来高屋建瓴的学习它,将会轻松许多。
创建超级管理员
要管理和使用 mongo,前提条件是有一个超级管理员用户,这个用户可以管理其他用户,其所在的数据库必须是 admin。进入 mongo 容器创建超级管理员:
# 进入 mongo 容器
docker exec -it mongo bash
# 进入 mongo 命令行模式
mongo
此时你会看到这样的信息:
接着输入如下命令:
# 使用 admin 数据库
use admin
# 显示结果:switched to db admin
# 创建超级管理员用户
db.createUser({user: "root", pwd: "123456", roles:[{role: "root", db: "admin"}]})
# 显示结果:
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
db.createUser 后面的参数是一个 json:
- user: 用户名
- pws: 密码
- roles.role: 指定用户的角色
- roles.db: 角色授予的数据库,通俗的说,该用户能管理那个数据库就写哪个
内置的常用的 roles.role 如下:
角色 | 权限描述 |
read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
userAdmin | 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 |
clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限 |
readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限 |
backup | 允许用户执行备份操作,包括创建和还原数据库备份 |
restore | 允许用户执行还原操作,用于还原数据库备份 |
root | 只在admin数据库中可用。超级权限,是readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin、restore和backup联合之后所有的权限 |
超级管理员创建好之后,就可以使用它登录了,但是你先别急着尝试,我们还有更优雅的做法。
优雅的创建超级管理员
对于这种搭建环境后还要啪啪的输入一堆命令的操作,想必看着都烦,Docker 在这个时候的作用就体现出来了:一次打包,处处运行。修改我们的 docker-compose.yml:
version: "3.7"
services:
mongo:
container_name: mongo
image: mongo
restart: always
ports:
- 27017:27017
# 必要,强制权限认证
command: [--auth]
environment:
TZ: CST-8
# 超级管理员用户名
MONGO_INITDB_ROOT_USERNAME: root
# 超级管理员密码
MONGO_INITDB_ROOT_PASSWORD: 123456
MONGO_INITDB_ROOT_USERNAME
和 MONGO_INITDB_ROOT_PASSWORD
这两个环境变量用于辅助我们建立一个超级管理员。重新建立容器,再登录就需要验证了:
如果这里的验证还选择 none 时,尝试打开连接,将会抛出一个需要权限的错误提示:
创建一个普通的数据库
admin 数据库和超级管理员一般不用做实际业务上的数据存储,我们需要建立一个普通的数据库和用户来操作数据。进入 mongo 容器来建立一个普通用户:
# 进入 mongo 容器
docker exec -it mongo bash
# 进入 mongo 命令行模式
mongo
先进入 admin 数据库完成超级管理员的认证:
创建一个名为 oldme 的数据库:
# use 命令可以切换数据库,如果切换的数据库不存在会自动创建它
use oldme
创建一个具有读写权限的普通用户 newton:
db.createUser({ user: "newton", pwd: "123456", roles: [ { role: "readWrite", db: "oldme" } ]})
navicat 测试:
数据库里面没有集合在 navicat 中打开连接是什么都不显示的,所以看见 navicat 中什么都不显示不要慌张,它不是部署失败了奥。想要看到具体的效果,回到 ssh 执行命令创建一个集合即可:
db.createCollection("user")
优雅的创建的普通管理员
创建超级管理员在 docker-compose.yml 中里面配置一下就好了,很优雅。那普通管理员有没有类似的方法呢,虽然 mongo 镜像没有我们准备,但是我们还是可以曲线救国的。怎么做呢,由于MongoDb 除了能使用 shell 管理外,还可以使用 javascript 脚本来管理,我们预先准备一个 sh 脚本,然后用它来执行 js 脚本,就可以达到我们的目的。做法如下:创建一个名为 mongo-init.sh
的文件,放在宿主机的任意目录下,键入以下固定内容:
mongo -- "admin" <<EOF
db.auth("$MONGO_INITDB_ROOT_USERNAME", "$MONGO_INITDB_ROOT_PASSWORD")
db = db.getSiblingDB("$MONGO_INITDB_DATABASE")
db.createUser({
user: "$MONGO_USERNAME",
pwd: "$MONGO_PASSWORD",
roles: [
{ role: "readWrite", db: "$MONGO_INITDB_DATABASE" }
]
})
EOF
然后在 docker-compose.yml 中把所需的环境变量赋值并且配置数据卷:
version: "3.7"
services:
mongo:
container_name: mongo
image: mongo
restart: always
ports:
- 27017:27017
# 加上权限认证
command: [--auth]
environment:
TZ: CST-8
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
MONGO_INITDB_DATABASE: oldme
MONGO_USERNAME: newton
MONGO_PASSWORD: 123456
volumes:
# 将sh脚本映射到/docker-entrypoint-initdb.d目录下,容器初始化时会自动执行
- /home/docker/mongo/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh
使用新的 docker-compose.yml 文件重建容器,重建的 MongoDb 里面会有一个已经创建好的数据库:oldme,这个数据库会有一个具备读写权限的管理员:newton。
数据映射
在容器销毁时,mongo 容器的数据会丢失,我们可以配置数据卷映射,将 mongo 容器中的数据文件映射到宿主机上,修改 docker-compose.yml,增加一个数据卷映射:
version: "3.7"
services:
mongo:
container_name: mongo
image: mongo
restart: always
ports:
- 27017:27017
# 加上权限认证
command: [--auth]
environment:
TZ: CST-8
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
MONGO_INITDB_DATABASE: oldme
MONGO_USERNAME: newton
MONGO_PASSWORD: 123456
volumes:
- /home/docker/mongo/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh
# 将数据放在宿主机的/home/docker/mongo/data中
- /home/docker/mongo/data:/data/db
重新创建容器,即可在宿主机中看见 mongo 的数据文件:
这样下次再销毁重建,所有的数据都会重新映射到容器中。
本文目录