十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS离线安装MongoDB 7.0完整指南:依赖排查与Docker替代方案

CentOS离线安装MongoDB 7.0完整指南:依赖排查与Docker替代方案 上周帮一个项目组处理内部数据库环境搭建服务器在隔离网段能连通局域网但连不上外网也没有可用的软件仓库。需求很明确CentOSLinux系统上装一个 MongoDB 7.0而且必须纯离线完成。这种活儿看着简单实际操作时一旦碰上 glibc、openssl 版本不匹配可能一折腾就是一下午。我这次完整走了一遍把坑都试出来了所以把整个过程整理出来。文章会先讲离线安装的方案选择和系统版本要求再给完整可复现的安装步骤最后是排障记录和 CentOS 7.9 的特殊处理建议。无论你是运维还是后端开发照着这份思路基本都能把服务跑起来。1. 先把方案定清楚离线装 MongoDB 7.0 之前要明白的事1.1 什么场景下必须离线安装我接触到的离线安装需求大多来自下面几种情况单位内部有等保要求生产网段与互联网物理隔离外网设备不允许接入内网虽然提供了 yum 源但里面只有基础系统包没有 MongoDB也没有额外的应用仓库项目交付到客户现场客户不允许服务器连接公网下载任何安装包公司有安全审计流程所有软件必须经过审批和杀毒扫描后才能带入内网。这些场景的共同点是你不能在线执行yum install mongodb-org必须在外部环境把所有软件包准备齐全再通过 U 盘、FTP、审批流程等方式拷入内网。离线安装最怕的不是“拷一个包进去就完事”而是“拷进去之后发现它还有一堆依赖库没带全”来回折腾审批流程极其浪费时间。所以离线安装的核心思路要提前建立起来不管最后用 rpm 还是 tar 包都必须把应用本体和它运行时依赖的库一起准备好并且提前了解目标机器的系统版本、glibc 版本、openssl 版本而不是直接去装。1.2 系统版本选型为什么我不推荐在 CentOS 7.9 上硬装 7.0这里要先说实话。MongoDB 官方对 MongoDB 7.0 的平台支持清单里RHEL 7 / CentOS 7 已经不在支持范围内官方只发布面向 RHEL 8 / RHEL 9 的二进制包。CentOS 7.9 自带 glibc 2.17而 MongoDB 7.0 的 RHEL 8 版本要求 glibc 2.28CentOS 7.9 自带 openssl 1.0.2而 MongoDB 7.0 需要 openssl 1.1 提供的 libcrypto.so.1.1。因此在 CentOS 7.9 上直接解压官方 tgz 包大概率会报GLIBC_2.28 not found或libcrypto.so.1.1: cannot open shared object file。如果你手头只有 CentOS 7.9并且确实想用 MongoDB 7.0硬装不是完全没可能但代价非常大要处理 glibc 升级、openssl 替换操作不当很容易把系统基础环境搞坏连 ssh、systemd 都可能起不来。我建议走两条更稳的路方案适用场景推荐程度换用 Rocky Linux 8.6 / CentOS Stream 8 / AlmaLinux 8系统可以重装或迁移最推荐原生离线安装很干净CentOS 7.9 Docker 离线运行 mongodb 镜像系统不能动又必须用 MongoDB 7.0推荐绕开 glibc/openssl 问题CentOS 7.9 原生硬装没有 Docker 也不允许换系统不推荐风险高且成功率低本文第 3 章的完整安装步骤我以 RHEL 8 兼容环境实测用的是 Rocky Linux 8.6为基准来写第 5 章单独讲 CentOS 7.9 上的 Docker 替代方案。这样既能满足“CentOS Linux 离线安装 MongoDB 7.0”的项目需求又不至于让你在错误的路线上浪费时间。2. 在有外网的机器上把安装包和依赖全部备齐2.1 需要准备哪些文件离线安装前建议先列一份清单。我这次实际用到的文件如下mongodb-linux-x86_64-rhel80-7.0.14.tgz mongosh-2.2.6-linux-x64.tgz其中第一个是 MongoDB Server 主程序包第二个是 MongoDB 官方的命令行客户端。这里很多人会忽略一个问题MongoDB 7.0 的 Server 包不再内置 mongo shell而是把 mongosh 单独发布。也就是说你只拷贝 server 包进内网装完之后会发现mongo命令不存在连验证服务都要再折腾一遍。我第一次离线部署 MongoDB 7.0 时就吃过这个亏所以现在准备物料时一定会把 mongosh 一并放进去。下载地址我习惯用官方源https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.14.tgz https://downloads.mongodb.com/compass/mongosh-2.2.6-linux-x64.tgz同时建议下载对应的 SHA-256 校验文件。离线安装包通常要经过 U 盘拷贝、杀毒扫描、审批流转等多道环节传输过程中文件被改动或损坏的概率不小提前校验能省去后面大量排障时间。2.2 下载与校验在有外网的环境里执行mkdir -p /opt/mongo-offline cd /opt/mongo-offline wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.14.tgz wget https://downloads.mongodb.com/compass/mongosh-2.2.6-linux-x64.tgz wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.14.tgz.sha256校验命令sha256sum -c mongodb-linux-x86_64-rhel80-7.0.14.tgz.sha256看到OK说明下载完整。如果输出FAILED不要犹豫直接重新下载。这一步几秒钟就能完成但很多人在内网部署失败后才回头检查结果发现是包本身被截断了白白浪费一晚上。2.3 内网传输与目录规划把两个 tgz 包通过 U 盘、FTP 或内网跳板机传到目标服务器的/opt/mongo-offline目录。我习惯在目标机器上先建一套清晰的目录结构mkdir -p /opt/mongo-offline mkdir -p /usr/local/mongodb/{bin,conf,data,logs} mkdir -p /usr/local/mongosh/bin为什么要把数据目录、日志目录、配置目录单独分出来因为 MongoDB 运行后会产生大量数据文件和日志跟二进制文件混在一起后续备份、日志切割、权限管理都会很痛苦。这种目录规划长期运维时会越来越香。另外我会把原始安装包复制一份到/root/backup/防止安装过程中误删导致重新走一遍外部审批。3. 原生离线安装全流程实测步骤3.1 解压并放置二进制在目标服务器上执行cd /opt/mongo-offline tar -zxvf mongodb-linux-x86_64-rhel80-7.0.14.tgz tar -zxvf mongosh-2.2.6-linux-x64.tgz解压后目录名通常是mongodb-linux-x86_64-rhel80-7.0.14里面bin/下有mongod、mongos等可执行文件。把相关命令复制到规划好的目录cp -a mongodb-linux-x86_64-rhel80-7.0.14/bin/* /usr/local/mongodb/bin/ cp -a mongosh-2.2.6-linux-x64/bin/* /usr/local/mongosh/bin/然后添加环境变量编辑/etc/profile.d/mongodb.shexport PATH/usr/local/mongodb/bin:/usr/local/mongosh/bin:$PATH使环境变量立即生效并验证source /etc/profile.d/mongodb.sh which mongod mongod --version如果mongod --version能正常输出版本信息说明 MongoDB 二进制在当前系统的 glibc 和 openssl 环境下能跑起来。如果这一步报GLIBC_2.28 not found说明系统不是 RHEL 8 兼容环境需要回到第 1 章重新确认系统版本。mongosh 也验证一下mongosh --version这里多说一句mongos和mongosh是两个完全不同的东西中间只差一个字母。mongos是 MongoDB 分片集群的路由组件mongosh才是命令行客户端。我第一次教别人装的时候有人把mongos当客户端去连接连不上还以为是离线包少了文件折腾了很久。3.2 编写 mongod.confMongoDB 从 4.x 开始推荐使用 YAML 格式的配置文件。下面这份是我在离线环境实测可用的最小化配置放在/usr/local/mongodb/conf/mongod.conf# /usr/local/mongodb/conf/mongod.conf systemLog: destination: file path: /usr/local/mongodb/logs/mongod.log logAppend: true storage: dbPath: /usr/local/mongodb/data wiredTiger: engineConfig: cacheSizeGB: 1 processManagement: fork: false net: port: 27017 bindIp: 0.0.0.0几个关键参数解释一下systemLog.logAppend: true日志追加写入而不是覆盖。MongoDB 重启后如果直接覆盖日志排障时想翻上次的启动记录就找不到了。storage.dbPath数据文件目录必须提前建好并且mongod运行用户要有写权限否则启动时会报权限相关错误。processManagement.fork如果用 systemd 托管服务这里必须写成false。systemd 希望服务进程在前台运行由它来统一管理守护状态。如果写成truemongod 会自己 fork 到后台systemd 会认为服务启动失败或者出现 start timeout。net.bindIp: 0.0.0.0允许所有网卡监听便于内网其他机器访问。如果只是本机用可以写成127.0.0.1更安全。wiredTiger.engineConfig.cacheSizeGBWiredTiger 存储引擎默认会占用物理内存的 50%如果机器内存只有 2G不显式设置的话可能会触发 OOM。建议根据机器内存提前规划比如 4G 内存的机器设成 1G 或 1.5G。3.3 配置 systemd 服务MongoDB 不建议直接用 root 账号跑我习惯创建一个独立的系统用户useradd -r -s /sbin/nologin mongod chown -R mongod:mongod /usr/local/mongodb然后创建 systemd 服务文件/etc/systemd/system/mongod.service[Unit] DescriptionMongoDB Database Server Documentationhttps://docs.mongodb.com/manual Afternetwork.target [Service] Usermongod Groupmongod EnvironmentLC_ALLC.UTF-8 EnvironmentLANGC.UTF-8 ExecStart/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/conf/mongod.conf ExecReload/bin/kill -HUP $MAINPID Restartalways LimitNOFILE64000 LimitNPROC64000 [Install] WantedBymulti-user.target这段配置有几个细节值得注意Usermongod和Groupmongod确保 MongoDB 以低权限用户运行避免写文件权限过高带来的安全风险。RestartalwaysMongoDB 意外退出后由 systemd 自动拉起适合数据库这类需要长期在线的服务。但是如果重复崩溃systemd 会按 rate limit 不断重启所以还是得靠日志定位根因。LimitNOFILE和LimitNPROC数据库通常需要较多的文件句柄和进程数限制建议显式调大。LC_ALL和LANG避免某些环境下 mongod 输出乱码或者 locale 相关告警。启动服务systemctl daemon-reload systemctl enable mongod systemctl start mongod systemctl status mongod启动后立刻看状态和日志tail -n 100 /usr/local/mongodb/logs/mongod.log ss -lntp | grep 27017看到27017端口在监听说明 mongod 进程已经起来了。如果日志中显示waiting for connections on port 27017说明一切正常。3.4 用 mongosh 做基础验证服务起来后用 mongosh 连接mongosh --host 127.0.0.1 --port 27017连接成功后在 mongosh 里执行db.runCommand({ ping: 1 }) db.version()ping返回{ ok: 1 }说明服务端正常工作。再插一条测试数据验证读写use testdb db.profile.insertOne({ name: offline-install-check, ts: new Date() }) db.profile.find()能正常写入和查询说明这套离线安装的核心链路已经通了。做到这里原生安装部分基本完成。4. 启动失败与连接失败两份排障记录4.1 报错 libcrypto.so.1.1 或 GLIBC_2.28 not found这是我被问到最多的错误几乎每个在 CentOS 7.9 上装 MongoDB 7.0 的人都见过mongod: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory或者./mongod: /lib64/libm.so.6: version GLIBC_2.28 not found原因其实很直白CentOS 7.9 自带 OpenSSL 1.0.2而 MongoDB 7.0 的 RHEL80 二进制依赖 OpenSSL 1.1 提供的libcrypto.so.1.1CentOS 7.9 的 glibc 版本是 2.17MongoDB 7.0 要求 glibc 2.28 以上。排查命令# 查看缺失的共享库 ldd /usr/local/mongodb/bin/mongod | grep not found # 查看系统当前 glibc 版本 strings /lib64/libc.so.6 | grep GLIBC_ | tail -n 5解决方案并不推荐“硬升级系统 glibc”。替换系统级 glibc 风险极高因为这个底层库几乎被所有程序依赖一个不兼容就可能让 ssh、systemd、yum 全部崩掉生产服务器直接失联。正确处理是换 RHEL 8 兼容系统或者用 Docker 跑。网上有一些复制高版本.so到自定义目录再设置LD_LIBRARY_PATH的做法只能作为临时验证不建议在业务环境使用因为 glibc 涉及底层系统调用不完整的环境容易引发内存校验错误、getaddrinfo 失败等隐蔽问题。4.2 mongod 启动后立即退出systemctl 显示失败现象systemctl start mongod systemctl status mongod输出● mongod.service - MongoDB Database Server Loaded: loaded (/etc/systemd/system/mongod.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code)我总结下来最常见的原因有四类原因典型报错处理方式数据目录或日志目录不存在Cannot create directory /usr/local/mongodb/data提前建目录并授权目录权限不足Permission deniedchown -R mongod:mongod /usr/local/mongodbmongod.conf 格式错误Error parsing YAML config file检查缩进和大小写端口被占用Address already in usess -lntp找占用进程排查顺序很有讲究journalctl -u mongod -n 50这条看 systemd 记录能快速定位到大概原因。但如果还看不清楚就直接手动前台启动/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/conf/mongod.conf前台启动时MongoDB 的日志会直接打印到终端不再经过 systemd 和日志文件很多问题一眼就能看到。我现在排查 MongoDB 启动故障几乎都是先跑这条命令比反复看 journalctl 高效得多。4.3 远程连不上防火墙、SELinux 和 bindIp另一种典型情况是服务器本机用 mongosh 能连但局域网内其他机器用mongodb://内网IP:27017就是连不上。按顺序排查第一步确认mongod.conf里的net.bindIp是不是0.0.0.0。如果保持默认的127.0.0.1外部网络当然连不上。很多新手改完配置后没有重启服务配置不生效也会出现这种情况。第二步检查 firewalldfirewall-cmd --permanent --add-port27017/tcp firewall-cmd --reload第三步检查 SELinux。如果getenforce返回Enforcing那大概率是 SELinux 拦住了 27017 端口。可以临时验证setenforce 0设为0之后如果能连上说明就是 SELinux 的问题。生产环境不建议直接关闭 SELinux更规范的做法是添加端口规则semanage port -a -t mongod_port_t -p tcp 27017CentOS 7 上如果没有mongod_port_t这个类型可以先安装policycoreutils-python-utils或者临时用http_port_t等已有类型放行。我个人比较务实内网开发环境可以接受setenforce 0但生产环境还是建议用规则放行不要图省事。5. 如果你手头只有 CentOS 7.9一条更稳妥的替代路线5.1 原生硬装的痛苦总结再说一遍核心结论CentOS 7.9 的底层环境是 glibc 2.17 OpenSSL 1.0.2MongoDB 7.0 的官方包要求 glibc 2.28 OpenSSL 1.1中间差了一个完整的大版本。虽然社区里确实有人通过替换 glibc 和 openssl 成功硬装了 MongoDB 7.0但这种操作在生产环境里一旦出问题恢复成本极高。我的建议很简单能换系统就换系统。Rocky Linux 8.6、AlmaLinux 8、CentOS Stream 8 都是 RHEL 8 兼容发行版跟 CentOS 7 的操作习惯差异不大迁移成本可控。如果你连系统迁移的审批都过不了那就走 Docker 方案。5.2 用 Docker 离线运行 MongoDB 7.0Docker 方案的本质是把 MongoDB 7.0 运行所需的操作系统环境封装在容器里和宿主机解耦。这样宿主机是 CentOS 7.9 也没关系容器内部可以是一个完整的 RHEL 8 兼容环境。离线准备步骤如下第一步在有外网的机器上拉取官方镜像并保存docker pull mongodb/mongodb-community-server:7.0.14 docker save mongodb/mongodb-community-server:7.0.14 -o mongodb-7.0.14.tar第二步准备好 Docker 引擎本身的离线安装包。CentOS 7 上可以直接用 rpm 方式安装 Docker提前用外网机器把 docker-ce 及其依赖拉全yumdownloader --resolve docker-ce第三步把mongodb-7.0.14.tar、Docker rpm 包以及依赖全部拷入内网。先离线安装 Docker再导入镜像docker load -i mongodb-7.0.14.tar第四步启动容器docker run -d \ --name mongodb7 \ --restartalways \ -p 27017:27017 \ -v /data/mongodb:/data/db \ mongodb/mongodb-community-server:7.0.14这里我把宿主机的/data/mongodb挂载到容器的/data/db确保 MongoDB 数据文件保存在宿主机磁盘上。即使容器被删掉、重新创建数据也不会丢。Docker 方案最大的优点是可以直接使用官方镜像稳定性和兼容性有保障最大的缺点是需要在现场安装 Docker离线准备量比原生安装多一步。如果你的内网已经有容器化基础设施这个方案基本就是最优解。5.3 我踩过几次坑之后的经验第一离线安装不是“一次性动作”而是“维护动作”。我每次装完 MongoDB都会把用到的 tgz 包、rpm 包、配置文件、systemd unit 文件全部整理到一个目录比如/opt/offline-packages/mongodb-7.0.14/。以后接新机器、同配置复制、版本升级直接整套拷过去比每次重新找包高效得多。第二养成“安装前校验”的习惯。离线包经过 U 盘、审批系统、杀毒软件层层流转文件很难保证完全没被动过。使用前跑一下sha256sum几秒钟的事能省下装到一半才报错的排查时间。第三MongoDB 7.0 默认使用 WiredTiger 存储引擎首次启动前一定要把storage.dbPath、wiredTiger.engineConfig.cacheSizeGB、net.bindIp、security.authorization这些关键参数想清楚。首次启动之后再改dbPath、replication这类参数会麻烦很多一次配好是最省事的。按这套流程我在 Rocky Linux 8.6 上离线装 MongoDB 7.0.14 只用了不到半小时在 CentOS 7.9 上走 Docker 方案也把服务稳定跑起来了。如果你在安装过程中遇到我这里没覆盖到的报错建议先执行journalctl -u mongod -n 200再手动前台启动mongod --config mongod.conf看实时日志绝大多数问题都能在这两步里定位出来。
返回列表