编程 · 24 2 月, 2025 0

Ansible Playbook速成实战:从一个简单例子开始

不废话,让我们直接开始!

什么需求?

  • 操作对象是3台服务器SRV01~03,都有Python环境
  • 需要在每台服务器上跑一个收集服务信息的脚本
  • 在Ansible控制台打印脚本输出
  • 登陆服务器使用一般用户“my_work”,但脚本需要sudo执行

本例中涉及到的知识点

  • Ansible Playbook标准目录结构
  • 主机清单的基本写法和使用
  • 远程执行命令并获取输出结果的Playbook写法(包括使用root权限)

开始整活

1. 创建工作目录

带“!”的目录,目录名请与下述保持一致。Ansible会自动从中读取所需内容。

pj/ (主目录)
 |- site.yml
 |- inventory (!)/
    |- servers.ini
 |- roles (!)
    |- get_service_status
       |- tasks (!)/
          |- main.yml

2. 编辑inventory

Inventory(主机清单)就是执行Ansible脚本的对象。将以下内容写入inventory/servers.ini。假设三个服务器的IP地址为192.168.0.1~192.168.0.3

[my_servers]
SRV01  ansible_host=192.168.0.1  ansible_user=my_work  ansible_become=yes  ansible_become_password="你的sudo密码"
SRV02  ansible_host=192.168.0.2  ansible_user=my_work  ansible_become=yes  ansible_become_password="你的sudo密码"
SRV03  ansible_host=192.168.0.3  ansible_user=my_work  ansible_become=yes  ansible_become_password="你的sudo密码"

能够sudo执行的关键在于ansible_becomeansible_become_password这两个参数。没sudo需求的时候可以不写。

※ 这时候你的老板突然产生了一些大胆的想法

3. 编辑site.yml

site.yml一般作为脚本执行的入口。

---
- name: 获取服务器信息
  hosts: my_servers
  gather_facts: no  # 没用就no
  tasks:

  roles:
    - role: get_service_status

这里稍微说明一下:

  • hostspj/inventory/servers.ini中定义的主机。可以是一个组(这里的“my_servers”),也可以是某个主机(如servers.ini里的“SRV01”)。
  • role:名称应与pj/roles中的文件夹名一致。
  • 关于格式:如果tasks中没有内容,tasksroles之间的换行是必须的。不然YAML的语法会将它们视为从属关系。

4. 编辑Role

将以下内容写入pj/roles/get_service_status/tasks/main.yml。这里假设需要执行的脚本储存在服务器的/home/my_work/collect.sh文件中。

- name: 执行脚本
  become: yes  # 因为要sudo执行
  become_method: sudo
  command: "bash /home/my_work/collect.sh"
  # 如果远程主机没有Python环境则可以用raw代替command
  register: service_status

- name: 打印结果
  debug:
    msg: "{{ service_status.stdout }}"
    # 如果要打印整个变量,用“var:”。可查看变量结构
    # var: service_status.stdout

※ 这时候你的老板又产生了一些大胆的想法

5. 执行脚本🎉

至此,实现需求所需要的条件都已具备。现在切回主目录pj/中,执行以下命令执行Ansible Playbook。

ansible-playbook -i ./inventory/servers.ini ./site.yml
# -i用于指定主机清单定义文件。不写的话会使用默认文件

※ 这时候你的老板依然有一些大胆的想法

  • 我想先验证远程主机的hostname,要是错了就不要继续执行了。 👉assert的使用