当前位置: 首页 > news >正文

用 Ansible playbook 批量初始化服务器:从手忙脚乱到一条命令

用 Ansible playbook 批量初始化服务器:从手忙脚乱到一条命令

刚拿到十台新机器,要装 Docker、建部署账号、配 SSH 密钥、关 root 密码登录、装监控 agent……如果你还在一台台 SSH 上去敲命令,不但慢,而且第三台漏了一步、第七台版本装错了都很正常。这篇用一个真实的「服务器初始化」场景,把 Ansible 从零跑通,重点讲那些文档里一笔带过、实际会绊住你的坑。

为什么是 Ansible 而不是一坨 shell 脚本

先说清楚 Ansible 到底解决了什么。你完全可以写个init.sh然后for host in ...; do ssh $host bash init.sh; done。但 shell 脚本有个致命问题:不幂等。脚本重复跑一遍,useradd deploy第二次就报错退出,echo xxx >> /etc/hosts会追加两遍。你不敢重复执行,也就没法「补跑失败的那几台」。

Ansible 的核心价值就是幂等:每个模块声明的是「最终状态」而不是「执行动作」。user模块说「deploy 用户应该存在」,已经存在就跳过,不存在才创建。同一个 playbook 跑一百遍,结果一致,失败了随时重跑。

Ansible 还不需要在目标机装 agent,走 SSH 就行,这也是它比 SaltStack/Puppet 上手快的原因。

第一步:装 Ansible 和写 inventory

控制端(你的笔记本或跳板机)装 Ansible,目标机什么都不用装,只要有 Python 和 SSH:

# Ubuntu/Debian 控制端sudoaptupdate&&sudoaptinstall-yansible ansible--version

inventory.ini描述你要管哪些机器,按角色分组:

[web] web1 ansible_host=10.0.1.11 web2 ansible_host=10.0.1.12 [db] db1 ansible_host=10.0.1.21 # 组的组:all_servers 包含 web 和 db 两组 [all_servers:children] web db # 给所有机器统一配连接参数 [all_servers:vars] ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_python_interpreter=/usr/bin/python3

先验证能连通,ping模块不是 ICMP,是「能不能 SSH 上去并跑 Python」:

ansible all_servers-iinventory.ini-mping

看到每台返回"ping": "pong"就通了。这一步跑不通,后面全免谈,先解决连接问题(常见是密钥没免密、或 root 登录被禁)。

第二步:写初始化 playbook

新建init.yml。这里做一件完整的初始化:建部署用户、下发 SSH 公钥、装基础软件、装 Docker、做一点安全加固。

----name:初始化服务器hosts:all_serversbecome:true# 以 sudo 提权执行vars:deploy_user:deploybase_packages:-curl-vim-git-htoptasks:-name:创建部署用户并加入 sudo 组ansible.builtin.user:name:"{{ deploy_user }}"groups:sudoshell:/bin/bashstate:present-name:下发部署用户的 SSH 公钥ansible.posix.authorized_key:user:"{{ deploy_user }}"state:present# lookup 从控制端本地读文件内容,不是从目标机读key:"{{ lookup('file', '~/.ssh/id_rsa.pub') }}"-name:安装基础软件包ansible.builtin.apt:name:"{{ base_packages }}"state:presentupdate_cache:true# 相当于先 apt update-name:安装 Docker(官方便捷脚本)ansible.builtin.shell:curl-fsSL https://get.docker.com|shargs:# 关键:已经装了就别再跑,手动补幂等creates:/usr/bin/docker-name:把部署用户加入 docker 组(免 sudo 用 docker)ansible.builtin.user:name:"{{ deploy_user }}"groups:dockerappend:true# append 很重要,否则会覆盖掉上面加的 sudo 组

运行:

ansible-playbook-iinventory.ini init.yml

输出里每个 task 会显示ok(已是目标态,没动)或changed(做了修改)。再跑一遍,你会看到几乎全是ok——这就是幂等的样子。

坑一:shell/command 模块默认不幂等,必须自己加 creates

上面装 Docker 用了shell模块。shellcommand是 Ansible 里少数不幂等的模块——它只管把命令跑一遍,不判断状态。你重复跑 playbook,curl | sh就会又下又装一遍。

解决办法是加creates(或removes)参数:creates: /usr/bin/docker的意思是「如果这个文件已存在,就跳过这个 task」。这样第二次跑就不会重装。凡是用shell/command,都要问自己:重复跑会不会出问题?会就加creates/removes,或者换成有幂等语义的专用模块。

坑二:append 不写,groups 会互相覆盖

注意上面把 deploy 用户先加进sudo组,后面又加进docker组。user模块的groups默认是覆盖语义——第二次设置groups: docker不加append: true的话,会把用户从 sudo 组里踢出去,只留 docker。加了append: true才是「追加到现有组」。这个坑很隐蔽,因为它不报错,只是权限悄悄变了。

坑三:安全加固要放最后,别把自己锁在门外

