Ansible Playbooks模式
目录
什么是Playbooks
前述操作对远程执行的命令都是相同的,那么是否可以同时对不同的主机执行不同的指令呢?当然可以,这就是本节要介绍的Ansible的剧本Playbooks。
Playbooks是Ansible的配置、部署、编排的语言。它们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合。如果Ansible模块是工作室中的工具,那么Playbooks就是设置的方案计划。
Playbook 和Ad-hoc
Ad-hoc 临时命令不适合复杂配置管理或编配场景
Ad-hoc 临时命令一次只能调用一个模块和一组参数。当需要多个操作时,必须使用多个临时命令来执行
Playbook 是描述要在受管主机上实施的必要配置或程序性步骤的文件。Playbook 为配置管理和部署提供了强大而灵活的解决方案。
Playbook 可以将冗长而复杂的管理任务转变为可轻松重复的历程,并且可预测成果。
Playbook格式
学习playbook命令前先查看ansible-playbook的帮助命令。
[root@localhost ~]# ansible-playbook -h
usage: ansible-playbook [-h] [--version] [-v] [-k] [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT] [--ssh-common-args SSH_COMMON_ARGS] [--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS] [--ssh-extra-args SSH_EXTRA_ARGS] [--force-handlers] [--flush-cache] [-b] [--become-method BECOME_METHOD] [--become-user BECOME_USER] [-K] [-t TAGS] [--skip-tags SKIP_TAGS] [-C] [--syntax-check] [-D] [-i INVENTORY] [--list-hosts] [-l SUBSET] [-e EXTRA_VARS] [--vault-id VAULT_IDS] [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES] [-f FORKS] [-M MODULE_PATH] [--list-tasks] [--list-tags] [--step] [--start-at-task START_AT_TASK] playbook [playbook ...] Runs Ansible playbooks, executing the defined tasks on the targeted hosts.
发现ansible-playbook命令需要一个plauybook.yml的文件名作为参数。那么问题又来了,什么是yml文件呢?
playbook执行 YAML 格式的文本文件,扩展名通常为 yml
Playbook示例
ansible-playbook test.yml
playbook 以三个破折号(---)作为文档开始标记。以三个点(…)作为文档结尾标记,尽管在实践中这经常被省略
在这些标记之间,playbook 由一组 plays 构成。YAML 列表中的item 以一个破折号开始,后跟空格
--- - name: configure important things hosts: master remote_user: root tasks: - name: read sys time shell: echo "`date +'%Y-%m-%d %T'`">time.txt - name: list file shell: ls -ltr>list.txt - name: configure important things 2 hosts: slave remote_user: root tasks: - name: list file shell: ls -ltr>list.txt
play 本身是 key-value 对的集合。同一 play 中的 keys 应该有相同的缩进。
示例 play 的第一行以破折号和空格(指示 play 是列表的第一项)开始,然后是第一个 key:name
play 中的第二个 key 是 hosts 属性,指定运行 play 任务的主机
play 中的最后一个 key 是 tasks 属性,为这个 play 运行的任务列表
tasks 属性列出要在主机上运行的任务。列表中的每个任务本身都是键值对的集合
yml语法注意事项
在yml文件中,使用带空格字符的缩进来表示数据的结构。YAML对缩进和使用了多少空格没有严格的要求,但是有两个基本规则:
- 层次结构中相同级别的数据元素(例如相同列表中的项)必须具有相同的缩进
- 子项必须比其父项缩进得更多
可以添加空行增加可读性
注意:只能使用空格缩进,不能使用 tab,如果使用 vi 编辑器,可以通过编辑 $HOME/.vimrc 将 Tab 转化为2个空格
Yaml语法
对初学者,这里有一个 playbook,其中仅包含一个 play:
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: pkg=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running service: name=httpd state=started handlers: - name: restart apache service: name=httpd state=restarted
Playbook 示例
编写yml文件
playbook 以三个破折号(---)作为文档开始标记。以三个点(…)作为文档结尾标记,尽管在实践中这经常被省略
在这些标记之间,playbook 由一组 plays 构成。YAML 列表中的item 以一个破折号开始,后跟空格
--- - name: configure important things hosts: master remote_user: root tasks: - name: read sys time shell: echo "`date +'%Y-%m-%d %T'`">time.txt - name: list file shell: ls -ltr>list.txt - name: configure important things 2 hosts: slave remote_user: root tasks: - name: list file shell: ls -ltr>list.txt
play 本身是 key-value 对的集合。同一 play 中的 keys 应该有相同的缩进。上面的示例显示了一个带有三个 keys 的 YAML 代码片段 前两个 keys 的值很简单。第三个 key 的列表中有两个 items 作为值
语法检查
ansible-playbook --syntax-check test.yml
执行
ansible-playbook test.yml
PLAY [master] ********************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************* ok: [localhost] ok: [10.0.0.30] TASK [read sys time] *************************************************************************************************************************************** changed: [localhost] changed: [10.0.0.30] PLAY [slave] *********************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************* ok: [10.0.0.32] TASK [list file] ******************************************************************************************************************************************* changed: [10.0.0.32] PLAY RECAP ************************************************************************************************************************************************* 10.0.0.30 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.0.0.32 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Playbook 示例详解
主机与用户
你可以为 playbook 中的每一个 play,个别地选择操作的目标机器是哪些,以哪个用户身份去完成要执行的步骤(called tasks).
示例 play 的第一行以破折号和空格(指示 play 是列表的第一项)开始,然后是第一个 key:name
name:描述 play 的目的。name key 是可选的,但推荐使用
- name: configure important things
hosts 行的内容是一个或多个组或主机的 patterns,以逗号为分隔符.
remote_user 就是账户名:
hosts: master remote_user: root
tasks 列表
play 中的最后一个 key 是 tasks 属性,为这个 play 运行的任务列表
tasks 属性列出要在主机上运行的任务。列表中的每个任务本身都是键值对的集合
tasks: - name: read sys time shell: echo "`date +'%Y-%m-%d %T'`">time.txt - name: list file shell: ls -ltr>list.txt
每一个 play 包含了一个 task 列表(任务列表).一个 task 在其所对应的所有主机上(通过 host pattern 匹配的所有主机)执行完毕之后,下一个 task 才会执行.有一点需要明白的是,在一个 play 之中,所有 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task.
在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除. 如果发生执行失败的情况,请修正 playbook 中的错误,然后重新执行即可.
task的定义
每个 task 的目标在于执行一个 moudle, 通常是带有特定的参数来执行.在参数中可以使用变量(variables).
下面是一种基本的 task 的定义,这也是大多数 module 使用的参数格式:
tasks:
- name: make sure apache is running service: name: httpd enabled: true
task自定义变量
再者,在每一个 task 中,可以定义自己的远程用户:
--- - hosts: webservers remote_user: root tasks: - name: test connection ping: remote_user: yourname
也支持从 sudo 执行命令:
--- - hosts: webservers remote_user: yourname sudo: yes
特别的command 和 shell
比较特别的两个 modudle 是 command 和 shell ,它们不使用 key=value 格式的参数,而是这样:
tasks:
- name: disable selinux command: /sbin/setenforce 0
使用 command module 和 shell module 时,我们需要关心返回码信息,
执行Playbook注意事项
输出结果
在控制节点上使用 ansible-playbook 命令执行 playbook
在执行 playbook 时,屏幕显示所执行的 play 和 tasks。输出中也会显示每一项 task 的结果
PLAY RECAP ************************************************************************* 192.168.100.10 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
一般来说,Ansible playbook 中的任务是幂等(idempotent)的,可以安全地多次运行 playbook。如果目标托管主机已经处于正确的状态,则不应进行任何更改。例如,假设前一个例子中的剧本再次运行:
幂等性
一般来说,Ansible playbook 中的任务是幂等(idempotent)的,可以安全地多次运行 playbook。如果目标托管主机已经处于正确的状态,则不应进行任何更改。例如,假设前一个例子中的剧本再次运行:
语法验证
在执行 playbook 前,最好进行验证,确保其内容的语法正确无误。ansible-playbook 命令提供了 --syntax-check 选项,可用于验证playbook 文件的语法。
ansible playbook --syntax-check webserver.yml
增加输出内容
ansible-playbook 命令的默认输出并没有提供详细的信息,可使用-v 选项增加输出内容
-v 是看运行细节。要更细节的信息,把-v换成 -vvv
-v
-vv
-vvv
-vvvv
执行空运行(dry run)
另一个有用选项是 -C 选项。这会使 Ansible 报告在执行该playbook 时将会发生什么更改,但不会对受管主机进行任何实际的更改
ansible-playbook -C webserver.yml
参考文档:http://www.ansible.com.cn/docs/playbooks_intro.html#about-playbooks
参考书籍:《Python自动化运维入门》