第一次批量接手新服务器的时候,我还在逐台手工敲命令。几十台机器从配置 yum 源、装基础工具、调内核参数到加固 SSH,每台至少折腾二十多分钟,错一台还容易埋隐患。后来我干脆把整套初始化流程整理成一个 CentOS 7 初始化脚本,新机器到手跑一遍,几分钟就能交付,输出日志一目了然。这篇文章就把这个脚本的设计思路、完整代码和踩过的坑一块儿分享出来,尤其是新手做运维或者自己折腾服务器的人,可以直接拿过去改改就用。
1. CentOS 7 初始化脚本到底在解决什么问题
先别急着看代码,我们得把问题聊透。很多人觉得初始化就是装个系统然后配个 IP,真正上过生产环境的人才知道,新机器落地这半小时能决定后面三个月省不省心。
1.1 手动初始化新机器的三个痛点
第一个痛点是重复劳动。公司采购一批服务器,硬件配置一致,装完 CentOS 7 之后要做的事情几乎完全一样:配源、装 epel、关 SELinux、设时区、调内核参数、建部署用户、加固 SSH、装 JDK、装 Docker。这些操作单看都不难,但一台一台手动敲,几十台下来既无聊又容易出错。
第二个痛点是顺序错乱。初始化各步骤之间是有依赖关系的,比如先配好 yum 源才能装软件包,先建好用户才能配置 sshd 的登录策略,先放通防火墙端口才能安全地修改 SSH 端口。手工执行时一旦打乱顺序,轻则某一步失败,重则把机器搞到连不上,只能让机房同事帮忙重启或者走 IPMI。
第三个痛点是配置漂移。三个人分别初始化三台机器,每个人的习惯不一样,有人顺手把 SSH 端口改成 2222,有人忘了关 SELinux,有人装了 Docker 但没设开机自启。半年后排查问题的时候,你会发现每台机器都是独一无二的“雪花服务器”,维护成本直线上升。
1.2 脚本设计必须死磕的四个原则
写初始化脚本不是把命令堆在一起就完事,我在实践中总结出四个核心原则。
第一是幂等性。脚本要有本事重复执行而不出乱子。比如创建用户之前先检查用户是否存在,安装软件之前先检查是否已安装,备份配置文件时加时间戳避免覆盖上一次的备份。做不到幂等,脚本跑第二遍就会报一堆错,运维同事会想骂人。
第二是可追溯性。脚本的每一步操作都要有日志输出,最好能落盘到 /var/log 下面。你想想,中午跑完脚本,晚上发现某台机器配置不对,如果没有日志,你根本不知道当时执行到哪一步、有没有报错。我习惯用一个 LOG_FILE 变量统一记录,并在关键步骤前后打点。
第三是模块化。每个功能点封装成独立函数,比如 set_yum_repo()、disable_selinux()、config_sshd()。这样做的好处是脚本可以按需裁剪,你不需要装 Docker 的公司注释掉对应函数就行,别人接手你的脚本也能一眼看懂整体流程。
第四是可配置性。把容易变化的参数抽到脚本头部集中管理,比如 SSH 端口、部署用户名、时区、需要安装的软件列表。改参数不用在代码里到处翻,改头部几行就行,配合配置漂移问题也能更快收敛。
1.3 脚本整体架构:从入口到出口的阶段划分
我习惯把初始化脚本分成四个阶段。前置检查阶段负责确认执行者是 root、机器能联网、系统版本符合预期。系统基础配置阶段负责 yum 源、epel、基础工具、SELinux、防火墙、时区。安全与账号阶段负责创建用户、配置 sudo、加固 SSH。应用安装阶段按需装 JDK、Docker、Git 等。最后统一打印执行总结,耗时情况一目了然。
这种分层的结构让我在不同项目里复用时特别舒服。新项目如果只要基础环境,后面两个阶段直接注释掉;如果是内网服务器,软件源配置改成公司私有镜像源即可。整个脚本像搭积木,而不是一盘散沙。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 初始化脚本的核心模块与关键参数设计
下面把各个模块逐个拆开讲。每个模块我都会说明为什么这么写、关键点在哪里、有哪些地方容易出问题。
2.1 软件源配置:决定后续能不能顺利装包
CentOS 7 的默认源指向 mirror.centos.org,但这个官方源体系已经进入维护末期,新装完的系统直接 yum 安装经常超时。所以脚本第一步就是切换软件源。我在大多数场景下会优先选择阿里云源,或者直接改用 vault.centos.org 这个归档源,具体看你公司的网络策略。
切换源之前一定要先做备份,把原始 .repo 文件移到带时间戳的备份目录,万一新源有问题还能回滚。然后下载新源文件,这里有个小坑:阿里云的 Centos-7.repo 文件里用到了 $releasever 变量,在 CentOS 7 上解析成 7 是没问题的,但如果你后面挂了 epel 源,epel.repo 里的 $releasever 也要确认能解析正确,否则会出现 baseurl 指向不存在的路径。
EPEL 源是安装很多额外软件包的前提,比如 htop、jq、python-pip 这些都不在默认源里。安装 epel-release 之后同样建议把 mirrorlist 注释掉,直接改用 baseurl 指向镜像地址,速度会快很多。
2.2 安全与访问控制:SELinux、防火墙与 SSH
SELinux 是初始化阶段绕不开的话题。很多应用在 CentOS 7 上装完跑不起来,排查半天发现是 SELinux 在拦。我在生产环境里偏向两种处理方式,要么直接关闭,要么保持 enforcing 但为应用写专门的策略。对于绝大多数中小团队,直接在初始化时关闭 SELinux 更省心。脚本里用 setenforce 0 临时关闭,再用 sed 修改 /etc/selinux/config 让重启后也保持关闭。
防火墙这里要分情况。如果服务器前面还有云安全组或者硬件防火墙,那么本机 firewalld 可以直接关闭,减少一层干扰。如果没有外部防护,则至少要放通 SSH 端口和业务端口。脚本里我做成一个变量,由使用者决定是 disable 还是手动加端口。
SSH 加固是安全重点。我会把 PermitRootLogin 设为 no,关闭 root 密码登录,开启 PubkeyAuthentication,设置 MaxAuthTries 为 3。但这里务必注意顺序:如果没有把公钥提前写入目标机器的 authorized_keys,一下子把密码登录关掉,密码登录又只允许 root 的话,你就进不去了。所以脚本里要先创建部署用户、生成或分发密钥,再改 sshd_config,最后 systemctl reload sshd,而不是 restart,reload 不会断开现有连接,这个细节能救命。
2.3 时间、内核参数与文件描述符限制
系统时间不同步会引发很多莫名其妙的问题,最典型的是 h
