ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CentOS离线环境安装stress:rpm依赖与本地yum源实战

CentOS离线环境安装stress:rpm依赖与本地yum源实战 简介面向CentOS Linux服务器运维与性能测试场景这套离线资源包解决无外网环境下压力测试工具链的部署难题适配需要在内网机房、隔离网络或离线交付环境中工作的系统管理员、运维工程师及性能测试人员可快速搭建压测环境。压缩包内共43个文件整体大小约46.66MB以11个rpm二进制安装包为核心组件辅以configure配置脚本、install-sh安装脚本、m4宏定义文件、texi格式说明文档等编译配套材料readme与changelog记录版本迭代信息c源码文件支持按需定制。资源集成stress-1.0.4压力测试工具及sar命令所需依赖组件可在完全离线条件下批量部署实现对CPU、内存、磁盘I/O及系统负载等多维度持续施压配合sar命令可同步采集压测过程中的性能指标便于后续分析。目前已有2587人学习下载。适合需要在内网或隔离环境中统筹压测工具链的读者包内目录结构清晰可依据需求选择对应组件安装直接开展压测实践与结果分析省去逐项排查在线依赖与版本匹配的步骤。1. 离线安装 stress先搞清楚它为什么让你卡在最前面你在新装好的 CentOS 服务器上敲下yum -y install stress几秒后收到一行No package stress available。这台机器在内网没有外网源默认仓库里翻遍了也没有 stress它属于 EPEL 扩展仓库而内网机器往往连 epel 的域名都解析不了。这个场景在服务器运维里再常见不过要做压测先得把这个小工具装上。本文只解决一件事——在 CentOS 离线环境下把 stress 的 rpm 包从有网的准备机带进内网按 rpm 依赖或本地 yum 源两种方式装好然后正确地对 CPU、内存和磁盘做压力验证。适合机房运维、性能测试工程师以及正在搭离线软件包仓库的同事参考。2. 离线安装前的准备rpm 还是本地 yum 源按场景选2.1 先理解 stress 的 rpm 依赖关系决定要带几个包很多人第一次离线装 stress 时以为要在外网机器上把整个 epel 仓库打包拷进去其实不用。stress 是个很轻的工具安装包本身只有几十 KB编译时链接了 glibc 的libc.so.6所以它最终真正依赖的只有 CentOS 系统自带的 glibc。也就是说你只要拿到 stress 本体 rpm多数情况下直接rpm -ivh就能成功。真正让离线安装翻车的从来不是依赖数量太多而是你拿错了架构或拿错了 el 版本。不过“多数情况下能直接装”不等于可以闭着眼睛拷。稳妥的做法是先在准备机上把依赖关系打印出来看一遍再决定要带哪几个包。准备机和目标机必须保持同一个大版本比如都是 CentOS 7否则后面会遇到 el 版本冲突的问题。# 在准备机上执行先确保 epel 仓库可用 yum install -y epel-release yum-utils yum deplist stress | grep -E dependency:|provider:yum deplist的输出大致是dependency: libc.so.6()(64bit)provider: glibc-2.17-xxx.el7.x86_64。这说明 stress 需要 64 位 glibc 提供libc.so.6而 CentOS 7 最小化安装默认就带 glibc 2.17目标机不用额外处理。真正要看的是 provider 那行里的 glibc 版本如果准备机比目标机新很多或者你把 el8 的 stress 包带到了 CentOS 7 上安装时就会报GLIBC_2.14 not found一类的符号缺失。先执行一次rpm -q glibc对一下能省掉后面大量排查时间。2.2 用 yumdownloader 在准备机上把依赖一次带齐确定依赖之后下一步是把需要的 rpm 文件从准备机上拉下来。常见做法是用yumdownloader --resolve它会自动把 stress 本体以及所有缺失依赖一起下载到当前目录。这个命令来自 yum-utils 包所以第一步先把它装好。mkdir -p /data/stress-rpms cd /data/stress-rpms yumdownloader --resolve stress ls -lh *.rpm--resolve的含义是“下载时同时解析依赖并一并拉取”目标是让这个目录在内网机器上变成一个自洽的安装集合。如果你只想要 stress 本体可以不加--resolve但考虑到内网机器缺包时补货成本极高我一般会连依赖一起带。下载完成之后把目录里的 rpm 全部拷进 U 盘或内网文件服务器再复制到目标机。拷完不要急着装先做一步校验sha256sum *.rpm与准备机上的输出对比一下。离线环境里最常见的低级事故就是 U 盘拷贝中 rpm 损坏导致安装时报“rpm 包校验失败”或装完一跑就段错误。2.3 多台机器批量装用 createrepo 做本地 yum 源而不是手工 rpm如果你只是给一台机器装手工rpm -ivh最直接如果要推五台十台我建议改用本地 yum 源。这里的逻辑是yum 只认仓库不认目录rpm 文件即使躺在磁盘上yum 也不会自动感知它。createrepo 会给这个目录生成 repodata 元数据再配一个baseurlfile://的 repo 文件内网机器就能像使用外网源一样让 yum 自己解析依赖关系并安装。# CentOS 7 上安装 createrepoCentOS 8 用 dnf install -y createrepo_c yum install -y createrepo createrepo /data/stress-rpms cat /etc/yum.repos.d/local-stress.repo EOF [local-stress] nameLocal Stress RPMS baseurlfile:///data/stress-rpms enabled1 gpgcheck0 EOF yum clean all yum install -y stress这里baseurlfile:///data/stress-rpms指向 2.2 中准备好的目录gpgcheck0是因为离线包的来源固定且你很难把 rpm 签名对应的公钥也一起带进来。如果公司安全规范要求验签就把准备机上的公钥导出带到内网并把这个值改为1。重点提醒createrepo之后目录里会多出一个repodata/子目录拷贝时要整目录复制只拷 rpm 文件的话 yum 依然识别不了。3. 手工 rpm 离线安装从依赖查找到安装成功的完整过程3.1 目标机先自查架构与 glibc 版本两条缺一不可拿到 rpm 包之后别急着装先在目标机上执行三句自查命令。很多离线安装失败不是包本身的问题而是目标机的基础环境和准备机不一致。uname -m rpm -q glibc ldd --version | head -n1uname -m输出x86_64说明是 64 位系统stress 的 rpm 包必须也是 x86_64 架构如果输出i686或i386你得去准备机上找 32 位版本的包。rpm -q glibc确认系统里 glibc 是否完整最小化安装的 CentOS 都会带但如果你做过精简裁剪这里可能会发现 glibc 缺失。ldd --version第一行是 glibc 具体版本号比如2.17把它和 stress rpm 包要求的最低版本做对比。这几个命令的输出记下来后面几乎所有依赖排查都要回来看它们。3.2 拷贝 rpm 并安装rpm -ivh 与 rpm -Uvh 的差别把 rpm 文件复制到目标机的/data/stress-rpms目录后执行安装命令。首选rpm -ivh因为它是“安装”语义对全新系统最直观如果系统里已经存在 stress它会明确提示package stress-XXX is already installed这时再用-Uvh做升级。rpm -ivh /data/stress-rpms/stress-*.rpm-i是 install-v是显示详细输出-h是打印进度条连起来足够看到每个 rpm 的安装过程。如果目录里有多个依赖 rpm可以直接用通配符一次装完rpm 会在同一个事务里检查所有包的依赖关系缺哪个会一次性列出来。看到error: Failed dependencies:时不要慌它列出的每一项都是当前系统缺失的库或符号。最常出现的libc.so.6()(64bit) is needed基本可以判定你拿错了架构回到 3.1 再核对一遍。如果依赖缺失列表中出现了libstdc.so.6这类 C 运行库说明目标机没有装 gcc 的运行时环境去准备机把libstdc的 rpm 一并下载带回来即可。3.3 安装后用哪三个命令验证才算真正成功安装命令返回成功不代表能用尤其是离线拷包场景。我验证 stress 安装是否真正成功固定用下面三个命令而不是只看一眼 rpm 输出。which stress rpm -q stress stress --versionwhich stress确认二进制文件落在 PATH 里一般会在/usr/bin/stress。rpm -q stress的输出如果是一串stress-1.0.4-16.el7.x86_64这样的版本号说明它已经写入 rpmdb后续卸载可以用rpm -e stress管理。stress --version是真正执行它能跑出版本号说明动态库链接正常这一步最能暴露“rpm 装上了但运行时缺符号”的问题。注意如果执行stress --version时系统无法打开共享库文件回到 3.1 对比 glibc 版本不要盲目重装。4. 装完别急着跑用 stress 压 CPU、内存的正确与验证方法4.1 stress 常用参数-c、-m、-d、-i、-t 到底什么意思stress 的命令行参数很朴素但每条都有明确分工。压测前先背熟这张表后面所有脚本都围着它转。参数全名作用常用值-c N--cpu N产生 N 个进程反复计算平方根占满 N 个逻辑 CPU小于等于逻辑核数-m N--vm N产生 N 个进程不断分配并释放内存由内存总量决定-d N--hdd N产生 N 个进程反复写入并删除临时文件1~4-i N--io N产生 N 个进程反复调用 sync()1~2-t N--timeout N持续 N 秒后自动退出压测时长--vm-bytes B每个 vm 进程分配的内存字节数不设默认 256MB512M / 1G--vm-hang N分配后挂起 N 秒再释放模拟内存驻留场景10~60--hdd-bytes B磁盘进程单次写入字节数用大值才看得出磁盘水位1G很多人误以为-c 1只占“半核”其实 sqrt 运算是纯 CPU 计算进程几乎不睡眠调度器把它塞进一个逻辑核就能把该核跑满。在超线程机器上负载读数会有些波动不用太纠结看/proc/loadavg的第一列即可。-m 1默认分配 256MB 内存多个 vm 进程叠起来会迅速耗尽内存压测脚本里最容易把机器搞挂的就是它所以单独压内存时务必配合--vm-bytes。4.2 最小压测命令4 个 CPU 进程跑 60 秒先跑一条最小命令验证 stress 能拉高负载。这台机器如果是 4 逻辑核用-c 4让它产生 4 个进程-t 60让它 60 秒后自动退出。stress -c 4 -t 60 watch -n 1 cat /proc/loadavgwatch -n 1每秒刷新一次/proc/loadavg你会看到第一个数字在 5 秒内迅速爬到 4.0 附近。注意它不会超过 4因为 stress 的 CPU 进程数由-c显式控制不是按机器核数自动扩展的。如果负载卡在很低的数值上先查 cgroup 的 CPU 限额cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us配合cpu.cfs_period_us计算一下当前容器或控制组允许使用的 CPU 配额配额不足时 stress 也会被限流。4.3 压内存与磁盘为什么 --vm-bytes 不设会“白压”只写-m 2的压测效果在一台 64G 内存的服务器上几乎看不到水位两个进程各分配 256MB总占用才 512MB。所以压内存的标准写法是显式指定--vm-bytes让单进程分配量直接压到内存总量的几分之一。stress -m 2 --vm-bytes 512M -t 60 free -h压磁盘时同理-d 1默认每个进程每次写 1GB 数据再删除在一台 SSD 机器上可能不到几秒就完成一轮磁盘 util 看不出持续压力。用--hdd-bytes 1G配合-d 1时iostat -x 1里的%util才会稳定在较高水平。注意stress 的磁盘压测会在当前目录或/tmp下创建临时文件跑完自动删除。如果目标目录写入权限不全磁盘压测会直接报错退出先cd /tmp或指定一个有写权限的工作目录。4.4 结束压测的三种方式压测时长失控是运维事故的高发点这里给你三种收尾手段。第一种是正规做法所有压测命令都带-t时间到了 stress 自动退出退出码为 0。第二种是手动中断前台运行时按CtrlCstress 收到 SIGINT 会清理临时文件后退出。第三种是强制终止进程已经失控、CtrlC 不管用的时候执行pkill -x stress。-x表示精确匹配进程名只杀 stress不会误伤名字包含 stress 的其他程序。需要特别注意的是SIGKILL强杀之后部分 hdd 临时文件可能来不及清理压测结束后检查一下/tmp下有没有stress.*.前缀的残留文件有就手动删掉。这个细节不处理下次跑同一台机器的磁盘压测时残留文件累计起来会把磁盘空间吃满。5. 离线安装 stress 的避坑记录四条翻车现场与处理办法5.1 No package stress availableepel-release 没装别急着怪离线现象在目标机上执行yum install -y stress结果报No package stress available于是以为离线环境装不了。原因CentOS 官方 base 仓库里没有 stress它存放在 EPELExtra Packages for Enterprise Linux仓库里。目标机没有安装 epel-releaseyum 根本不知道有这个包存在和离线无关。解决在准备机上下载epel-release-latest-7.noarch.rpmCentOS 8 对应 epel-release-latest-8拷到目标机用rpm -ivh装掉再执行yum install -y stress。如果目标机连 epel 域名也访问不了那就直接跳过 yum用第二章的方法把 stress 本体 rpm 拷进去手工安装这是离线场景最常见也最可靠的路径。5.2 提示缺少 libc.so.6()(64bit)八成是你拿错了架构包现象rpm -ivh stress-*.rpm时一条error: Failed dependencies: libc.so.6()(64bit) is needed by stress-...直接拦住安装。原因错误信息里的(64bit)是关键。它说明当前 rpm 包是 64 位系统上的版本你的机器系统架构不匹配。最常见的情况是把 i68632 位的 stress 包拷到了 x86_64 机器上或者是反过来。不要一看到“依赖缺失”就去准备机下载一堆 glibc先敲uname -m看看架构再核对 rpm 包名里是否带x86_64。解决去准备机上重新下载对应架构的 rpm。判断方法很简单uname -m是x86_64就只认文件名里带x86_64的包uname -m是i686就找i686的包。架构对齐之后这条报错基本不会再出现。5.3 el7 的包硬装到 CentOS 8反过来也不行现象CentOS 8 机器上安装 CentOS 7 的 stress rpm报错信息像package stress-1.0.5-1.el7.x86_64 is intended for a different operating system或者装完之后一执行就提示GLIBC_2.28 not found。原因el7 和 el8 的 rpm 包编译时链接的 glibc 版本基线不同。el7 的包在 CentOS 8 上装不上el8 的包在 CentOS 7 上会因为系统 glibc 版本过低而运行失败。这些都是“拿错源”导致的不是 stress 本身有问题。解决准备机上做yumdownloader时就要指定清楚目标系统。如果目标机是 CentOS 7.9就在 CentOS 7.9 的机器上下包目标机是 CentOS 8.5就在 CentOS 8.5 的环境上下包。我一般会在目录名上直接标注 el 版本比如stress-rpms-el7/、stress-rpms-el8/避免拷错。5.4 手工拷了 rpm 包yum localinstall 却总是报找不到现象把 rpm 文件放在目标机的/data目录后执行yum localinstall /data/stress-*.rpm提示依赖无法解析或根本找不到本地文件。原因yum localinstall的依赖解析仍然依赖已配置的 yum 仓库。如果 stress 的依赖包不在当前系统里而系统又没有可用仓库它就解不了依赖另外通配符在某些版本里还会把整套 repodata 缺失也当错误抛出来。解决如果你依赖齐全直接用rpm -ivh /data/stress-*.rpm最省事不用给 yum 参与的机会。如果你希望 yum 来解析依赖就不要用localinstall而是像 2.3 节那样createrepo出本地源再yum install -y stress。这两条路选一条走到头别混着来。5.5 本地源配好了yum install 还是说找不到包现象repo 文件写好baseurlfile:///data/stress-rpms也确认无误但yum install stress仍然报No package stress available。原因yum 有缓存机制。仓库元数据第一次生成后yum 会把 repomd.xml 缓存下来后续访问不再重新读取磁盘目录如果 createrepo 是在拷贝之后才执行的或者目录内容有过变化旧缓存就会失效。解决执行yum clean all清掉缓存再跑yum makecache重建最后yum repolist确认local-stress出现在仓库列表里。还有一个经常踩中的细节repo 文件如果是从别处复制的检查enabled1是不是被改成了0以及文件有没有放在/etc/yum.repos.d/目录下并以后缀.repo结尾。6. 把离线包做成可复用的部署目录脚本化后下次不再重复踩坑离线安装做到第三次我就开始厌倦重复敲命令了。现在我的习惯是维护一个固定的离线部署目录里面除了 rpm 文件还有一份校验文件和一段部署脚本。这个目录无论换到哪台内网机器一条命令装完跑一个 5 秒的冒烟测试确认能用再离开。#!/bin/bash # deploy_stress_offline.sh # 用法: bash deploy_stress_offline.sh /path/to/rpms set -euo pipefail RPMS_DIR${1:-/opt/stress-rpms} EXPECTED_ARCHx86_64 if [ $(uname -m) ! $EXPECTED_ARCH ]; then echo 架构不匹配当前 $(uname -m)需要 $EXPECTED_ARCH exit 1 fi rpm -q stress /dev/null 21 { echo stress 已安装: $(rpm -q stress) exit 0 } ls $RPMS_DIR/*.rpm /dev/null 21 || { echo 目录 $RPMS_DIR 里没有 rpm 文件 exit 1 } rpm -ivh $RPMS_DIR/*.rpm stress --version stress -c 1 -t 5脚本里set -euo pipefail的作用是任何一条命令失败就立即退出避免在依赖缺失的情况下继续往下跑最后留下一个半装状态。rpm -q stress先做幂等检查已经装过的机器直接跳过不用重复装。安装之后紧接着执行stress --version和stress -c 1 -t 5冒烟测试前者验证动态库链接正常后者验证 CPU 进程真的能拉起来。冒烟测试退出码为非 0 时脚本会因为set -e直接中断不会让你误以为装成功了。再补一条我踩过的问题不要在同一个目录里混放多个 el 版本或架构不同的 rpm。rpm -ivh $RPMS_DIR/*.rpm会把目录里所有包都装一遍混放时可能同时装进两个版本后面的包覆盖前面的排查起来比直接报错还麻烦。我的习惯是每个小版本一个子目录目录名带 el 标识拷贝时整目录搬运。校验这一步也放在部署目录里准备机上生成sha256sum *.rpm CHECKSUMS把 CHECKSUMS 文件一起拷进 U 盘目标机上执行sha256sum -c CHECKSUMS确认所有包完整。有次我图省事跳过校验拷贝的 rpm 在 U 盘里损坏了装完一跑stress --version就报错折腾到最后发现是包的问题。从那以后我的离线部署目录里永远放一份 CHECKSUMS 文件。这套方法不只适用于 stress你换成其他离线 rpm 包同样能用希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进