5 台机器要装同一个软件,你还在逐台 SSH?Ansible 让你一条命令搞定所有机器,零 Agent、纯 SSH、上手即用。
周末给 HomeLab 的 5 台机器做系统更新,常规做法是打开 5 个终端窗口,逐台 ssh 进去,敲 apt update && apt upgrade -y。结果经常是等第一台跑完,第三台早就断连了,只能重连、重来。说真的,这不是运维,是体力活。
如果你管理超过 2 台服务器,就该上 Ansible 了。
为什么是 Ansible
| 特性 |
Ansible |
Puppet/Chef |
Shell 脚本 |
| Agent |
不需要 |
需要 |
不需要 |
| 学习曲线 |
低 |
高 |
看你脚本能力 |
| 幂等性 |
内置 |
内置 |
自己写 |
| 模板引擎 |
Jinja2 |
ERB/HCL |
envsubst |
| 适合场景 |
批量操作+配置 |
持续配置管理 |
简单任务 |
Ansible 最大优势:不需要在目标机器装任何 Agent,纯 SSH 通信,装完 Ansible 就能用。
安装
控制端(你的工作机)安装 Ansible:
# Ubuntu/Debian
sudo apt update && sudo apt install -y ansible
# macOS
brew install ansible
# pip(推荐,版本最新)
pip install ansible
# 验证
ansible --version
目标机器只需要满足两个条件:SSH 可达 + Python 3 已安装(大部分 Linux 发行版自带)。
编写 Inventory
Inventory 告诉 Ansible 你有哪些机器。创建 hosts.ini:
[homelab]
k3s-master ansible_host=192.168.1.101
k3s-node1 ansible_host=192.168.1.102
k3s-node2 ansible_host=192.168.1.103
[docker-host]
dell-3430 ansible_host=192.168.1.104
[nas]
synology ansible_host=192.168.1.105
[homelab:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_ed25519
[all:vars]
ansible_python_interpreter=/usr/bin/python3
测试连通性:
ansible all -i hosts.ini -m ping
输出:
k3s-master | SUCCESS => {
"changed": false,
"ping": "pong"
}
k3s-node1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
...
全部 pong,说明所有机器就绪。
Ad-hoc 命令:批量操作一步到位
不想写脚本,只想快速执行一条命令?用 ad-hoc:
# 所有机器同时更新包索引
ansible all -i hosts.ini -m apt -a "update_cache=yes" --become
# 查看所有机器磁盘使用
ansible all -i hosts.ini -m shell -a "df -h / | tail -1"
# 批量重启 K3s 节点上的容器运行时
ansible homelab -i hosts.ini -m systemd -a "name=containerd state=restarted" --become
# 批量安装 htop
ansible all -i hosts.ini -m apt -a "name=htop state=present" --become
常用的 -m 模块:
| 模块 |
用途 |
示例 |
ping |
测试连通性 |
ansible all -m ping |
shell |
执行 shell 命令 |
-m shell -a "uptime" |
apt |
管理包(Debian 系) |
-m apt -a "name=nginx state=present" |
copy |
拷贝文件 |
-m copy -a "src=app.conf dest=/etc/" |
file |
管理文件/目录 |
-m file -a "path=/data state=directory" |
systemd |
管理服务 |
-m systemd -a "name=nginx state=started" |
user |
管理用户 |
-m user -a "name=deploy state=present" |
第一个 Playbook:一键更新所有机器
Ad-hoc 适合临时操作。复杂任务需要 Playbook——YAML 格式的任务编排。
创建 update-all.yml:
---
- name: 批量更新 HomeLab 所有机器
hosts: all
become: yes
tasks:
- name: 更新包索引
apt:
update_cache: yes
cache_valid_time: 3600
- name: 升级所有包
apt:
upgrade: dist
- name: 清理不需要的包
apt:
autoremove: yes
- name: 检查是否需要重启
stat:
path: /var/run/reboot-required
register: reboot_flag
- name: 提示需要重启的机器
debug:
msg: "{{ inventory_hostname }} 需要重启!"
when: reboot_flag.stat.exists
- name: 显示磁盘使用情况
shell: df -h / --output=pcent | tail -1
register: disk_usage
- name: 打印磁盘使用率
debug:
msg: "{{ inventory_hostname }}: 根分区已用 {{ disk_usage.stdout | trim }}"
执行:
ansible-playbook -i hosts.ini update-all.yml
Ansible 会逐台执行,每步都打印结果。register 可以保存命令输出,后面用 when 做条件判断——这就是 Playbook 比 Shell 脚本强的地方:逻辑编排 + 幂等性。
进阶:用模板批量配置
假设你要给 3 台 K3s 节点配置不同的 hostname 和 hosts 文件。用 Jinja2 模板:
创建 templates/hosts.j2:
127.0.0.1 localhost
{{ ansible_host }} {{ inventory_hostname }}
{% for host in groups['homelab'] %}
{{ hostvars[host]['ansible_host'] }} {{ host }}
{% endfor %}
在 Playbook 中使用:
- name: 配置 hosts 文件
template:
src: hosts.j2
dest: /etc/hosts
backup: yes
notify: reboot
template 模块会自动渲染 Jinja2 模板,变量从 inventory 和 facts 中来。notify 会在文件变更时触发 handler:
handlers:
- name: reboot
reboot:
msg: "配置变更,重启中"
实战:HomeLab 初始化 Playbook
把上面所有招数组合起来,写一个完整的初始化脚本:
---
- name: HomeLab 机器初始化
hosts: all
become: yes
vars:
common_packages:
- htop
- vim
- curl
- wget
- net-tools
- python3-pip
tasks:
- name: 安装常用工具
apt:
name: "{{ common_packages }}"
state: present
- name: 创建运维用户
user:
name: ops
groups: sudo
shell: /bin/bash
- name: 部署 SSH 公钥
authorized_key:
user: ops
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
- name: 禁止 root 密码登录
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin prohibit-password"
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
一条命令,所有机器初始化完毕。下次加新机器,加到 inventory 里重跑一次就行——这就是幂等性的好处。
小结
Ansible 的核心思路:用声明式的方式描述"机器应该是什么状态",而不是"怎么变成这个状态"。
- Inventory 管理机器列表
- Module 执行具体操作
- Playbook 编排任务流程
- Template 生成配置文件
- Handler 处理变更后的动作
下一篇,我们聊 Terraform——用同样的思路管理基础设施资源(VM、网络、存储),让 HomeLab 的环境搭建也变成代码。