MongoDB 8.0 副本集
MongoDB 8.0 副本集 · 从零手动部署手册环境Rocky Linux 9.5 MongoDB 8.0.32 Community拓扑3 数据节点一主两从 1 client副本集名rs0完成时间2026-09-20 验收结果12/12 全绿见文末验证表配套脚本scripts/mongo-rs-prod-deploy.sh节点本地 · 角色化 · 幂等配套驱动tools/rsctl.py宿主机侧 SSH 扇出、tools/rs-dashboard.py验收台、tools/lab-start.py一键启停一、实验目标搭一套真实生产级的 MongoDB 副本集而不是能跑通的演示环境。二、拓扑与规划定档主机名IP角色规格磁盘说明mongo-pri10.10.10.70PRIMARY2 vCPU / 2 GB20G 系统 12G 数据盘priority2优先当选主mongo-sec110.10.10.71SECONDARY2 vCPU / 2 GB20G 12Gpriority1mongo-sec210.10.10.72SECONDARY2 vCPU / 2 GB20G 12Gpriority1mongo-client10.10.10.73client1 vCPU / 1 GB20G只装mongosh做连接验证配置项取值网络VMnet2 host-only10.10.10.0/24DHCP 关闭全静态副本集名rs0监听bindIp: 本机内网IP,127.0.0.1端口27017数据目录/data/mongodb独立 XFS 卷认证keyFile 内部认证 authorization: enabled服务托管systemdmongod.service开机自启 崩溃重启为什么内存底线是 2 GBMongoDB 8.0 的 WiredTiger 缓存默认(RAM−1GB)/2下限 256 MB。1 GB 机器必然触底2 GB 才是能正常喘气的起点。三、虚拟机是怎么来的快照克隆本项目采用从既有干净快照克隆而不是从 ISO 逐台装系统4 次交互式安装约 1 小时且容易装出不一致的环境。# 宿主机侧源机必须已关机vmrun-Tws cloneD:\rokey9.3\Rocky Linux 64 位.vmx\D:\MongoDB 实验\mongo-pri\mongo-pri.vmxfull\-snapshotok-cloneNamemongo-pri要点源机快照链是ok装机后干净态克隆体要剥掉uuid.*/ethernet0.generatedAddress/vmci0.id/nvme0.subnqnUUID强制 VMware 重生成身份否则与源机撞 MAC/UUID。每台数据节点再挂一块12 GB 稀疏盘vmware-vdiskmanager -c -s 12GB -t 0挂到nvme0:1。基线镜像实测画像项值发行版Rocky Linux 9.5 (Blue Onyx)内核5.14.0-503.14.1.el9_5→ 更新后5.14.0-687.49.1.el9_8安装形态最小化1056 包网卡ens160安全SELinuxEnforcing、firewalld active、chrony active磁盘单 20G NVMep1 /boot1G xfs p2LVMrl-root17G xfs无独立数据卷⚠️内核版本是硬约束MongoDB 与 Linux 内核6.19–7.0.13不兼容会崩。Rocky 9 的 5.14 内核安全。四、⚠️ 网络顺序本项目最容易踩的坑VMnet2是 host-only没有外网—— 而 MongoDB 走官方 dnf 源安装必须联网。所以顺序被锁死① 在 VMnet8(NAT) 上配静态 IP只写配置不动网络→ 系统就绪 → dnf update → 安装 MongoDB ② 关机 → vmx 切 VMnet2 → 开机静态 IP 这时才生效 ③ 在 VMnet2 上分发 keyFile → 写 mongod.conf → 启动 → rs.initiate → 验收反过来做会直接卡死先在 VMnet2 上起机器就再也装不上包了无外网、内网源也没跑。五、部署步骤Step 1 · 静态 IP 与主机名# 静态 IPhost-only 网络不设默认路由nmcli con mod ens160 ipv4.method manual ipv4.addresses10.10.10.70/24 nmcli con mod ens160 ipv4.never-defaultyesipv4.gatewayipv4.dnsnmcli con mod ens160 connection.autoconnectyeshostnamectl set-hostname mongo-pri# /etc/hosts 四台互解cat/etc/hostsEOF # mongo-rs-prod-deploy 10.10.10.70 mongo-pri 10.10.10.71 mongo-sec1 10.10.10.72 mongo-sec2 10.10.10.73 mongo-client EOFStep 2 · 系统就绪仅 3 台数据节点client 跳过# 时间同步副本集选举强依赖时间systemctlenable--nowchronyd# 内核参数grubby --update-kernelALL--argstransparent_hugepagenevercat/etc/sysctl.d/99-mongodb.confEOF vm.swappiness1 vm.zone_reclaim_mode0 vm.max_map_count262144 EOFsysctl--system# 文件描述符与进程数上限cat/etc/security/limits.d/99-mongodb.confEOF mongod soft nofile 64000 mongod hard nofile 64000 mongod soft nproc 64000 mongod hard nproc 64000 EOF# 数据盘12G 独立 XFS 卷mkfs.xfs-f/dev/nvme0n2mkdir-p/dataecho/dev/nvme0n2 /data xfs defaults,noatime 0 0/etc/fstabmount-a# 防火墙只放行内网到 27017firewall-cmd--permanent--add-rich-rule\rule familyipv4 source address10.10.10.0/24 port port27017 protocoltcp acceptfirewall-cmd--reload⚠️THP 的验证方式/sys/kernel/mm/transparent_hugepage/enabled的内容形如always madvise [never]——方括号里才是当前生效值。用awk {print $1}取会永远得到always恒假报失败。Step 3 · 安装 MongoDB 8.0.32cat/etc/yum.repos.d/mongodb-org-8.0.repoEOF [mongodb-org-8.0] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/x86_64/ gpgcheck1 enabled1 gpgkeyhttps://pgp.mongodb.com/server-8.0.asc EOF# ★ 必须显式导入公钥见第七节踩坑 #3rpm--importhttps://pgp.mongodb.com/server-8.0.asc systemctl disable--nowmongod2/dev/null||true# 装完先别让它自己起dnf-yupdate# 生产级基线1.6 GB / 656 包慢网络下 20 分钟dnfinstall-ymongodb-org-8.0.32# 数据节点# client 只装dnf install -y mongodb-mongosh离线/慢网环境优化多台装同一套包时先下一份再扇出别让每台都走公网见第七节踩坑 #4。# 宿主机一次下齐 → 推进各机 dnf 缓存缓存目录名由 repo 配置哈希决定同配置机器完全一致dnfinstall-y/root/mongo-rpms/*.rpm# 或 --rpm-dir/root/mongo-rpmsStep 4 · keyFile 与 mongod.conf# keyFile三台必须**同一份**否则内部认证失败openssl rand-base64756/etc/mongo-keyfilechmod400/etc/mongo-keyfilechownmongod:mongod /etc/mongo-keyfile md5sum /etc/mongo-keyfile# 三台比对必须一致/etc/mongod.confstorage:dbPath:/data/mongodbsystemLog:destination:filelogAppend:truepath:/var/log/mongodb/mongod.lognet:port:27017bindIp:10.10.10.70,127.0.0.1# 本机内网 IP 本机回环**不绑 0.0.0.0**processManagement:timeZoneInfo:/usr/share/zoneinforeplication:replSetName:rs0security:keyFile:/etc/mongo-keyfileauthorization:enabledSELinux 保持 enforcing只给数据目录打对标签dnfinstall-ypolicycoreutils-python-utils semanage fcontext-a-tmongod_var_lib_t/data/mongodb(/.*)?restorecon-Rv/datals-Zd/data/mongodb# 确认上下文启动systemctlenablemongod systemctl restart mongod systemctl is-active mongod ss-tln|grep27017# 应看到 127.0.0.1:27017 与 10.10.10.70:27017 两条Step 5 · 初始化副本集与建账号只在 mongo-pri 上做// 1) 初始化免认证本地例外窗口内rs.initiate({_id:rs0,members:[{_id:0,host:10.10.10.70:27017,priority:2},{_id:1,host:10.10.10.71:27017,priority:1},{_id:2,host:10.10.10.72:27017,priority:1}]})// 约 3 秒后应选出 PRIMARY// 2) 建管理员仍在本地例外窗口内可免认证db.getSiblingDB(admin).createUser({user:mongoAdmin,pwd:强口令,roles:[root]})// 3) 建应用最小权限账号 —— ★ 必须带认证db.getSiblingDB(appdb).createUser({user:appuser,pwd:强口令,roles:[{role:readWrite,db:appdb}]})第二节必须带认证authorization: enabled时本地例外只覆盖建第一个用户。第一个用户建完例外窗口立即关闭 —— 之后建第二个用户必须-u mongoAdmin -p pw --authenticationDatabase admin。这是本实验最容易卡住的一步报错还会被包装层吞掉只看到退出码 1。六、验收四项 十二项从client10.10.10.73发起四项硬指标#验收项怎么验实测结果1副本集健康rs.status().members看角色与 health✅ 1 PRIMARY 2 SECONDARYhealth12复制生效主库写 →直连从库读✅ 主写acktrue从库读到同一条3故障转移rs.stepDown(60)观察新主✅ 原主.70→ 新主10.10.10.714认证生效不带凭据连接✅ 被拒requires authentication扩展的 12 项体检tools/rs-dashboard.py判据与deploy --verify同源V0 4 台可达 V6 SELinux enforcing 放行内网 27017 V1 三节点 mongod 服务 active V7 MongoDB 版本 8.0.32 V2 27017 端口监听 V8 副本集健康1 主 2 从 health1 V3 keyFile 三台一致且 400 V9 复制生效主写→直连从库读 V4 dbPath 文件系统 XFS V10 认证生效无凭据被拒 V5 THPnever / swappiness1 V11 client 可用七、生产级体现在这#项目本方案1认证无keyFile 内部认证 管理员 应用最小权限账号2服务托管--fork手动拉起systemd 托管开机自启 崩溃自动重启3缓存cacheSizeGB: 0.25防 OOM按内存自动2 GB → 约 0.5 GB不再手工压4文件系统ext4dbPath 独立 XFS 卷WiredTiger 官方推荐5THP手写 rc.localgrubby 参数持久禁用6内核参数只改 swappiness加vm.zone_reclaim_mode0、vm.max_map_count262144、limits 640007SELinux关闭保持 enforcing只给数据目录打标签8防火墙关闭firewalld 仅放行内网源到 270179时间同步—chrony 校时副本集选举强依赖10备份无mongodump定时 从节点快照双轨11监控无FTDC 默认开启 db.serverStatus()巡检八、踩坑记录都是本实验实测authorization: enabled下本地例外只够建一个用户—— 建第二个用户必须带认证见 Step 5。THP 检查要取方括号里的值——awk {print $1}恒得always假报失败。必须在装包前显式rpm --importMongoDB 公钥—— dnf 的首次自动导入不可靠尤其当 RPM 是预置缓存命中时dnf 直接进签名校验却还没导过 key报公钥没有安装 / GPG 检查失败极易误判成缓存里的包坏了。注意rpm -qa显示的名字mongodb-mongosh-2.12.0-1.el8.x86_64不等于仓库文件名实际是mongodb-mongosh-2.12.0.x86_64.rpm要用dnf repoquery --location pkg拿真实 URL。多台装同一套包先下一份再扇出—— 本实验repo.mongodb.org单连接仅 ~180 KB/s4 台各下一份就是 4 倍公网流量。正确顺序先测速 → 一次下齐 → SFTP 扇出 → 各机从本地装。想事后从装好的那台捞包是行不通的dnf 默认keepcache0装完立刻删 RPM。连接串里的口令必须完整 percent-encode—— 只替换#不够口令里的会被 URI 解析器当成用户信息结束符直接报Invalid URL。用urllib.parse.quote(pwd, safe)。dnf -y update升级 openssh-server 会重启 sshd→ 正在跑的 SSH 会话当场掉线10054。这不是部署失败远端脚本仍在跑重连后查/root/logs/即可。SSH 横幅被 RST 的修法ping 通、22 端口开着但一连就重置 —— 是 guest 侧僵死连接撞上 sshd 限流。走vmrunVMware Tools 通道不依赖网络ss -K state established ( sport :22 )systemctl restart sshd。九、日常运维# 启停一键入口含开机自启切换python tools/lab-start.py# 开 VM → 等 SSH → 确保 mongod active → 等选出主 → 出验收台python tools/lab-start.py--status# 只报状态python tools/lab-start.py--stop# 收摊停 mongod 关 4 台 VMpython tools/lab-start.py--autostarton# 副本集巡检mongoshmongodb://mongoAdmin:pw10.10.10.70:27017,10.10.10.71:27017,10.10.10.72:27017/?replicaSetrs0authSourceadmin\--evalrs.status().members.map(m [m.name, m.stateStr, m.health])# 备份从节点上做避免压主库mongodump--hostrs0/10.10.10.70:27017,10.10.10.71:27017,10.10.10.72:27017\-umongoAdmin-ppw--authenticationDatabaseadmin--out/data/backup/$(date%F)# 手动主从切换mongosh同上连接串--evalrs.stepDown(60)# 回滚部署还原 /etc 配置 停服务sudobashscripts/mongo-rs-prod-deploy.sh--role1--undo十、验证表验收项判定命令期望实测主机名hostnamectl --staticmongo-pri/sec1/sec2/client✅ 四台正确静态 IPhostname -I10.10.10.70–73✅ 四台正确内核uname -r5.14.x避开 6.19–7.0.13✅5.14.0-687.49.1.el9_8MongoDB 版本rpm -q mongodb-org8.0.32✅ 三台一致mongod 服务systemctl is-active mongodactive✅ 三台 active端口监听ss -tln | grep 27017内网 IP 回环两条✅ 三台各 2 个 socketdbPath 文件系统findmnt -no FSTYPE /data/mongodbxfs✅ 三台 xfskeyFilemd5sum /etc/mongo-keyfile三台一致 权限 400✅ md5 相同副本集rs.status()1 主 2 从 health1✅复制主写 → 直连从库读从库读到同一条✅故障转移rs.stepDown(60)主自动切换✅.70→.71认证无凭据连接被拒✅THPcat /sys/.../enabled[never]✅ 三台 neverSELinuxgetenforceEnforcing✅ 三台验收台python tools/rs-dashboard.py12/12✅12/12 全绿