初始化常包含「禁用 root 密码登录」这类加固。顺序很重要:必须先确认 deploy 用户能免密登录、能 sudo,再去禁 root,否则你可能把自己锁在门外。加固 task 用lineinfile精确改配置,并在改完后重启 sshd:

-name:禁用 SSH 密码登录(仅允许密钥)ansible.builtin.lineinfile:path:/etc/ssh/sshd_configregexp:'^#?PasswordAuthentication'line:'PasswordAuthentication no'validate:'sshd -t -f %s'# 改完先校验语法,错了不落盘,防止 sshd 起不来notify:restart sshd# 触发下面的 handlerhandlers:-name:restart sshdansible.builtin.service:name:sshstate:restarted

这里两个关键点:validate让 Ansible 在写入前先用sshd -t检查配置语法,语法错了直接失败、不破坏原文件;notify+handlers是 Ansible 的经典模式——只有配置真的改变了才触发重启,没改动就不重启,避免每次跑 playbook 都无谓重启 sshd。

只对部分机器跑 / 只跑某些步骤

日常运维你常常只想操作一部分机器或一部分步骤。给 task 打 tag:

-name:安装 Dockeransible.builtin.shell:curl-fsSL https://get.docker.com|shargs:creates:/usr/bin/dockertags:[docker]

然后:

# 只对 web 组跑ansible-playbook-iinventory.ini init.yml--limitweb# 只跑打了 docker 标签的 taskansible-playbook-iinventory.ini init.yml--tagsdocker# 先看看会改什么,但不真改(彩排模式)ansible-playbook-iinventory.ini init.yml--check--diff

--check --diff尤其有用:上生产前先彩排一遍,看清楚每台会发生什么改动,再真正执行。

小结

  • Ansible 相比 shell 脚本的核心优势是幂等——声明最终状态而非动作,同一 playbook 跑一百遍结果一致,失败可随时重跑补齐。
  • 目标机零依赖(只需 Python + SSH),先用-m ping确认连通再干活。
  • shell/command是少数不幂等的模块,重复执行有副作用的一定要加creates/removes,或换成专用幂等模块。
  • user模块改groups记得append: true,否则组会被覆盖,权限悄悄变错还不报错。
  • 安全加固放最后、改 sshd 用validate校验语法 +notifyhandler 按需重启;上生产前用--check --diff彩排。
  • 一句话记忆点:Ansible 管的是「机器该是什么样」,不是「你要跑什么命令」——想清楚最终态,幂等自然就有了。
http://www.jsqmd.com/news/1193603/

相关文章:

  • RK3576开发板机器学习环境搭建与手写数字识别实战
  • 如何免费下载百度文库、道客巴巴等30+文档平台?kill-doc浏览器脚本终极解决方案
  • DS90UB662-Q1寄存器深度解析:构建稳定高速串行链路的实战指南
  • 如何利用zephyr-cn实现Zephyr容器化部署:新手友好的完整指南
  • 终极免费GTA5辅助工具:YimMenu完整使用与安全防护指南
  • 深度解密:5大实战技巧精通跨平台流媒体下载神器N_m3u8DL-RE
  • Windows 10官方ISO镜像下载全攻略:安全纯净的系统安装指南
  • 终极FGO自动战斗工具:Fate/Grand Automata专业配置指南
  • 如何永久备份微信聊天记录?WeChatExporter一键导出完整方案
  • 医院信息化-3 智慧医院“三位一体”评级实战指南:从标准解读到建设路径
  • VirtualLab通用探测器:光学仿真中的电磁场分析利器
  • Transformer推理优化终极指南:从500ms到10ms的完整实战方案
  • 【BGP协议实战解析】——从报文交互到路径选择的深度剖析
  • STM32L476 Nucleo开发板入门与低功耗应用实践
  • 如何快速配置Wand增强工具:完整功能扩展指南
  • PCB表面处理工艺:沉金与镀金技术对比与应用
  • C++ std::async 异步编程:原理、实战与性能优化指南
  • wordpress模板建站服务公司
  • 3个关键步骤:ExplorerPatcher如何破解Windows 11 22631版本的Win+X快捷键失效难题
  • ESP32终极图形库FabGL:从VGA显示到复古游戏模拟的完整指南
  • Windows 11系统优化终极指南:一键清理让你的电脑速度提升51%
  • 3步突破BT下载龟速:Tracker优化实战指南
  • Windows Home Server 2011安装测试:家庭服务器搭建与功能验证指南
  • 臻识车牌识别一体机HTTP推送数据解析与业务系统集成实战
  • 2026年7月寄半折等主流快递比价:德邦10kg跨省费用全解析 - 快递物流资讯
  • C++程序崩溃分析:Core Dump生成与GDB/LLDB调试实战
  • Verilog-A行为建模实战指南
  • SpringBoot启动图标进阶:从文本到彩色动态Banner的定制艺术
  • N皇后遗传算法Python实战:从原理到可调试工程实现
  • 遗传算法工程落地:从失效根因到产线级鲁棒优化器