PlayBooks 介绍
Playbooks 简介
简单来说,playbooks是一种简单的配置管理系统与多机器部署系统的基础。与现有的其他系统有不同之处,且非常适合复杂应用的部署。
Playbooks 可用于声明配置,更强大的地方在于,playbooks可以编排有序的去执行过程,甚至做到多组机器间来回有序的执行特别指定的步骤,并且可以同步或异步的发起任务。
Playbook 语言的示例
Playbooks 的格式是 yaml,语法做到最小化,意在避免playbooks成为一种编程语言或脚本,但他也并不是一个配置模型或过程的模型。
playbook由一个或多个‘play’组成,他的内容是一个以‘play’为元素的列表,通过playbook可以编排步骤进行多机器的部署。
---
- 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 基础
主机与用户
可以为playbook中每一个play,单独的选择操作的目标机器是那些、以哪个用户身份去执行。
如果你需要在使用 sudo 时指定密码,可在运行 ansible-playbook 命令时加上选项 --ask-sudo-pass (-K). 如果使用 sudo 时,playbook 疑似被挂起,可能是在 sudo prompt 处被卡住,这时可执行 Control-C 杀死卡住的任务,再重新运行一次.
---
- host: webserver,dbserver 【一个或多个组或主机,用‘逗号’分开】
remote_user: root 【执行操作的账户】
tassk:
- name: test connection
ping:
remote_user: slave1 【在不同的task中可以定义不同的执行用户】
--- // 支持sudo执行命令
- host: webserver,dbserver
remote_user: slave1
sudo: yes
--- // 可以在一个task中使用sudo,而不是整个play中使用sudo
- host: webserver,dbserver
remote_user: slave1
tasks:
- service: name=nginx state=started
sudo: yes
--- // 也可以登录后,sudo到不同的用户身份,而不是用root
- host: webserver,dbserver
remote_user: slave1
sudo: yes
sudo_user: postgres
Task 列表【每一个 play 包含了一个 task 列表(任务列表)顺序执行】
每一个 play 包含了一个 task 列表(任务列表)。一个 task 在其所对应的所有主机上(通过 host pattern 匹配的所有主机)执行完毕之后,下一个 task 才会执行。有一点需要明白的是(很重要),在一个 play 之中,所有 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task。(注:此处翻译未必准确,暂时保留原文)
在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除。 如果发生执行失败的情况,请修正 playbook 中的错误,然后重新执行即可。
每个 task 的目标在于执行一个 moudle, 通常是带有特定的参数来执行。在参数中可以使用变量(variables)。
modules 具有”幂等”性,意思是如果你再一次地执行 moudle(译者注:比如遇到远端系统被意外改动,需要恢复原状),moudle 只会执行必要的改动,只会改变需要改变的地方。所以重复多次执行 playbook 也很安全。
对于 command module 和 shell module,重复执行 playbook,实际上是重复运行同样的命令.如果执行的命令类似于 ‘chmod’ 或者 ‘setsebool’ 这种命令,这没有任何问题.也可以使用一个叫做 ‘creates’ 的 flag 使得这两个 module 变得具有”幂等”特性 (不是必要的).
每一个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个 task 的。 如果没有定义 name,‘action’ 的值将会用作输出信息中标记特定的 task。
tasks:
- name: make sure apache is running
service: name=httpd state=running
- 两个特殊的 modudle 【非 key=value 模式】
tasks:
- name: disable selinux
command: /sbin/setenforce
tasks:
- name: run this command and ignore the result
shell: /usr/sbin/somecommand || /bin/true
Handlers 【在发生改变时执行的操作】
Handlers 也是一些 task 的列表,通过名字来引用,它们和一般的 task 并没有什么区别。Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行。不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
Ansible-pull【拉取配置而非推送配置】
Ansible-pull 是一个小脚本,他从git上checkout一个关于配置指令的repo然后以这个配置指令来运行ansible-playbook。
[[email protected] ~]# ansible-pull --help
Usage: ansible-pull -U <repository> [options] [<playbook.yml>]
pulls playbooks from a VCS repo and executes them for the local host
Options:
--accept-host-key adds the hostkey for the repo url if not already added
--ask-vault-pass ask for vault password
--check don't make any changes; instead, try to predict some
of the changes that may occur
-C CHECKOUT, --checkout=CHECKOUT
branch/tag/commit to checkout. Defaults to behavior of
repository module.
--clean modified files in the working repository will be
discarded
-d DEST, --directory=DEST
directory to checkout repository to
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with @
-f, --force run the playbook even if the repository could not be
updated
--full Do a full clone, instead of a shallow one.
-h, --help show this help message and exit
-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
specify inventory host path or comma separated host
list. --inventory-file is deprecated
-l SUBSET, --limit=SUBSET
further limit selected hosts to an additional pattern
--list-hosts outputs a list of matching hosts; does not execute
anything else
-m MODULE_NAME, --module-name=MODULE_NAME
Repository module name, which ansible will use to
check out the repo. Choices are ('git', 'subversion',
'hg', 'bzr'). Default is git.
-M MODULE_PATH, --module-path=MODULE_PATH
prepend colon-separated path(s) to module library
(default=[u'/root/.ansible/plugins/modules',
u'/usr/share/ansible/plugins/modules'])
-o, --only-if-changed
only run the playbook if the repository has been
updated
--purge purge checkout after playbook run
--skip-tags=SKIP_TAGS
only run plays and tasks whose tags do not match these
values
-s SLEEP, --sleep=SLEEP
sleep for random interval (between and n number of
seconds) before starting. This is a useful way to
disperse git requests
-t TAGS, --tags=TAGS only run plays and tasks tagged with these values
--track-subs submodules will track the latest changes. This is
equivalent to specifying the --remote flag to git
submodule update
-U URL, --url=URL URL of the playbook repository
--vault-id=VAULT_IDS the vault identity to use
--vault-password-file=VAULT_PASSWORD_FILES
vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--verify-commit verify GPG signature of checked out commit, if it
fails abort running the playbook. This needs the
corresponding VCS module to support such an operation
--version show program's version number and exit
Connection Options:
control as whom and how to connect to hosts
-k, --ask-pass ask for connection password
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
use this file to authenticate the connection
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=None)
-c CONNECTION, --connection=CONNECTION
connection type to use (default=smart)
-T TIMEOUT, --timeout=TIMEOUT
override the connection timeout in seconds
(default=)
--ssh-common-args=SSH_COMMON_ARGS
specify common arguments to pass to sftp/scp/ssh (e.g.
ProxyCommand)
--sftp-extra-args=SFTP_EXTRA_ARGS
specify extra arguments to pass to sftp only (e.g. -f,
-l)
--scp-extra-args=SCP_EXTRA_ARGS
specify extra arguments to pass to scp only (e.g. -l)
--ssh-extra-args=SSH_EXTRA_ARGS
specify extra arguments to pass to ssh only (e.g. -R)
Privilege Escalation Options:
control how and which user you become as on target hosts
--ask-sudo-pass ask for sudo password (deprecated, use become)
--ask-su-pass ask for su password (deprecated, use become)
-K, --ask-become-pass
ask for privilege escalation password
- clever playbook 【可通过crontab来配置ansible-pull】
Git 地址:https://github.com/ansible/ansible-examples/blob/master/language_features/ansible_pull.yml
提示与技巧
在playbook执行输出信息的底部,可以找到关于托管节点的信息,也可看到一般的失败信息,和严重的“unreachable”信息,这两个是分开计数的。
[root@master ~]# ansible-playbook playbook.yml --list-hosts
playbook: playbook.yml
play #1 (slave1): slave1 TAGS: []
pattern: [u'slave1']
hosts ():
[[email protected] ~]# ansible-playbook playbook.yml
PLAY [slave1] *******************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************
fatal: [192.168.27.111]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.27.111 port 22: No route to host\r\n", "unreachable": true}
to retry, use: --limit @/root/playbook.retry
PLAY RECAP **********************************************************************************************************************************************************************************
192.168.27.111 : ok=0 changed=0 unreachable=1 failed=0