外观
环境初始化清单
新机器交付前一次性做完。这一节的每一项,后面出事时都会被当成"默认正确"的前提。
一、时区与时间同步
bash
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp true
timedatectltext
Local time: Wed 2026-10-28 00:02:11 CST
Universal time: Tue 2026-10-27 16:02:11 UTC
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: yes
NTP synchronized: yesbash
chronyc sources -vtext
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 10.0.0.1 3 6 377 31 -12us[ -45us] +/- 1.2ms^* 表示当前同步源。
时间不同步会连锁出事
- TLS 证书校验失败。
- Kafka/ZK 时间戳错乱,retention 行为异常。
- 分布式锁、JWT 过期判断错。
- 日志时间对不上,排障时误判。
云主机必须确保 NTP 可达;内网机器至少要能访问一台内网 NTP。
二、主机名与解析
bash
hostnamectl set-hostname kafka-1bash
cat >> /etc/hosts <<'EOF'
10.0.0.21 kafka-1
10.0.0.22 kafka-2
10.0.0.23 kafka-3
EOFbash
hostname -f
getent hosts kafka-2text
kafka-1
10.0.0.22 kafka-2主机名必须是短名 + 能反查,很多中间件(RabbitMQ、ZK、ES)依赖它。
DNS:
bash
cat /etc/resolv.conftext
nameserver 10.0.0.2
options timeout:1 attempts:2timeout:1 attempts:2 避免某个 DNS 不可用时卡 5 秒。
三、字符集与语言
bash
localectl statustext
System Locale: LANG=en_US.UTF-8
VC Keymap: us
X11 Layout: usbash
localectl set-locale LANG=en_US.UTF-8建议用 en_US.UTF-8:错误信息是英文,方便搜索;同时支持中文文件名。中文提示用 zh_CN.UTF-8,但部分老程序的日志会变乱码。
四、文件句柄与进程数
bash
ulimit -ntext
1024ini
# /etc/security/limits.d/99-base.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 4096
* hard nproc 4096limits.conf 对 systemd 服务不生效
systemd 启动的服务走 unit 里的 LimitNOFILE。两边都要配:
ini
[Service]
LimitNOFILE=65535五、内核参数
ini
# /etc/sysctl.d/99-base.conf
# 连接队列
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 16384
# TIME_WAIT 复用(客户端侧)
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_fin_timeout = 30
# 文件句柄
fs.file-max = 1000000
fs.inotify.max_user_watches = 524288
# 内存
vm.swappiness = 1
vm.overcommit_memory = 1
# 禁止 ICMP 重定向(防路由劫持)
net.ipv4.conf.all.accept_redirects = 0bash
sysctl -p /etc/sysctl.d/99-base.conftext
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
...vm.overcommit_memory=1 是 Redis 的硬要求(否则 BGSAVE 的 fork 会失败),其他服务也无害。
六、swap
bash
free -h
swapon --show数据库/缓存机器建议关掉:
bash
swapoff -a
sed -i '/ swap /s/^/#/' /etc/fstab通用机器可以留 2~4G 应急:
bash
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab七、防火墙
bash
systemctl status firewalld --no-pager
firewall-cmd --statetext
running只放通必要端口:
bash
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
firewall-cmd --list-alltext
public (active)
target: default
interfaces: eth0
services: ssh
ports: 8080/tcpUbuntu:
bash
ufw allow 22/tcp
ufw allow 8080/tcp
ufw enable
ufw status verbose云上还要开安全组
系统防火墙只是两层里的一层。云主机必须在控制台同时放通安全组,否则 ss 显示监听正常、firewall-cmd 也放通了,外部依然连不上。
八、SELinux
bash
getenforcetext
Enforcing不要图省事关掉,正确做法是加规则:
bash
# 允许 nginx 监听 8080
semanage port -a -t http_port_t -p tcp 8080
# 恢复文件上下文
restorecon -Rv /var/www确实要临时关(仅排障):
bash
setenforce 0永久关(不推荐):
bash
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config九、命令历史与审计
ini
# /etc/profile.d/history.sh
export HISTTIMEFORMAT="%F %T "
export HISTSIZE=10000
export HISTFILESIZE=20000
shopt -s histappendbash
source /etc/profile.d/history.sh
history | tail -3text
981 2026-10-28 00:05:12 systemctl restart nginx
982 2026-10-28 00:05:31 firewall-cmd --list-allHISTTIMEFORMAT 让每条命令带时间,出事后能回溯"什么时候改的"。
十、一次性检查脚本
bash
#!/usr/bin/env bash
set -uo pipefail
echo "== os =="; head -4 /etc/os-release
echo "== kernel =="; uname -r
echo "== time =="; timedatectl | grep -E 'Time zone|synchronized'
echo "== locale =="; locale | head -3
echo "== hostname =="; hostname -f
echo "== nproc =="; nproc
echo "== mem =="; free -h | head -2
echo "== disk =="; df -h | grep -vE 'tmpfs|overlay'
echo "== nofile =="; ulimit -n
echo "== swap =="; swapon --show || echo none
echo "== selinux =="; getenforce 2>/dev/null || echo n/a
echo "== firewall=="; firewall-cmd --state 2>/dev/null || ufw status 2>/dev/null || echo n/a
echo "== listen =="; ss -lntp | head -10十一、踩过的坑
| 现象 | 根因 | 处置 |
|---|---|---|
| 日志时间差 8 小时 | 时区/应用 TZ | timedatectl + 应用 TZ |
| TLS 证书校验失败 | 时间偏差大 | 开 NTP |
| 服务无法解析主机名 | /etc/hosts 缺失 | 补全集群节点 |
| 并发上不去 | ulimit -n 1024 | limits.conf + unit |
Redis fork: Cannot allocate memory | overcommit_memory | 设为 1 |
| 外部连不上,内部正常 | 安全组 | 控制台放通 |
| nginx 起不来、SELinux 报错 | 端口不在允许列表 | semanage port -a |
| 关 swap 后启动变慢 | 内存不足,之前靠 swap | 加内存,而不是开着 swap |