新加一台服务器,手动执行那套「建用户、装软件、改配置」的流程要半小时,还总会漏一步;第五台服务器到来时,这套流程就是不可承受之重。Ansible 解决的问题是:把运维操作写成可重复执行的代码,一台和一百台用同一份剧本。
为什么选 Ansible:无代理架构
Ansible 与被管机器之间只走 SSH——不需要在目标机器预装任何 agent 或服务。控制节点装好 Ansible,目标机有 Python 和 SSH 就行。对比 Puppet/SaltStack 需要先给全网装客户端,Ansible 的接入成本几乎为零,这也是它成为中小团队首选的原因。
Inventory:把机器编成名册
Inventory 是被管机器的清单,INI 格式(也支持 YAML):
[web]web1 ansible_host=10.0.1.11web2 ansible_host=10.0.1.12
[db]db1 ansible_host=10.0.2.11
[all:vars]ansible_user=deployansible_ssh_private_key_file=~/.ssh/id_ed25519要点:
- 方括号定义分组,一台机器可以属于多个组; playbook 按组指定操作对象。
ansible_host、ansible_user这类连接变量可以按主机、按组、按all全局三个层级设置,就近覆盖。
验证连通性(Ansible 的「hello world」):
ansible all -i inventory.ini -m ping-m ping 不是 ICMP,而是实际 SSH 上去执行一个 Python 模块,返回 pong 说明连接、认证、Python 环境全部就绪。
Ad-hoc:单行命令批量执行
不写剧本也能直接批量操作,适合一次性任务:
# 查看所有 web 机器的负载ansible web -i inventory.ini -m shell -a "uptime"
# 给所有机器安装 htopansible all -i inventory.ini -m apt -a "name=htop state=present" --become--become 表示在目标机提权(默认 sudo)。
Playbook:把流程写成 YAML
重复性任务要写成 playbook。例如「部署 Nginx 并启动」:
- name: 配置 web 服务器 hosts: web become: true tasks: - name: 安装 nginx apt: name: nginx state: present update_cache: true
- name: 下发站点配置 template: src: nginx.conf.j2 dest: /etc/nginx/sites-available/default notify: 重载 nginx
- name: 确保服务运行 service: name: nginx state: started enabled: true
handlers: - name: 重载 nginx service: name: nginx state: reloaded执行:
ansible-playbook -i inventory.ini site.yml幂等性:Ansible 最重要的设计
同一个 playbook 执行一次和执行一百次,结果应该相同。 Ansible 的模块大多遵循这个原则:apt: name=nginx state=present 表示「确保 nginx 处于已安装状态」——已安装就跳过,没装才装。这与 shell 脚本里裸写 apt install nginx 有本质区别:脚本每次执行都产生副作用,playbook 描述的是目标状态。
写 playbook 时警惕破坏幂等的写法:shell/command 模块没有状态概念,默认每次都执行。能用专用模块(apt、copy、template、file、user……)就不用 shell;必须用 shell 时,加 creates/removes 参数告诉 Ansible 如何判断「已经做过了」。
template 与 handler
template模块用 Jinja2 渲染配置文件,变量在运行时注入,同一份模板可以给测试、生产环境生成不同配置。handler是「变更后动作」:上面的例子里,只有配置文件真的发生变化时才会触发 nginx reload,配置没动就不打扰服务。这也是幂等思想的一部分。
高频模块速查
| 模块 | 用途 | 例子 |
|---|---|---|
apt / dnf | 包管理 | name=vim state=latest |
copy | 直接下发文件内容 | content="..." dest=/etc/motd |
template | Jinja2 模板下发 | src=app.conf.j2 dest=... |
file | 建目录、改权限 | path=/data state=directory mode=0755 |
user | 用户管理 | name=deploy shell=/bin/bash groups=sudo |
service / systemd | 服务管理 | name=nginx state=restarted enabled=true |
cron | 定时任务 | name=backup job="/opt/backup.sh" hour=3 |
lineinfile | 确保某行存在/不存在 | 改 sshd 配置单条参数 |
让 playbook 可维护的三条经验
- 敏感信息入 Vault:密码、私钥用
ansible-vault encrypt_string加密后再写进变量文件,仓库里只存密文。 --check+--diff先演习:ansible-playbook site.yml --check --diff只演算不执行,并展示将发生的变化,上线前必跑。- 任务命名要具体:
name: 安装 nginx比name: apt好——执行输出和失败定位都靠任务名。
延伸阅读
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 8 天
部分内容可能已过时