管理好几十上百台服务器,核心思路是把 非标准化的烂摊子变成流水线作业。
- 凡是需要操作超过两次的,写成脚本。
- 凡是需要在两台机器以上执行的,用 Ansible。
- 凡是需要人肉盯着看的,交给 Prometheus。
摸底与规范化处理
刚接手大批量的机器时,最可怕的是乱。系统版本不一致,主机名未设置或与实际运行的服务不一致,等等。
因此,为了方便维护大批量的服务器,第一步就是要规范主机名。
规范主机名
按照 地区-环境-业务-角色-序号 的方式来给每台服务器修改HostName。通过Shell脚本,配合IP和主机名对应表,循环跑一遍hostnamectl set-hostname命令。
示例:bj-prod-shop-nginx-01
- bj:北京节点
- prod:生产环境
- shop:电商商城业务
- nginx:服务角色
- 01:第一台
统一系统版本
要想批量维护服务器时不出错,操作系统版本必须锁死。别一会儿 CentOS 7.6,一会儿 7.9,一会儿又冒出个 Ubuntu。内核版本不同,有些内核参数的表现是不一样的。
新机器到手,先跑一遍初始化脚本。主要包括以下内容:
- 更换 YUM/APT 源: 换成阿里云或清华源,内网有条件的自建 Repo 更好,速度就是生命。
- 安装基础工具包: vim, lrzsz, wget, curl, net-tools, sysstat (iostat, mpstat, sar 全靠它),tcpdump。哪怕现在用不上,装上总没错,省得排错时抓瞎。
- 时间同步(Chrony) :把 NTP 换成 Chrony 吧,同步速度快,精度高。配置好内网的 NTP server,别让 100 台机器都去公网对时,防火墙要是严一点就瞎了。
- 文件描述符限制: echo "* - nofile 65535" >> /etc/security/limits.conf。别等业务跑起来报 "Too many open files" 再去改,那时候通常得重启进程
使用Ansible自动化执行命令
大批量管理主机时,使用Ansible是最高效的选择。遇到在执行命令的时候遇到网络波动某些机器的某些命令没有执行,可以重复执行Ansilble脚本,因为它是幂等的。跑一次和跑十次,结果都是一样的,不会因为重复执行而出错。
SSH优化
Ansible 既然走 SSH,那 SSH 的连接速度就决定了你的执行效率。100 台机器,每台慢 1 秒,就是慢 100 秒。
- 关闭 DNS 解析:在 /etc/ssh/sshd_config 里设置 UseDNS no。否则每次连上去它都要反查你的 IP,慢得要死。
- 复用连接(ControlPersist):在你的管理机(Ansible控制端)的 ~/.ssh/config 或者 ansible.cfg 里配置开启 ControlMaster 和 ControlPersist。建立一次连接后,socket 文件保留一段时间,后续的命令直接复用通道,速度起飞。
Ansible调优
默认 Ansible 的并发数(forks)是 5。意思是一次只操作 5 台。遇到几百台机器的时候跑完得猴年马月。在 ansible.cfg 里,把 forks 改成 20 甚至 50。取决于你控制机的 CPU 和带宽。
示例: 批量分发配置:修改所有 Nginx 的 nginx.conf。
- name: Update Nginx Config
hosts: web_group
tasks:
- name: Push config file
copy:
src: ./nginx.conf
dest: /etc/nginx/nginx.conf
backup: yes # 关键!覆盖前先备份,救命用的参数
notify: Reload Nginx # 触发器,只有文件变了才重启
handlers:
- name: Reload Nginx
service:
name: nginx
state: reloaded合理配置监控
监控不是越多越好,是越准越好(可观测性)。
没有监控,运维就是瞎子。但几十上百台机器,如果监控策略没搞好,会触发洪水泛滥一般的“告警风暴”。
Prometheus + Grafana 是标配
放弃 Zabbix 吧(虽然它是经典),Prometheus 在自动发现和容器化支持上更现代化。
每台机器装个 node_exporter,这就把 CPU、内存、磁盘 IO、网络流量全收上来了。
关于 Load Average 的误区
很多新手喜欢监控 CPU 使用率,设定超过 80% 就报警。其实在 Linux 下,Load Average(负载) 往往比 CPU 使用率更能反映问题。
CPU 高可能是单纯计算密集型任务,机器还能响应。但如果 Load 高(超过 CPU 核数),说明有进程在排队等待 CPU 或者等待磁盘 IO(D状态进程)。
建议的报警策略:
- Load Average > CPU 核数 * 1.5(持续 5 分钟):严重报警。
- 磁盘剩余空间 < 15%:预警(给人处理的时间)。
- 磁盘 Inodes 使用率:别忘了这个!有时候磁盘没满,但小文件太多把 Inode 耗尽了,一样写不进数据。
告警收敛
这是个大坑。如果交换机抖了一下,大量机器同时报“网络不可达”,你的手机短信能瞬间炸了。
因此需要配置 Alertmanager 的 group_wait 和 group_interval,把同一时间段、同一类别的报警合并成一条发出来。比如:“[严重] 100台机器 SSH 连接超时”,而不是 100 条短信。
日志集中管理
当日志存储在本地的时候,如果机器少,出问题了 ssh 上去 tail -f /var/log/messages还可以接受。
但现在是个大的集群,里面可能有几十上百台机器。如果用户反馈“访问报错”,请求是随机分发到某台机器的,这时该怎么找?难道开 100 个终端窗口去 grep?
Loki+Promtail+Grafana
传统的 ELK (Elasticsearch, Logstash, Kibana) 确实强大,但是吃内存大户。Elasticsearch 维护起来也得要点水平。
如果资源有限,推荐 Loki + Promtail + Grafana (PLG)方案。
- Promtail:部署在每台服务器上,极轻量,只负责采集日志文件,打上标签(Label),推送到 Loki。
- Loki:日志存储。它不像 ES 那样做全文索引(费内存),它只索引标签。查日志的时候类似 grep,但是是分布式的 grep。
- Grafana:展示界面。
这样,开发跑过来问:“帮我查下这个订单号为什么失败”,你直接在 Grafana 里输入 {app="shop"} |= "ORDER123456",一秒钟出结果。
安全防护
Jumpserver 堡垒机
千万别把服务器的真实 IP 和 root 密码直接给开发人员,甚至运维内部也别互相传私钥。
搭建一个开源的 Jumpserver。
统一入口:所有人都得先登堡垒机,再跳转。
- 权限回收:某人离职了,你只需要在堡垒机上禁用他的账号,而不用去 100 台机器上删他的公钥。
- 录像审计:这是甩锅神器。万一数据库被删了,回放录像,谁敲的 rm -rf,几点几分敲的,一清二楚。
Sudo 权限控制
别给所有人 root。用 Ansible 批量分发 /etc/sudoers 配置。
利用 Linux 的 Group 功能,比如 dev 组只能 sudo systemctl restart nginx,而不能 sudo su -。精确控制权限范围。
评论 (0)