一、什么是 Ansible Playbook
学习 Ansible 时,我们通常使用 Ad-Hoc 临时命令,例如:
ansible all -i inventory.ini -m ping或者:
ansible k8s_cluster -i inventory.ini -m shell -a "hostname"这种方式适合执行简单、临时的操作,比如快速验证某台服务器的连通性,或者临时查看某个服务的运行状态。它的优点是输入方便、反馈直接,适合在排查问题时随手使用。
但是在真实运维工作中,我们经常需要执行一系列固定操作,例如:
安装软件,修改配置文件,启动服务,配置防火墙,创建用户,分发文件,重启服务,批量部署Kubernetes
如果每次都手动输入命令,效率非常低。一方面,命令一多就容易出错,比如漏掉某个步骤、写错参数;另一方面,这些操作往往需要在多台服务器上重复执行,手动操作不仅耗时,而且难以保证每台机器的配置完全一致。
这时候就需要使用Ansible Playbook。
Playbook 本质上就是一个 YAML 格式的自动化脚本,可以把多个运维操作写成一个完整的执行流程。它把“做什么”“在哪台机器上做”“以什么权限做”都清晰地描述出来,形成一份可读、可复用、可版本管理的运维文档。
例如,我们要在一批服务器上完成 nginx 的部署,手动操作需要依次执行以下步骤:
连接服务器 ↓ 安装 nginx ↓ 启动 nginx ↓ 设置开机自启 ↓ 检查 nginx 状态这些操作都可以通过一个 Playbook 自动完成。只要写好一次,之后无论是对 3 台还是 30 台服务器,都能一键批量执行,并且每次执行的结果都是可预期的、一致的。
简单来说,Ad-Hoc 命令适合“临时、单次、简单”的操作,而 Playbook 适合“固定、重复、复杂”的运维流程。掌握了 Playbook,就相当于把日常运维工作从“手动敲命令”升级为“编写自动化脚本”,这也是迈向自动化运维的第一步。
二、Playbook 基本结构
一个最简单的 Playbook:
--- - name: Test Ansible Playbook hosts: all become: yes tasks: - name: Show hostname command: hostname保存为:
test.yml执行:
ansible-playbook -i inventory.ini test.ymlPlaybook 结构说明
--- - name: Test Ansible Playbook表示:play的名称
主要用于描述这个 Playbook 的作用。
hosts: all表示在哪些主机上执行。
例如:
hosts: all所有主机。
hosts: k8s_cluster只在 Kubernetes 集群执行。
hosts: web_servers只在 Web 服务器组执行。
become: yes表示使用 sudo 提权。
相当于:
sudo command例如普通用户连接服务器:
ubuntu但是安装软件需要 root 权限。
那么:
become: yes就非常重要。
tasks:表示任务列表。
一个 Playbook 可以包含多个任务。
例如:
tasks: name: Task 1 command: hostname name: Task 2 command: uptimeAnsible 会按照顺序执行。
三、第一个 Playbook 实战
进入 Ansible 工作目录:
cd /root/ansible-k8s创建文件:
nano test.yml写入:
--- - name: Test Playbook hosts: k8s_cluster become: yes tasks: - name: Show hostname command: hostname - name: Show system uptime command: uptime检查语法:
ansible-playbook -i inventory.ini test.yml --syntax-check如果正确:
playbook: test.yml执行:
ansible-playbook -i inventory.ini test.yml输出类似:
PLAY [Test Playbook] TASK [Gathering Facts] ok: [k8s-master] ok: [k8s-node01] ok: [k8s-node02] TASK [Show hostname] changed: [k8s-master] changed: [k8s-node01] changed: [k8s-node02] PLAY RECAP k8s-master k8s-node01 k8s-node02说明三个节点都成功执行任务。
四、Playbook 与 Ad-Hoc 的区别
Ad-Hoc
例如:
ansible all -m shell -a "systemctl restart nginx"特点:
临时执行,适合简单任务,不方便保存,不适合复杂流程
Playbook
例如:
tasks: name: Install nginx apt: name: nginx state: present name: Start nginx service: name: nginx state: started特点:
可以保存。可以重复执行,支持多个任务,支持变量,支持条件判断,支持循环,支持自动化部署
实际生产环境中,大部分自动化运维工作都会使用 Playbook。
五、Playbook 常用模块
Ansible 的核心是模块。
常见模块包括:
| 模块 | 作用 |
|---|---|
| command | 执行命令 |
| shell | 执行 Shell 命令 |
| copy | 复制文件 |
| file | 管理文件 |
| apt | Ubuntu 软件管理 |
| yum | CentOS 软件管理 |
| service | 管理服务 |
| systemd | 管理 systemd 服务 |
| user | 管理用户 |
| group | 管理用户组 |
| debug | 输出信息 |
下面逐个介绍。
六、command 模块
创建:
--- - name: Command Test hosts: k8s_cluster tasks: - name: Show hostname command: hostname执行:
ansible-playbook -i inventory.ini command.yml等价于:
hostnamecommand 不支持 Shell 特性
例如:
command: ls /tmp | grep nginx可能无法正常执行。
因为:
|属于 Shell 管道。
这时候需要使用:
shell:七、shell 模块
例如:
--- - name: Shell Test hosts: k8s_cluster become: yes tasks: - name: Check nginx image shell: ctr -n k8s.io images list | grep nginx || true这里:
|是 Shell 管道。
|| true表示即使 grep 没找到 nginx,也不要让任务失败。
command 与 shell 的区别
command
command: hostname适合简单命令。
shell
shell: ps aux | grep nginx适合:管道,重定向,变量,Shell 语法
八、debug 模块
debug 用于输出信息。
例如
--- - name: Debug Test hosts: k8s_cluster tasks: - name: Show hostname command: hostname register: hostname_result - name: Print hostname debug: msg: "{{ hostname_result.stdout }}"执行后会输出:
k8s-master k8s-node01 k8s-node02九、register 注册变量
Ansible 可以把任务执行结果保存到变量。
例如:
- name: Check hostname command: hostname register: result这里:
result保存了命令执行结果。
查看:
- name: Show result debug: var: result输出可能包含:
changed: true stdout: k8s-master stderr: rc: 0常用返回值
stdout
标准输出:
{{ result.stdout }}stdout_lines
按行输出:
{{ result.stdout_lines }}rc
返回值:
{{ result.rc }}例如:
0通常表示成功。
十、copy 模块
copy 用于复制文件。
例如:
--- - name: Copy File hosts: k8s_cluster become: yes tasks: - name: Copy nginx config copy: src: nginx.conf dest: /etc/nginx/nginx.conf结构:
Ansible 控制节点 ↓ copy ↓ 远程服务器十一、file 模块
file 模块可以管理:文件,目录,权限,软链接
例如创建目录:
- name: Create directory file: path: /opt/test state: directory创建文件:
- name: Create file file: path: /opt/test/test.txt state: touch删除文件:
- name: Delete file file: path: /opt/test/test.txt state: absent十二、apt 模块
Ubuntu 使用:
apt:安装 nginx:
--- - name: Install nginx hosts: k8s_cluster become: yes tasks: - name: Update apt cache apt: update_cache: yes - name: Install nginx apt: name: nginx state: present执行:
ansible-playbook -i inventory.ini install-nginx.yml十三、service 模块
用于管理服务。
启动 nginx:
- name: Start nginx service: name: nginx state: started停止:
- name: Stop nginx service: name: nginx state: stopped重启:
- name: Restart nginx service: name: nginx state: restarted开机自启:
- name: Enable nginx service: name: nginx enabled: yes十四、完整 Nginx 自动部署 Playbook
下面是一个完整案例。
创建:
nano nginx.yml内容:
--- - name: Install and Configure Nginx hosts: k8s_cluster become: yes tasks: - name: Update apt cache apt: update_cache: yes - name: Install nginx apt: name: nginx state: present - name: Start nginx service: name: nginx state: started enabled: yes - name: Check nginx status shell: systemctl is-active nginx register: nginx_status - name: Show nginx status debug: msg: "Nginx status: {{ nginx_status.stdout }}"执行:
ansible-playbook -i inventory.ini nginx.yml整个流程:
更新软件源 ↓ 安装 nginx ↓ 启动 nginx ↓ 设置开机自启 ↓ 检查 nginx 状态 ↓ 输出结果十五、when 条件判断
when 可以实现条件执行。
例如:
- name: Only run on master command: hostname when: inventory_hostname == "k8s-master"那么只有:
k8s-master会执行。
node01 和 node02 会跳过。
Kubernetes 场景
例如:
- name: Pull image on master command: ctr -n k8s.io images pull nginx:latest when: inventory_hostname == "k8s-master"只有 Master 节点执行。
十六、循环 loop
例如批量安装软件:
- name: Install packages apt: name: "{{ item }}" state: present loop: - nginx - curl - vim相当于:
apt install nginx apt install curl apt install vim但是通过 Ansible 自动批量完成。
十七、Playbook 幂等性
这是 Ansible 最重要的特点之一。
例如:
apt: name: nginx state: present第一次执行:
changed安装 nginx。
第二次执行:
ok因为 nginx 已经存在。
这叫:
幂等性意思是:
同一个 Playbook 执行多次,最终结果保持一致。
例如:
第一次执行 → 安装 nginx 第二次执行 → 不重复安装 第三次执行 → 不重复安装这非常适合自动化运维。
十八、handlers:配置改变后重启服务
例如修改 nginx 配置:
- name: Copy nginx config copy: src: nginx.conf dest: /etc/nginx/nginx.conf notify: - Restart nginx然后:
handlers: name: Restart nginx service: name: nginx state: restarted完整结构:
--- - name: Configure nginx hosts: k8s_cluster become: yes tasks: - name: Install nginx apt: name: nginx state: present - name: Copy nginx config copy: src: nginx.conf dest: /etc/nginx/nginx.conf notify: - Restart nginx handlers: - name: Restart nginx service: name: nginx state: restarted只有配置文件发生变化时:
Restart nginx才会执行。
十九、实际 Kubernetes 自动化案例
前面我们已经使用 Ansible 管理 Kubernetes 集群。
例如检查所有节点镜像:
ansible -i inventory.ini k8s_cluster -m shell -a "sudo ctr -n k8s.io images list"也可以写成 Playbook。
创建:
nano check-images.yml内容:
--- - name: Check Kubernetes Images hosts: k8s_cluster become: yes tasks: - name: Check containerd images shell: ctr -n k8s.io images list register: image_list - name: Show images debug: var: image_list.stdout_lines执行:
ansible-playbook -i inventory.ini check-images.yml这样以后只需要执行:
ansible-playbook check-images.yml就可以自动检查整个 Kubernetes 集群。
二十、常用命令
检查 Playbook 语法:
ansible-playbook -i inventory.ini nginx.yml --syntax-check查看执行计划:
ansible-playbook -i inventory.ini nginx.yml --check执行 Playbook:
ansible-playbook -i inventory.ini nginx.yml详细输出:
ansible-playbook -i inventory.ini nginx.yml -v更详细:
ansible-playbook -i inventory.ini nginx.yml -vvv二十一、推荐目录结构
说明:
inventory.ini服务器清单。
playbooks/存放自动化任务。
files/存放需要分发的文件。
templates/存放 Jinja2 模板。
roles/存放大型模块化自动化项目。
二十二、总结
通过本篇文章,我们学习了 Ansible Playbook 的基础知识。对于 Linux 运维工程师来说,Playbook 是必须掌握的技能。因为真实生产环境通常几十台服务器,统一配置,统一部署,统一更新,统一检查Ansible Playbook 正是实现这种批量自动化运维的重要工具。