2. 环境标准化:操作系统选型与配置、内核参数调优、基础依赖安装
环境标准化,说白了就是给所有机器定一个“出厂设置”。
我见过太多团队,开发用 CentOS 7,测试用 Ubuntu 18,生产又换成 Rocky Linux。结果呢?同一个参数在不同发行版上表现完全不一样,排查问题能查到崩溃。所以,环境标准化是部署实践的第一道防线。
2.1 操作系统选型:别纠结,选主流
选操作系统,我个人习惯看三点:生态成熟度、商业支持、生命周期。
| 发行版 | 适用场景 | 生命周期 | 我的建议 |
|---|---|---|---|
| Rocky Linux / AlmaLinux | 生产环境、核心业务 | 10年(与RHEL同步) | 首选,稳定且免费 |
| Ubuntu LTS (20.04/22.04) | 容器化、K8s、AI/ML | 5年 + 5年扩展 | 适合新项目,包更新快 |
| Debian Stable | 高稳定性、低变更场景 | 3年 + 2年LTS | 极稳,但软件版本偏旧 |
| CentOS 7 (已停维) | 遗留系统迁移 | 已结束 | 尽快迁移,别犹豫 |
核心原则:全环境(开发、测试、预发、生产)使用同一个大版本。比如统一用 Rocky Linux 9.x,不要开发用 8.x,生产用 9.x。
为什么?因为不同大版本的内核参数默认值、glibc 版本、systemd 行为都不一样。我曾经在 CentOS 7 上调好的 TCP 参数,迁移到 Rocky 9 后直接导致连接超时——因为内核从 3.10 跳到了 5.14,很多参数名和默认值都变了。
2.2 内核参数调优:别照抄,要理解
内核参数调优,是环境标准化里最容易出问题的地方。很多人从网上抄一段 sysctl.conf,往生产上一丢,结果网络断了、内存爆了。
我建议按场景来调,而不是盲目堆参数。下面是我常用的几个调优模板:
2.2.1 网络性能(高并发场景)
# /etc/sysctl.d/99-network.conf
# 连接跟踪
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 600
# TIME_WAIT 优化
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# 端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 快速回收(注意:内核 4.12+ 已移除 tcp_tw_recycle)
# net.ipv4.tcp_tw_recycle = 0 # 别用,NAT 环境下会出大问题
避坑指南:我曾经在生产环境开启了 tcp_tw_recycle,结果导致 NAT 后面的用户大量出现连接失败。因为该参数会丢弃时间戳不匹配的包。从内核 4.12 开始,这个参数已经被移除了,但如果你还在用旧内核,千万别开。
2.2.2 内存与文件系统(数据库/缓存场景)
# /etc/sysctl.d/99-memory.conf
# 减少 swap 使用
vm.swappiness = 10
# 脏页回写
vm.dirty_ratio = 30
vm.dirty_background_ratio = 5
# 文件句柄
fs.file-max = 2097152
# 共享内存(Redis/PostgreSQL 需要)
kernel.shmmax = 68719476736
kernel.shmall = 16777216
2.2.3 安全加固(通用场景)
# /etc/sysctl.d/99-security.conf
# 防 SYN 攻击
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
# 防 IP 欺骗
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 禁 ICMP 重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
生效方式:sysctl -p /etc/sysctl.d/99-network.conf。建议每个场景单独一个文件,方便排查和回滚。
2.3 基础依赖安装:最小化 + 版本锁定
基础依赖,我遵循两个原则:最小化安装和版本锁定。
最小化,就是只装你需要的。别图省事装个 Development Tools 组包,那会带来几百个不必要的包,增加攻击面。
版本锁定,就是通过包管理器固定版本,避免“昨天还能跑,今天就不行了”的尴尬。
2.3.1 必备工具清单
| 类别 | 工具 | 说明 |
|---|---|---|
| 编译工具 | gcc, make, cmake | 编译 C/C++ 组件 |
| 脚本语言 | Python 3, Perl | 自动化脚本依赖 |
| 网络工具 | curl, wget, net-tools, iproute | 网络诊断与调试 |
| 系统工具 | vim, htop, lsof, strace | 日常运维与排障 |
| 安全工具 | openssl, ca-certificates | TLS/SSL 通信 |
2.3.2 版本锁定示例(Rocky Linux)
# 安装 epel 和 yum-versionlock
dnf install -y epel-release yum-versionlock
# 锁定关键包版本
yum versionlock add python3 curl openssl
# 查看已锁定的包
yum versionlock list
我的习惯:在基础镜像或初始化脚本里,把 versionlock 作为最后一步。这样后续任何 dnf update 都不会意外升级这些关键依赖。
2.4 环境标准化流程图
下面这张图,是我做环境标准化时的核心流程。你想想看,如果每一步都按这个来,环境差异带来的问题至少能减少 80%。
2.5 自动化:用代码固化标准
手动配环境,一次两次还行。但你要管理 100 台、1000 台机器呢?必须自动化。
我个人习惯用 Ansible 来做环境初始化。下面是一个简化版的 playbook 示例:
---
- name: 环境标准化初始化
hosts: all
become: yes
tasks:
- name: 设置内核参数
sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
- { name: 'net.ipv4.tcp_fin_timeout', value: '15' }
- { name: 'vm.swappiness', value: '10' }
- { name: 'fs.file-max', value: '2097152' }
- name: 安装基础依赖
dnf:
name:
- gcc
- make
- curl
- vim
- htop
state: present
- name: 锁定关键包版本
command: yum versionlock add python3 curl openssl
args:
warn: false
小技巧:把内核参数文件(/etc/sysctl.d/*.conf)和依赖清单纳入 Git 管理。每次变更都走 PR 评审,这样谁改了什么东西,一查就知道。
2.6 验证:环境标准化 checklist
做完以上步骤,别急着上线。先跑一遍验证脚本。我常用的检查项:
- 内核版本:
uname -r,确认与预期一致 - 参数生效:
sysctl -a | grep tcp_fin_timeout,确认值已修改 - 文件句柄:
ulimit -n,确认已调大 - 依赖版本:
python3 --version,确认与锁定版本一致 - 安全基线:
sysctl net.ipv4.tcp_syncookies,确认已开启
我曾经踩过的坑:有一次我调完内核参数,sysctl -p 也执行成功了,但重启后参数全部恢复默认。排查了半天,发现是 /etc/sysctl.d/ 目录下的文件没有执行权限。嗯,systemd 读取这个目录时,会跳过不可执行的文件。所以记得 chmod +x /etc/sysctl.d/*.conf。
环境标准化,说白了就是“把不确定性降到最低”。操作系统选型、内核参数、基础依赖,这三件事做好了,后续的部署、扩容、灾备都会顺畅很多。别嫌麻烦,这一步省下的时间,会在后面十倍百倍地还给你。