CentOS 7.9离线部署Nginx全攻略:从Yum本地源到源码编译
1. 项目概述与核心价值
最近在给一个客户做私有化部署,他们的服务器环境是内网隔离的,完全没法连外网。客户的需求很简单,就是要在几台CentOS 7.9的机器上把Nginx跑起来,用来做几个内部Web服务的反向代理和负载均衡。听起来是个基础活,但“离线”这两个字,让整个事情的复杂度直接上了一个台阶。你不能用yum install nginx一键搞定,所有依赖都得自己手动搬进去,版本兼容性、编译参数、启动脚本,每一个环节都可能是个坑。我花了差不多一天时间,从准备离线包到最终服务稳定运行,踩了几个不大不小的坑,也总结出了一套相对“傻瓜式”的流程。所谓“傻瓜式”,不是说完全无脑点下一步,而是把每一步为什么这么做、可能会遇到什么问题、怎么解决都讲清楚,让你即使第一次操作,也能按图索骥,稳稳当当地把Nginx在离线CentOS上部署起来。这篇文章,就是这份经验的完整记录,特别适合运维工程师、实施交付同学,或者任何需要在封闭网络环境中部署Web服务的场景。
2. 离线部署的整体思路与准备工作
离线部署的核心矛盾在于:我们需要在无法访问互联网的机器上,安装一个通常依赖网络包管理器的软件。解决这个矛盾,思路就清晰了:“线下准备,线上搬运”。我们需要在一台能联网的、环境尽可能与目标服务器一致的机器上,准备好Nginx及其所有依赖的离线安装包,然后把这些包完整地搬运到内网服务器上进行安装。
2.1 环境摸底与规划
动手之前,搞清楚目标服务器的“底细”至关重要,这直接决定了我们准备离线包的准确性。
- 操作系统版本确认:这是第一步,也是最重要的一步。必须精确到次版本号。通过
cat /etc/redhat-release命令,确认系统是 CentOS 7.9。不同的小版本(如7.6和7.9)的内核和基础库可能有细微差别,虽然大部分情况下兼容,但为了绝对稳定,我们尽量做到环境一致。 - 系统架构确认:执行
uname -m,确认是 x86_64(64位)还是 i386/i686(32位)。现在主流服务器基本都是64位,但确认一下总没错。我们的准备工作将基于 x86_64 进行。 - 现有软件环境探查:用
rpm -qa | grep -E ‘openssl|pcre|zlib’粗略看一下系统是否已经安装了Nginx可能依赖的核心库(如openssl、pcre、zlib)及其版本。这一步不是必须,但能帮助我们判断是否需要额外准备这些依赖。
基于以上信息,我们的作战计划如下:
- 准备机:找一台能联网的CentOS 7.9 x86_64虚拟机或物理机,作为我们的“弹药加工厂”。
- 部署机:目标内网CentOS服务器。
- 传输方式:由于网络隔离,通常使用U盘、移动硬盘或者通过跳板机使用
scp/sftp命令进行文件传输。
2.2 离线安装包的两种获取策略
为Nginx准备离线包,主要有两种主流方法,各有优劣。
策略一:使用Yum离线下载(推荐给新手)这种方法利用yum的downloadonly插件,只下载不安装,可以自动解决依赖关系,非常适合对RPM包依赖链不熟悉的朋友。
- 在准备机上,安装
downloadonly插件:yum install yum-plugin-downloadonly。 - 创建用于存放RPM包的目录,例如
mkdir /opt/nginx-offline。 - 执行下载命令:
yum install --downloadonly --downloaddir=/opt/nginx-offline nginx。这条命令会分析nginx安装所需的所有依赖,并把它们(包括nginx主包)下载到指定目录。
注意:默认的CentOS基础仓库可能不包含最新版的Nginx。如果你需要特定版本或更新版本的Nginx,需要先配置EPEL(Extra Packages for Enterprise Linux)仓库或Nginx官方仓库。对于离线环境,你需要在准备机上先配置好这些仓库,再执行下载。
策略二:源码编译打包(适合定制化需求)如果你需要开启特定的Nginx模块(如http_sub_module替换响应内容)、使用最新的稳定版,或者对性能有极致要求,源码编译是更灵活的选择。
- 在准备机访问Nginx官网(
nginx.org)下载所需版本的源码包(如nginx-1.24.0.tar.gz)。 - 同时,下载其依赖的源码包,通常包括:
openssl:用于HTTPS支持。pcre:用于正则表达式支持,location匹配依赖它。zlib:用于Gzip压缩。
- 在准备机上编译安装Nginx,记录下完整的
./configure参数。然后,我们并不直接使用编译好的二进制文件,而是将源码包和编译所需的依赖源码包打包,带到内网服务器上重新编译。这样做的好处是兼容性最好,避免因准备机和部署机库文件版本差异导致运行错误。
两种策略如何选?
- 求快、求稳,功能满足即可:选策略一(Yum离线下载)。这是最接近“傻瓜式”的方法。
- 需要特定版本、定制模块、深度优化:选策略二(源码编译)。本文将以策略一作为主线进行详细演示,因为它覆盖了更广泛的“快速部署”场景,并在最后补充策略二的关键步骤和注意事项。
3. 基于Yum的离线部署全流程实操
我们假设目标是通过Yum离线包完成部署。这是最常用、最不容易出错的方式。
3.1 阶段一:在联网准备机上制作离线包
首先,确保你的准备机是纯净的CentOS 7.9,避免残留的软件包影响依赖分析。
配置Yum仓库(关键步骤): 默认的
base仓库里的Nginx版本可能很旧。我们需要添加EPEL仓库来获取较新的稳定版。# 安装EPEL仓库的发布包 yum install -y epel-release安装后,你可以通过
yum info nginx查看可用的Nginx版本。如果需要Nginx官方的最新主线版或稳定版,则需要添加Nginx官方仓库,这里以稳定版为例:# 创建Nginx官方仓库文件 cat > /etc/yum.repos.d/nginx.repo << EOF [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key EOF实操心得:对于离线部署,
gpgcheck=1可能会导致问题,因为无法联网验证密钥。在内网部署时,可以在仓库配置中暂时将gpgcheck设为0,或者在准备机上下载好GPG密钥并一并打包带走。生产环境需权衡安全与便利。清理缓存并下载离线包:
# 清理旧缓存,确保下载最新元数据(在准备机联网状态下) yum clean all yum makecache # 安装downloadonly插件(如果未安装) yum install -y yum-plugin-downloadonly # 创建离线包目录 mkdir -p /opt/nginx-offline-packages # 下载Nginx及其所有依赖 yum install --downloadonly --downloaddir=/opt/nginx-offline-packages -y nginx执行完成后,检查
/opt/nginx-offline-packages目录,应该能看到一堆.rpm文件,其中必然包含一个名字类似nginx-1.xx.x-x.el7.x86_64.rpm的文件。额外依赖检查与补充: 有些隐式依赖可能在
downloadonly时没有被捕获,比如Nginx作为系统服务管理需要systemd(系统自带),但为了更保险,我们可以把一些常见的、可能缺失的基础依赖也一并下载。特别是,如果你的目标服务器是最小化安装(Minimal Install),那么很多开发库和工具可能没有。# 下载一些基础工具和库,在离线环境里会非常有用 yum install --downloadonly --downloaddir=/opt/nginx-offline-packages -y \ createrepo \ vim \ net-tools # 包含ifconfig等网络工具createrepo这个包非常重要,它用于为我们下载的这一堆RPM包创建一个本地的Yum仓库元数据,这样在部署机上我们就可以用yum localinstall来安装了,它能自动处理包之间的依赖关系。创建本地Yum仓库: 在离线包目录中生成仓库元数据。
cd /opt/nginx-offline-packages createrepo .执行成功后,目录下会多出一个
repodata文件夹。至此,一个完整的、包含Nginx及其依赖的本地Yum仓库就制作好了。打包并传输: 将整个
/opt/nginx-offline-packages目录打包。cd /opt tar -zcvf nginx-offline-packages.tar.gz nginx-offline-packages/然后,通过U盘、移动硬盘或内网文件传输工具,将这个
nginx-offline-packages.tar.gz压缩包拷贝到目标部署机的某个目录下,例如/tmp。
3.2 阶段二:在离线部署机上安装
现在,我们切换到那台不能上网的CentOS服务器上。
解压离线包:
cd /tmp tar -zxvf nginx-offline-packages.tar.gz -C /opt/现在,
/opt/nginx-offline-packages目录及其内部的repodata就位了。配置本地Yum源: 我们需要告诉部署机的Yum,除了光盘镜像,还可以从我们刚解压的这个本地目录里找软件包。
# 备份原有的repo文件(可选但建议) cd /etc/yum.repos.d/ mkdir bak mv *.repo bak/ # 创建本地仓库配置文件 cat > /etc/yum.repos.d/local-nginx.repo << EOF [local-nginx] name=Local Nginx and Dependencies Repository baseurl=file:///opt/nginx-offline-packages enabled=1 gpgcheck=0 # 因为我们没有配置GPG密钥,所以这里禁用检查 EOFbaseurl中的file://协议头后面跟的是绝对路径。清理并重建Yum缓存:
yum clean all yum makecache如果看到
local-nginx仓库的元数据被成功加载,就说明本地仓库配置成功了。安装Nginx: 现在,安装Nginx就和在联网环境下一样简单了。
yum install -y nginxYum会自动从我们配置的本地仓库中解析依赖并完成安装。
验证安装:
# 查看Nginx版本 nginx -v # 查看编译参数和模块(可选) nginx -V # 启动Nginx服务 systemctl start nginx # 设置开机自启 systemctl enable nginx # 检查服务状态 systemctl status nginx如果状态显示
active (running),恭喜你,Nginx服务已经成功跑起来了。防火墙放行(如果需要): 如果部署机开启了防火墙(firewalld),需要放行HTTP(80)和HTTPS(443)端口。
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload最后,打开浏览器,访问服务器的IP地址,你应该能看到Nginx的欢迎页面。
4. 源码编译方式的离线部署要点
对于选择源码编译路线的朋友,流程上有所不同,核心在于依赖的完整性和编译环境的一致性。
在准备机收集源码包:
- Nginx:
nginx-1.24.0.tar.gz(从 nginx.org 下载) - PCRE:
pcre2-10.42.tar.gz(从 pcre.org 下载,注意Nginx 1.21.5以后推荐pcre2) - OpenSSL:
openssl-1.1.1w.tar.gz(从 openssl.org 下载) - Zlib:
zlib-1.2.13.tar.gz(从 zlib.net 下载) 将所有*.tar.gz包打包,传输到部署机。
- Nginx:
在部署机准备编译环境: 源码编译需要编译器(gcc)和相关的开发库。如果你的部署机是最小化安装,这些都没有。一个讨巧的办法是,在准备机上用Yum的
downloadonly下载“Development Tools”工具组和这些依赖的开发包。# 在准备机上执行 yum groupinstall --downloadonly --downloaddir=/opt/development-packages “Development Tools” yum install --downloadonly --downloaddir=/opt/development-packages -y pcre-devel openssl-devel zlib-devel将这个
development-packages目录也打包传到部署机,并用类似创建本地仓库的方法安装这些编译工具和开发库。这是离线环境下搭建编译环境的关键。在部署机编译安装:
tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-pcre=../pcre2-10.42 \ --with-zlib=../zlib-1.2.13 \ --with-openssl=../openssl-1.1.1w make make install--with-pcre,--with-zlib,--with-openssl参数指向的是依赖源码解压后的目录路径,这样Nginx编译时会使用我们指定的、一起离线带过来的源码,而不是系统可能不存在或版本不匹配的库。创建系统服务: 源码安装的Nginx不会自动生成systemd服务文件。需要手动创建
/usr/lib/systemd/system/nginx.service文件,并配置正确的启动路径。这是源码安装比RPM安装多出来的一个管理步骤。
5. 部署后的关键配置与优化
安装成功只是第一步,让Nginx在你的业务场景中稳定、高效地工作,还需要进行配置。
5.1 核心配置文件解析
Nginx的主配置文件是/etc/nginx/nginx.conf(RPM安装) 或/usr/local/nginx/conf/nginx.conf(源码安装)。它的结构清晰,主要由以下几个块构成:
- main:全局设置,如工作进程数、用户、日志路径等。
- events:配置网络连接模型,如
worker_connections(每个工作进程的最大连接数)。 - http:包含所有HTTP相关的配置,这是最常修改的部分。
- server:在
http块内,定义一个虚拟主机(一个网站或服务)。 - location:在
server块内,用于匹配特定的URI,进行更精细的规则处理。
一个最简单的反向代理配置示例,放在/etc/nginx/conf.d/myapp.conf:
server { listen 80; server_name myapp.internal.com; # 你的域名或IP location / { proxy_pass http://192.168.1.100:8080; # 后端应用服务器的地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }注意:每次修改配置文件后,必须测试配置语法是否正确,然后再重载服务,而不是重启。
nginx -t # 测试配置文件语法 nginx -s reload # 平滑重载配置(不影响正在处理的连接) # 或者使用systemctl systemctl reload nginx
5.2 性能调优入门参数
在nginx.conf的main和events区域,有几个参数对性能影响较大,可以根据服务器硬件进行调整:
worker_processes:工作进程数。通常设置为与CPU核心数相等。可以通过auto参数自动设置。worker_connections:每个工作进程允许的最大并发连接数。这个值乘以worker_processes就是Nginx能处理的最大总连接数。需要结合系统的ulimit -n(文件描述符限制)来设置,不能超过系统限制。keepalive_timeout:客户端与Nginx之间长连接保持的时间。适当调大可以减少TCP连接建立和断开的开销,但会占用更多资源。对于高并发API服务可以调小,对于普通网站可以保持默认或稍大。gzip:启用压缩,可以显著减少传输文本内容(HTML, CSS, JS)的大小。在http块中配置gzip on;并设置相关参数。
5.3 日志管理与切割
Nginx默认日志会一直写入同一个文件,时间长了文件会巨大。我们需要配置日志切割。使用Linux自带的logrotate工具是最佳实践。 创建配置文件/etc/logrotate.d/nginx:
/var/log/nginx/*.log { daily missingok rotate 30 compress delaycompress notifempty create 640 nginx adm sharedscripts postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 `cat /var/run/nginx.pid` fi endscript }这个配置表示:每天切割一次日志,保留最近30天的归档,压缩旧日志,切割后通知Nginx重新打开日志文件。
6. 常见问题与故障排查实录
离线部署过程中,你大概率会遇到下面这些问题。我把它们和解决方法整理成了表格,方便快速查阅。
| 问题现象 | 可能原因 | 排查命令与解决方案 |
|---|---|---|
执行nginx -v提示-bash: nginx: command not found | 1. Nginx未安装成功。 2. 安装成功但可执行文件路径未加入系统PATH。 | 1. 检查是否安装:`rpm -qa |
systemctl start nginx失败,状态显示failed | 1. 配置文件语法错误。 2. 端口被占用。 3. 依赖的库文件缺失。 | 1.首要步骤:nginx -t检查语法。根据错误信息修改配置。2. 检查端口占用:`netstat -tlnp |
| 访问服务器IP,无法连接或拒绝连接 | 1. Nginx服务未运行。 2. 防火墙阻止了端口。 3. SELinux安全策略阻止。 | 1.systemctl status nginx确认服务状态。2. firewall-cmd --list-all查看防火墙规则,确保80/443端口开放。3. 临时禁用SELinux测试: setenforce 0。如果问题解决,说明是SELinux问题,需要配置正确的上下文或策略,生产环境不建议直接关闭,可以执行:chcon -Rt httpd_sys_content_t /usr/share/nginx/html(针对web目录)。 |
访问显示403 Forbidden | 1. 启动Nginx的用户(默认nginx)对网站根目录没有读取权限。2. 目录索引文件(如index.html)不存在。 | 1. 检查目录权限:ls -ld /usr/share/nginx/html/。确保Nginx用户(或nobody)有r-x权限。可以修改目录权限:chmod 755 /path/to/root或修改文件所有者:chown -R nginx:nginx /path/to/root。2. 确认根目录下存在 index.html或你在配置中指定的默认文件。 |
反向代理后端服务失败,日志显示502 Bad Gateway | 1. Nginx无法连接到后端服务(地址/端口错误,后端服务未启动)。 2. 后端服务响应超时。 | 1. 在Nginx服务器上测试连接后端:telnet <后端IP> <后端端口>或curl -v http://<后端IP>:<端口>。2. 检查Nginx的 proxy_connect_timeout和proxy_read_timeout配置值,适当调大。查看Nginx错误日志,通常会有更详细的连接失败原因。 |
使用本地Yum源安装时,提示No package nginx available | 1. 本地仓库元数据未正确生成或未加载。 2. 仓库配置文件路径 ( baseurl) 错误。3. 仓库未启用 ( enabled=0)。 | 1. 确认在离线包目录执行了createrepo .且生成了repodata文件夹。2. 检查 /etc/yum.repos.d/local-nginx.repo中的baseurl,确保路径正确无误,可以用file://协议访问到repodata父目录。3. 执行 yum repolist all查看local-nginx仓库是否被启用和加载。 |
磁盘空间充足,但df和du显示结果差异巨大 | 通常是有文件被删除,但仍有进程持有该文件的句柄,导致空间未释放。Nginx的日志文件如果被误删而未重载服务,就可能出现此问题。 | 1. 使用 `lsof |
一个典型的排错流程:当服务异常时,我习惯按以下顺序排查:1)systemctl status nginx看状态和最后日志;2)nginx -t测配置;3)tail -f /var/log/nginx/error.log看实时错误;4) 检查网络连通性(端口、防火墙);5) 检查权限和SELinux。这个顺序能解决90%以上的问题。
7. 进阶:将Nginx整合到企业级运维体系
当Nginx稳定运行后,我们可以考虑如何让它更好地融入自动化运维流程。
7.1 配置管理的版本化
手动修改nginx.conf是危险的,容易出错且难以回溯。建议将Nginx配置文件纳入版本控制系统(如Git)。可以建立一个专门的仓库,目录结构如下:
nginx-config-repo/ ├── nginx.conf # 主配置 ├── conf.d/ # 存放各个server配置片段 │ ├── app1.conf │ ├── app2.conf │ └── upstreams.conf # 上游服务器定义 ├── ssl/ # 存放SSL证书(注意.gitignore忽略私钥!) └── scripts/ └── deploy.sh # 部署脚本通过Git进行变更管理、代码评审和回滚。部署时,使用一个脚本将仓库中的配置文件同步到服务器的/etc/nginx/目录,然后执行nginx -t && systemctl reload nginx。
7.2 状态监控与健康检查
Nginx自带一个简单的状态模块ngx_http_stub_status_module(通常默认启用)。在配置文件中添加:
location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; # 只允许本机访问,安全考虑 allow 192.168.1.0/24; # 或者允许你的监控服务器网段 deny all; }访问http://your-server/nginx_status,你会看到类似这样的信息:
Active connections: 3 server accepts handled requests 10 10 20 Reading: 0 Writing: 1 Waiting: 2这些数据(活跃连接数、已处理的连接和请求数)可以被Prometheus、Zabbix等监控系统抓取,配合Grafana做成仪表盘,实时掌握Nginx的健康状况和性能指标。
7.3 负载均衡策略实践
在http块中,使用upstream块定义一组后端服务器,然后在location中用proxy_pass指向这个upstream。
upstream backend_servers { # 默认是轮询(round-robin) server 192.168.1.101:8080 weight=3; # weight权重,越高分配请求越多 server 192.168.1.102:8080; server 192.168.1.103:8080 backup; # backup服务器,当主服务器全部不可用时启用 # 其他策略: # ip_hash; # 基于客户端IP的哈希,实现会话保持 # least_conn; # 最少连接数 } server { location / { proxy_pass http://backend_servers; # ... 其他proxy参数 } }选择哪种策略取决于业务场景:无状态的API服务可以用轮询或最少连接;需要会话保持的Web应用可以用ip_hash(注意后端服务器扩容缩容时的影响)。
7.4 日志分析与安全考量
Nginx的访问日志包含了丰富的信息。你可以使用像GoAccess、awstats这样的工具进行离线分析,生成漂亮的报表,了解流量来源、热门页面、错误请求等。 安全方面,除了配置防火墙和谨慎的SELinux策略,还应该:
- 隐藏Nginx版本号:在
http块或server块中设置server_tokens off;,防止潜在攻击者针对特定版本漏洞进行攻击。 - 限制请求速率:使用
limit_req_zone和limit_req指令防止CC攻击。 - 禁用不必要的HTTP方法:在关键
location中配置if ($request_method !~ ^(GET|HEAD|POST)$) { return 444; }。 - 妥善保管SSL证书私钥:确保其权限为
600,且仅限root用户读取。
离线部署Nginx,从技术上看并不复杂,但极其考验准备工作是否细致周全。核心在于在联网环境下模拟出离线环境的所有需求。这份指南几乎涵盖了从规划、打包、安装、配置到排错和进阶的全过程。我最深的体会是,离线部署的成功,90%取决于准备阶段。那个本地Yum仓库的制作,以及编译环境依赖包的提前准备,是整个过程最关键的“胜负手”。下次再遇到类似的内网环境部署,无论是MySQL、Redis还是其他中间件,这套“线下打包、创建本地源、线上安装”的思路都是完全通用的。
