首页 / 资讯中心 / 文章详情

Linux服务器上MongoDB生产环境搭建:从安装到认证加固全指南

Linux服务器上MongoDB生产环境搭建:从安装到认证加固全指南 ★ FEATURED ARTICLE
看到标题里的“MonggoDB”我先职业病犯一下这个拼写多了一个g正确是MongoDB。不过这不重要重要的是我猜你真正想做的是在一台Linux服务器上把一个能长期跑、不裸奔、不随便崩的MongoDB环境给搭起来。网上的Linux搭建MongoDB教程不少但普遍有三个毛病只教安装不教配置配完之后压根没开认证数据库直接暴露在网络上再就是流程只能在本机跑通一换机器、一上生产环境就各种起不来。这篇文章我想换个写法不是把安装命令抄一遍就完事而是把从选型、装包、写配置、交给systemd托管到开启认证加固这一整条链路完整走一遍。每个步骤我尽量讲清楚“为什么这么做”顺带把我实际部署时踩过的坑也交代了。适合看这篇的人有两类一类是完全没接触过MongoDB的Linux新手按着步骤能搭出一套可用的环境另一类是已经被各种启动报错和权限问题折磨过的运维朋友我相信后面几节能帮你省点排查时间。1. 动手之前先想清楚安装方式、目录布局和运维习惯1.1 三种安装方式别一上来就无脑apt我见过太多人一上来就apt install mongodb或者yum install mongodb装完发现版本老得离谱很多新特性根本用不了。这里先把安装方式的取舍说清楚。发行版自带软件源是最省事但最不推荐的方式。Debian系和Red Hat系仓库里的MongoDB版本普遍滞后而且维护节奏和官方对不上。适合什么场景呢本地开发随便试试、不想配源、对版本没要求可以装来玩玩但生产环境绝对别用。官方源安装是大多数情况下的最优解。MongoDB官方维护了适配主流发行版的软件仓库通过系统包管理器直接安装指定大版本。好处是版本新、安全补丁更新快、能用systemd直接管理、卸载也干净。缺点只有一个需要服务器能访问外网。官方压缩包部署适合不能联网的内网环境、需要多版本并存做测试、或者公司内部有统一目录规范要求手动安装的场景。手动部署最大的好处是路径完全可控坏处是包管理器相关的便利全没了后面的systemd、日志轮转、权限配置都得自己手工搞定。三种方式我的建议排序是能连外网用官方源不能连外网用压缩包发行版自带仓库只用来做快速体验。1.2 目录规划不做好后面全是坑Linux搭建MongoDB环境时最容易忽略的就是目录规划。很多教程默认让你把数据放在/data/db这个目录本身没问题但有几个点你要提前想好数据目录和数据盘要分开想。如果服务器有独立数据盘强烈建议把dbPath放在独立磁盘上否则系统盘写满之后整个服务器都会遭殃。MongoDB数据目录至少要预留20%的剩余空间WiredTiger引擎在磁盘写满后不会优雅退出而是直接崩恢复过程又慢又痛苦。日志目录别和数据目录混在一起。日志放在/var/log/mongodb/mongod.log独立于数据文件方便排查问题也方便之后做日志轮转。MongoDB的日志默认是追加式的单文件久了会很大建议配好logrotate或者至少定期重开日志文件。运行用户一定不要用root。单独建一个mongod用户来跑MongoDB进程这是Linux服务的基本素养也是后面systemd单元文件里Usermongod的前提。如果图省事用root启动数据文件的属主会变成root之后换用户启动直接就Permission denied给你看。我习惯的目录结构是/usr/local/mongodb # 程序安装目录压缩包部署时 /etc/mongod.conf # 配置文件 /data/db # 数据文件 /var/log/mongodb/ # 日志文件如果是官方源安装程序目录由包管理器自己管不需要操心但数据目录和日志目录的规划和权限一样要注意。2. 安装流程官方源、压缩包、首连成功2.1 Debian系用官方源安装的最短路径以Ubuntu 22.04为例添加MongoDB官方源并安装的完整步骤是这样的sudo apt-get install -y gnupg curl curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-8.0.gpg echo deb [ signed-by/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list sudo apt-get update sudo apt-get install -y mongodb-org这几条命令要拆开理解不然换个发行版就不会玩了。第一条装的是curl和gpg工具这是下载和校验签名密钥的前置条件。第二条把官方签名密钥从MongoDB官网拉下来转成GPG keyring格式放到/usr/share/keyrings下。这里用--dearmor是为了把asc格式转成二进制keyring给后续source列表里signed-by引用。第三条是核心往/etc/apt/sources.list.d/里写了一条新的软件源。注意jammy对应Ubuntu 22.04如果你是Ubuntu 24.04就换成nobleDebian 12就换成bookworm。multiverse是Ubuntu源的组件分类MongoDB的包放在这个类别里。写完后apt update更新索引然后apt install -y mongodb-org装的就是最新8.0系列。官方源安装完会在/etc/mongod.conf放一份默认配置也会自动创建mongod用户这一点很省事。2.2 Red Hat系的安装思路Red Hat系CentOS、Rocky、AlmaLinux走的是/etc/yum.repos.d/配置仓库的路子。在/etc/yum.repos.d/mongodb-org-8.0.repo里写入[mongodb-org-8.0] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/8.0/x86_64/ gpgcheck1 enabled1 gpgkeyhttps://www.mongodb.org/static/pgp/server-8.0.asc然后执行sudo yum install -y mongodb-org$releasever会自动替换成系统大版本号用dnf和yum都一样。装完后默认配置文件同样是/etc/mongod.conf数据目录和日志目录也由安装包创建好了。2.3 压缩包部署路径完全自控内网环境没法连MongoDB仓库的用压缩包其实不复杂。先去官网下载页找到对应系统的压缩包下载后按下面流程操作mkdir -p /workspace/soft cd /workspace/soft curl -fsSL https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-8.0.x.tgz -o mongodb.tgz tar -zxvf mongodb.tgz sudo mv mongodb-linux-x86_64-ubuntu2204-8.0.x /usr/local/mongodb sudo mkdir -p /data/db /var/log/mongodb export PATH/usr/local/mongodb/bin:$PATH注意压缩包文件名里的平台标识要和系统匹配我这里是Ubuntu 22.04 x86_64下载页会给出精确版本号把8.0.x替换成实际版本即可。移动目录时最好把目录名统一改成不带版本号的mongodb这样后面更新版本只需要替换软链配置里的路径不用动。第一次验证能否启动先用手工方式sudo mongod --dbpath /data/db --logpath /var/log/mongodb/mongod.log --fork--fork表示后台运行--logpath把日志写到文件。首次启动会初始化数据文件看到forked process说明启动成功。接着验证连通性mongosh --eval db.runCommand({ping:1})这里多说一句现在MongoDB官方客户端已经改名mongosh早期教程里的mongo命令在新版本里根本没有。看到{ ok: 1 }返回说明服务已经能正常响应请求了。手工启动只适合临时验证正式使用必须交给systemd管理这一点我放到后面单独讲。3. mongod.conf 配置文件关键字段与容易翻车的地方3.1 一份最常用的最小配置不管用哪种方式安装最终都是通过/etc/mongod.conf来控制服务行为。MongoDB的配置文件是YAML格式缩进错了直接启动失败。下面这份是我在新环境上的通用起点systemLog: destination: file path: /var/log/mongodb/mongod.log logAppend: true storage: dbPath: /data/db engine: wiredTiger wiredTiger: engineConfig: cacheSizeGB: 2 net: port: 27017 bindIp: 127.0.0.1 processManagement: fork: falselogAppend: true表示日志追加写入不是每次启动都覆盖这点排查历史问题的时候特别重要。dbPath是数据目录engine默认就是WiredTiger写出来是为了明确意图。fork这里先设成false因为交给systemd管理时这个值要和unit文件里的Type类型匹配后面细说。3.2 一个很容易被忽略的WiredTiger缓存设置cacheSizeGB这个参数非常值得多说几句。WiredTiger引擎会用它作为内部缓存上限默认值是物理内存的一半减1GB如果机器内存很小默认也有下限。听起来很合理对吧但问题在于这个默认值在某些机器上会让MongoDB吃掉几乎一半内存如果同一台机器还跑着别的服务直接OOM。我给新手讲这个参数习惯用一个类比WiredTiger的缓存就像餐厅里的自助餐台窗口太少客人排队太久窗口太多虽然看起来阔气但食材总量有限做出来没人吃的菜反而浪费后厨空间。对于一台8GB内存的服务器跑一个业务量不大的MongoDBcacheSizeGB设成2GB一般够用剩下的内存留给操作系统页缓存和别的进程。这个值不必设得很大WiredTiger对磁盘的依赖远没有想象中那么强够用就好。3.3 bindIp、慢日志和容易被时代抛弃的旧参数bindIp直接决定了谁可以连到你的MongoDB。默认配置大多是127.0.0.1也就是只能本机访问。生产环境如果要让其他机器访问可以写内网IP多个IP用逗号分隔比如bindIp: 127.0.0.1, 10.0.0.12。不建议直接写0.0.0.0除非你有防火墙规则做兜底否则就是把数据库裸奔在网络上。慢日志也是一个常常被忽略的配置。MongoDB默认不记录超过指定时长的慢查询想排查应用性能问题会缺少关键线索。建议在配置里加operationProfiling: mode: slowOp slowOpThresholdMs: 200mode: slowOp表示只记录慢操作slowOpThresholdMs: 200把阈值设成200毫秒。这样之后用db.system.profile就能筛出拖慢业务的查询。还有一类坑是旧版本参数在新版本里被移除了。比如过去老版本的--nojournal、--syncdelay这类参数在WiredTiger成为默认引擎后已经变得无意义新版本直接拒绝启动并报出“unrecognized option”。所以从网上抄配置的时候一定要确认版本兼容性不要拿5.0的配置文件往8.0上硬套。4. 用systemd接管进程告别裸跑和手工启停4.1 为什么一定要用systemd管理很多人测试环境里会一直用mongod --fork这种方式跑服务进程后台化、退出后没人管、重启服务器后还得手动拉起这在生产环境里完全不可接受。systemd帮我们解决了三件事开机自启、崩溃自动重启、统一日志管理。把MongoDB交给systemd意味着你不用自己在命令行里折腾--fork和--logpathsystemd会按unit文件的定义去拉起进程并在进程异常退出后自动重启。4.2 一份可以直接用的unit文件在/etc/systemd/system/mongod.service里写入下面内容[Unit] DescriptionMongoDB Database Server Afternetwork.target Wantsnetwork-online.target [Service] Typeforking Usermongod Groupmongod ExecStart/usr/local/mongodb/bin/mongod --config /etc/mongod.conf ExecReload/bin/kill -HUP $MAINPID Restarton-failure LimitNOFILE64000 [Install] WantedBymulti-user.target这里有几处非常关键。Typeforking意味着systemd知道这个进程会自己fork到后台父进程启动完成就算成功。这个模式下/etc/mongod.conf里的processManagement.fork必须设为true两者才能配对。如果你用压缩包部署ExecStart指向的实际路径要用/usr/local/mongodb/bin/mongod官方源安装的话通常是/usr/bin/mongod。Usermongod和Groupmongod指定进程运行身份。Restarton-failure只在异常退出时重启正常stop不会被拉起。LimitNOFILE64000加大了文件描述符上限MongoDB高并发连接时会创建大量文件句柄默认的1024完全不够。配置文件准备好后执行sudo systemctl daemon-reload sudo systemctl enable --now mongod sudo systemctl status mongodenable --now同时完成开机自启和立即启动status输出里看到active (running)就说明成功了。这里顺便补充一个必须养成的习惯修改mongod.conf后不要直接重启先用mongod --config /etc/mongod.conf手工前台启动一次确认没有报配置错误再走systemd重启。不然unit文件配错、配置也报错排查起来两头分心。4.3 启动权限新手翻车率最高的地方我自己在搭环境时被Permission denied卡过一次后来才发现是数据目录属主不对。官方源安装会自动创建mongod用户并把数据目录的属主设置好但压缩包部署这条路完全要自己动手sudo mkdir -p /data/db /var/log/mongodb sudo chown -R mongod:mongod /data/db /var/log/mongodb如果漏了这一步mongod进程明明启动了日志里却反复出现权限错误数据库根本起不来。排查方法很简单看目录属主ls -ld /data/db /var/log/mongodb第一列应该是drwxr-xr-x mongod mongod如果不是chown改过来再启动。这个坑我倒不是说有多难而是它出现的时机很隐蔽通常是在你信心满满以为一切OK的时候突然给你泼一盆冷水。5. 数据安全默认裸奔认证和绑定必须一起做5.1 默认安装的MongoDB有多危险MongoDB默认是不开启访问控制的只要端口开放任何人都能连上来而且没有账号密码这道屏障。真实世界里针对27017端口的扫描一刻都没停过有些扫描工具会自动帮你建库、插入勒索提示更激进的做法是把你整个库删掉再要赎金。我不想去描述那些真实安全事件的细节只想告诉你一句话新装的MongoDB在开启认证和绑定内网IP之前绝对不要暴露到公网。安全防线要三层一起做绑定内网IP、防火墙限制来源、开启认证鉴权。只做其中一层都顶不住。5.2 开启认证的完整操作先把服务启动起来此时还没有认证用mongosh进入shellmongosh切到admin库创建管理员账号use admin db.createUser({ user: admin, pwd: 换成你自己的强密码, roles: [{ role: root, db: admin }] })root角色是超级权限通常只给管理员用。创建完在配置文件里加上安全段security: authorization: enabled重启服务sudo systemctl restart mongod重启后不带账号就进不去了登录方式变成mongosh -u admin -p --authenticationDatabase admin--authenticationDatabase admin指明用户凭证存在admin库里。这里有个新手容易卡住的地方登录时报Authentication failed大概率不是密码错而是忘了带--authenticationDatabase或者指定的认证库和用户实际所在的库不匹配。5.3 业务账号最小权限与网络层配合用root账号跑业务连接是另一个常见坏习惯。实践上应该给每个业务库单独建账号只授予对应库的权限use appdb db.createUser({ user: appuser, pwd: 换成业务账号密码, roles: [{ role: readWrite, db: appdb }] })这个账号只能在appdb里读写其他库一概碰不了。如果只读场景甚至可以只给read角色权限再降一级。网络层配合方面bindIp不要写0.0.0.0指定内网IP即可。如果服务器上开着防火墙放行来源网段sudo ufw allow from 10.0.0.0/8 to any port 27017或者用iptables的思路同理。需要提醒的是云服务器上除了系统防火墙还有一层安全组规则两个地方要一起核对防火墙放行了但安全组挡着外部照样连不上。跨网段访问或者公网场景生产环境一定得上TLS加密。MongoDB从4.x开始默认生成的证书就能用来开启TLS具体配置可以等有需求时再深入研究但至少要有这个意识认证只解决“你是谁”TLS解决的是“你说话有没有人偷听”。6. 实际部署中踩过的坑与完整排查链路6.1 启动失败先看日志别瞎猜MongoDB启动失败的排查第一件事永远是打开日志文件。官方源的日志默认在/var/log/mongodb/mongod.log手工部署的时候自己指定了logpath。日志尾部是最有价值的sudo tail -n 100 /var/log/mongodb/mongod.log几个高频报错我列一张表方便你对照问题报错关键词常见原因解决办法Permission denied数据目录或日志目录属主不对chown -R mongod:mongod对应目录Cannot open /data/db目录不存在或没创建mkdir -p /data/dbUnrecognized option配置文件字段拼错或版本不兼容用新版本支持的字段替换YAML缩进错误使用了tab缩进或缩进不一致统一用两个空格缩进6.2 进程在跑但连不上按链路逐层查进程起来了、日志也没报错但客户端就是连不上这个问题在我接触过的新手里出现频率极高。我给你一条可以直接照做的排查链路在服务器本机执行ss -lntp | grep 27017确认端口真的在监听。如果什么都没有说明mongod根本没起来回头查日志。确认进程存在ps -ef | grep mongod。如果进程在但没监听端口大概率是配置里的net.port和实际启动参数对不上。从另一台机器执行telnet 服务器IP 27017确认网络路径通不通。Connection refused说明端口没监听Connection timed out说明防火墙或安全组把包丢了。本机能连、远程不能连就往bindIp、防火墙、安全组三个方向查。确认客户端连接串里的IP和配置的bindIp匹配如果MongoDB只绑定了内网IP你用公网IP去连自然不通。这条链路我建议按顺序走不要一上来就怀疑配置网络联通性都没确认就对配置文件反复折腾纯属浪费时间。6.3 用kill -9强杀进程是我吃过最大的亏有次排查连接异常时我图省事直接kill -9把mongod进程杀掉结果再次启动时日志里出现WiredTiger的恢复过程数据量大的时候启动时间翻了几倍。更糟糕的情况是强杀瞬间如果正好有数据写入WiredTiger的检查点没落盘恢复时可能直接报数据文件损坏。正确关闭MongoDB的方式有三种命令行里用db.shutdownServer()优雅关闭、systemctl stop mongod、或者向主进程发送SIGTERM。kill -9是最后手段不到万不得已不要用。这也是为什么我一直强调用systemd管理MongoDB不需要你手动找进程号去杀一条systemctl stop干干净净。6.4 升级大版本配置文件也要跟着体检MongoDB大版本升级不是简单换包重装。官方升级路径要求跨大版本必须逐步升级比如5.x到6.x再到7.x不能跳级。升级前旧配置文件里的过期参数、不再兼容的启动选项都要提前清理。我有一次直接把旧配置里的storage.journal.enabled拿到新版本上服务直接拒绝启动日志提示这个参数已经在当前版本里失效了。所以养成一个习惯每次升级前先用目标版本的二进制文件手工跑一次配置校验确认没有不可识别选项。这一步能在升级窗口之前暴露大部分不兼容问题比升级到一半再回滚舒服多了。我自己搭MongoDB环境的心得其实很简单先把数据目录、运行用户、日志这些地基打好再谈安装和配置把服务交给systemd后再去调参数网络绑定和认证从第一天就做好不要等出了问题再补。做到这几点这套环境基本就能安安稳稳跑上很久。
阅读完成 · 觉得有帮助?
咨询建站