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