accelerate
對於使用ansible 1.5 及以後版本的用戶,加速模式只在如下狀況下有用處:html
(A) 管理紅帽企業版 Linux 6 或者更早的那些依然使用 paramiko 的版本 python
(B) 像在文檔中描述的那樣:沒法在 TTYs 中使用 sudo.web
#只需在你的 play 中添加 accelerate: true 便可使用加速模式: --- - hosts: all accelerate: true tasks: - name: some task command: echo {{ item }} with_items: - foo - bar - baz #若是你但願改變 Ansible 用於加速模式的端口,你只需添加 accelerated_port 選項: --- - hosts: all accelerate: true # default port is 5099 accelerate_port: 10000 #accelerate_port 選項也一樣能經過指定環境變量 ACCELERATE_PORT 或者在你的 ansible.cfg 中配置: [accelerate] accelerate_port = 5099
async
poll
async_status
默認狀況下playbook中的任務執行時會一直保持鏈接,直到該任務在每一個節點都執行完畢.有時這是沒必要要的,好比有些操做運行時間比SSH超時時間還要長.docker
解決該問題最簡單的方式是一塊兒執行它們,而後輪詢直到任務執行完畢.shell
你也能夠對執行時間很是長(有可能遭遇超時)的操做使用異步模式.json
爲了異步啓動一個任務,能夠指定其最大超時時間以及輪詢其狀態的頻率.vim
若是你沒有爲 poll 指定值,那麼默認的輪詢頻率是10秒鐘:安全
--- - hosts: all remote_user: root tasks: - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec command: /bin/sleep 15 async: 45 poll: 5
async 並無默認值,若是你沒有指定 async 關鍵字,那麼任務會以同步的方式運行,這是Ansible的默認行爲.服務器
另外,若是你不須要等待任務執行完畢,你能夠指定 poll 值爲0而啓用 「啓動並忽略」app
--- - hosts: all remote_user: root tasks: - name: simulate long running op, allow to run for 45 sec, fire and forget command: /bin/sleep 15 async: 45 poll: 0
對於要求排它鎖的操做,若是你須要在其以後對同一資源執行其它任務,那麼你不該該對該操做使用」啓動並忽略」.好比yum事務.
--forks
參數值過大會更快的觸發異步任務.也會加快輪詢的效率.
當你想對 「啓動並忽略」 作個變種,改成」啓動並忽略,稍後再檢查」,你可使用如下方式執行任務:
--- # Requires ansible 1.8+ - name: 'YUM - fire and forget task' yum: name=docker-io state=installed async: 1000 poll: 0 register: yum_sleeper - name: 'YUM - check on fire and forget task' async_status: jid={{ yum_sleeper.ansible_job_id }} register: job_result until: job_result.finished retries: 30
若是 async:
值過小,可能會致使 「稍後檢查」 任務執行失敗,由於 async_status::
的臨時狀態文件還未被寫入信息,而」稍後檢查」任務就試圖讀取此文件.
--check
--diff
--limit
當以 --check
參數來運行 ansible-playbook 時,將不會對遠程的系統做出任何更改.
相對的,任何帶有檢測功能的模塊(這幾乎包含了全部的主要核心模塊,但這不要求全部的模塊都需支持.) 只要支持 ‘檢測模式’ 將會報告它們會作出什麼改變而不是直接進行改變.其餘不支持檢測模式的模塊將既不響應也不提出相應的報告.
檢測模式只是一種模擬.若是你的playbook是以先前命令的執行結果做爲條件的話,那它可能對你就沒有什麼大用處了. 可是對於基於一次一節點的基礎配置管理的使用情形來講是頗有用.
Example: ansible-playbook foo.yml --check
有時候你甚至會想在檢測模式中執行一個任務.爲了達到這樣的效果, 你須要在相應的任務上使用 always_run 子句.跟 when 子句同樣,它的值是一個 Jinja2 表達式. 在一個簡單的例子中,布爾值也會表達爲一個適當的 YAML 值.
Example: tasks: - name: this task is run even in check mode command: /something/to/run --even-in-check-mode always_run: yes
友情提示,帶有 when 子句的任務會返回false,該任務將會被跳過,即便它還被添加了會返回true的 always_run 子句.
對 ansible-playbook 來講 --diff
選項與 --check
(詳情參下)配合使用效果奇佳,不過它也能夠單獨使用.當提供了相應的標識後,當遠程系統上任何模板文件的變化時,ansible-playbook CLI 將會報告文件上任何文本的變化 (或者,若是使用了 --check
參數,將報告會發生的變化.).由於 diff 特性會產生大量的輸出結果,因此它在一次檢測一個主機時使用爲佳,如:
ansible-playbook foo.yml --check --diff --limit foo.example.com
serial
因爲設計初衷是做爲多用戶,Anisible很擅長在某一個主機上表明另外一個作事,或者參考遠程主機作一些本地工做.
這個特性對於架設連續實現某些設施或者無縫滾動升級,這裏你可能會提到負載均衡或者監控系統.
更多的特性容許調試事情完成的順序,和設置一批窗口,來肯定多少機器在一次中滾動更新.
默認來講,Anisble 能夠試圖參考某一個play來並行操做全部主機.對於滾動更新案例,你可使用’‘serial’’ 關鍵詞來定義Ansible在一個特定時間同時控制多少主機:
- name: test play hosts: webservers serial: 3
在上面的例子,若是咱們有100臺主機,3 臺主機定義在組’webservers’ 能夠在下面3個主機開始以前徹底完成
這個’‘serial’’ 關鍵詞在Ansible 1.8 之後能夠被定義爲百分數,用來定義每一次操做一個play中百分之多少主機:
- name: test play hosts: websevers serial: "30%"
若是主機數不能被passes數量整除,最後的pass將會包含提醒信息,無論多小的百分比,每一個pass的主機數必定會大於等於1.
默認來講,Ansible 會持續執行,只要在一個組中還有主機沒有宕機.
在有些狀況下,例如以前提到的滾動更新,也許理想的狀況是當一個失敗數上限達到時,主動宕掉這個play.
爲了達到這個目的,在 1.3版本中,你能夠設置最大失敗半分比:
- hosts: webservers max_fail_percentage: 30 serial: 10
在上面的例子中,若是在10個服務器中若是多餘3個,其它的play就會主動宕掉.這個百分比必須被超過,不只僅是相等.
例如若是serial值唄設置爲4,而且你但願任務主動在2個系統失敗時候放棄.那麼這個百分比應該設置爲49而不是50.
delegate_to
local_action
若是你想參考其它主機來在一個主機上執行一個任務,咱們就可使用’delegate_to’關鍵詞在你要執行的任務上.
這個對於把節點放在一個負載均衡池裏面活着從裏面移除很是理想. 這個選項也對處理窗口中斷很是有用. 使用’serial’關鍵詞來控制必定數量的主機也是一個好想法:
--- - hosts: webservers serial: 5 tasks: - name: take out of load balancer pool command: /usr/bin/take_out_of_pool {{ inventory_hostname }} delegate_to: 127.0.0.1 - name: actual steps would go here yum: name=acme-web-stack state=latest - name: add back to load balancer pool command: /usr/bin/add_back_to_pool {{ inventory_hostname }} delegate_to: 127.0.0.1
--- # ... tasks: name: take out of load balancer pool local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }} # ... name: add back to load balancer pool local_action: command /usr/bin/add_back_to_pool {{ inventory_hostname }}
A common pattern is to use a local action to call ‘rsync’ to recursively copy files to the managed servers. Here is an example:
--- # ... tasks: - name: recursively copy files from management server to target local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/
connection
在本地使用playbook有時候比ssh遠程使用更加有用.能夠經過把playbook放在crontab中,來確保一個系統的配置,能夠頗有用.
在OS installer 中運行一個playbook也頗有用.例如Anaconda kickstart.
要想在本地運行一個play,能夠直接設置」host:」 與 「hosts:127.0.0.1」, 而後使用下面的命令運行:
ansible-playbook playbook.yml --connection=local
或者,一個本地鏈接也能夠做爲一個單獨的playbook play應用在playbook中, 即使playbook中其餘的plays使用默認遠程 鏈接以下:
- hosts: 127.0.0.1 connection: local
run_once
有時候你有這樣的需求,在一個主機上面只執行一次一個任務.這樣的配置能夠配置」run_once」來實現:
--- # ... tasks: # ... - command: /opt/application/upgrade_db.py run_once: true # ...
這樣能夠添加在」delegat_to」選項對中來定義要執行的主機:
- command: /opt/application/upgrade_db.py run_once: true delegate_to: web01.example.org
當」run_once」 沒有和」delegate_to」一塊兒使用,這個任務將會被清單指定的第一個主機.
在一組被play制定主機.例如 webservers[0], 若是play指定爲 「hosts: webservers」.
這個方法也很相似,雖然比使用條件更加簡單粗暴,以下事例:
- command: /opt/application/upgrade_db.py when: inventory_hostname == webservers[0]
environment
你徹底有可能遇到一些更新包須要經過proxy才能正常獲取,或者甚至一部分包須要經過proxy升級而另一部分包則不須要經過proxy.
或者可能你的某個腳本須要調用某個環境變量才能正常運行.
Ansible 使用 ‘environment’ 關鍵字對於環境部署的配置很是簡單容易,下面是一個使用案例:
- hosts: all remote_user: root tasks: - apt: name=cobbler state=installed environment: http_proxy: http://proxy.example.com:8080
environment 也能夠被存儲在變量中,像以下方式訪問:
- hosts: all remote_user: root # here we make a variable named "proxy_env" that is a dictionary vars: proxy_env: http_proxy: http://proxy.example.com:8080 tasks: - apt: name=cobbler state=installed environment: proxy_env
雖然上面只展現了 proxy 設置,但其實能夠同時其實支持多個設置. 大部分合合乎邏輯的地方來定義一個環境變量均可以成爲 group_vars 文件,示例以下:
--- # file: group_vars/boston ntp_server: ntp.bos.example.com backup: bak.bos.example.com proxy_env: http_proxy: http://proxy.bos.example.com:8080 https_proxy: http://proxy.bos.example.com:8080
ignore_errors
failed_when
fail
change_when
Ansible 一般默認會確保檢測模塊和命令的返回碼.
有時一條命令會返回 0 但那不是報錯.有時命令不會老是報告它 ‘改變’ 了遠程系統.
本節描述了 如何將 Ansible 處理輸出結果和錯誤處理的默認行爲改變成你想要的.
一、忽略錯誤命令
一般狀況下, 當出現失敗時 Ansible 會中止在宿主機上執行.有時候,你會想要繼續執行下去.爲此 你須要像這樣編寫任務:
- name: this will not be counted as a failure command: /bin/false ignore_errors: yes
注意上面的系統僅僅處理那個特定的任務,因此當你在使用一個未定義的變量時, Ansible 仍然會報 錯,須要使用者進行處理.
二、控制對失敗的定義
假設一條命令的錯誤碼毫無心義,只有它的輸出結果能告訴是你什麼出了問題,好比說字符串 「FAILED」 出 如今輸出結果中.
在 Ansible 1.4及以後的版本中提供了以下的方式來指定這樣的特殊行爲:
- name: this command prints FAILED when it fails command: /usr/bin/example-command -x -y -z register: command_result failed_when: "'FAILED' in command_result.stderr"
三、覆寫返回結果
當一個 shell或命令或其餘模塊運行時,它們每每都會在它們認爲其影響機器狀態時報告 「changed」 狀態,
tasks: - shell: /usr/bin/billybass --mode="take me to the river" register: bass_result changed_when: "bass_result.rc != 2" # this will never report 'changed' status - shell: wall 'beep' changed_when: False
tags
若是你有一個大型的 playbook,那可以只運行其中特定部分的配置而無需運行整個 playbook 將會頗有用.
plays 和 tasks 都因這個理由而支持 「tags」
tasks: - yum: name={{ item }} state=installed with_items: - httpd - memcached tags: - packages - template: src=templates/src.j2 dest=/etc/foo.conf tags: - configuration
若是你只想運行一個很是大的 playbook 中的 「configuration」 和 「packages」,你能夠這樣作:
ansible-playbook example.yml --tags "configuration,packages"
另外一方面,若是你只想執行 playbook 中某個特定任務 以外 的全部任務,你能夠這樣作:
ansible-playbook example.yml --skip-tags "notification"
你一樣也能夠對 roles 應用 tags:
roles: - { role: webserver, port: 5000, tags: [ 'web', 'foo' ] }
你一樣也能夠對基本的 include 語句使用 tag:
- include: foo.yml tags=web,foo
--start-at
--step
若是你想從指定的任務開始執行playbook,可使用``–start-at``選項:
ansible-playbook playbook.yml --start-at="install packages"
以上命令就會在名爲」install packages」的任務開始執行你的playbook.
咱們也能夠經過``–step``選項來交互式的執行playbook:
ansible-playbook playbook.yml --step
這樣ansible在每一個任務前會自動中止,並詢問是否應該執行該任務.
好比你有個名爲``configure ssh``的任務,playbook執行到這裏會中止並詢問:
Perform task: configure ssh (y/n/c):
「y」回答會執行該任務,」n」回答會跳過該任務,而」c」回答則會繼續執行剩餘的全部任務而再也不詢問你.
ansible-vault
--ask-vault-pass
--vault-password-file
Ansible 1.5的新版本中, 「Vault」 做爲 ansible 的一項新功能可將例如passwords,keys等敏感數據文件進行加密,
而非存放在明文的 playbooks 或 roles 中. 這些 vault 文件能夠分散存放,也能夠集中存放.
經過`ansible-vault` 來編輯文件,常常用到的命令如 –ask-vault-pass , –vault-password-file .
你能夠在 ansible.cfg 中定義密碼文件所在位置,這個選項就不須要在命令行中指定標誌了.
vault 能夠加密任何 Ansible 使用的結構化數據文件. 甚至能夠包括:
「group_vars/」 或 「host_vars/」 inventory 變量,
「include_vars」 或 「vars_files」 加載的變量,
經過 ansible-playbook 命令行使用 「-e @file.yml」 或 「-e @file.json」 命令傳輸的變量文件,
role變量,
全部默認的變量均可以被 vault 加密.
由於 Ansible tasks, handlers等都是數據文件, 全部的這些都可以被 vault 加密. 若是你不喜歡你使用的變量被泄漏,你能夠將整個 task 文件部分加密.
不過,這個工做量比較大並且可能給你的同事帶來不便哦 !
執行以下命令,建立加密文件:
ansible-vault create foo.yml
首先你將被提示輸出密碼, 通過Vault加密過的文件如需查看需同時輸入密碼後才能進行.
提供密碼後, 工具將加載你定義的 $EDITOR 的編輯工具默認是 vim, 一旦你關閉了編輯會話框,生成後的文件將會是加密文件.
默認加密方式是 AES (基於共享密鑰)
編輯加密文件,使用 ansible-vault edit . 該命令會先加密文件爲臨時文件並容許你編輯這個文件,當完成編輯後會保存回你所命名的文件並刪除臨時文件:
ansible-vault edit foo.yml
若是你但願加密一個已經存在的文件,使用 ansible-vault encrypt . 該命令也可同時批量操做多個文件:
ansible-vault encrypt foo.yml bar.yml baz.yml=
若是不但願繼續加密一個已經加密過的文件,經過 ansible-vault decrypt 你能夠永久解密. 命令將解密並保存到硬盤上,這樣你不用再使用 ansible-vault edit 來編輯文件了:
ansible-vault decrypt foo.yml bar.yml baz.yml
Available since Ansible 1.8
若是你不但願經過編輯的方式來查看文件, ansible-vault view 能夠知足你的須要:
ansible-vault view foo.yml bar.yml baz.yml
執行 vault 加密後的playbook文件,最少須要提交以下兩個標誌之一. 交互式的指定 vault 的密碼文件:
ansible-playbook site.yml --ask-vault-pass
該提示被用來解密(僅在內存中)任何 vault 加密訪問過的文件. 目前這些文件中全部的指令請求將被使用相同的密碼加密.
另外,密碼也能夠定義在一個文件或者一個腳本中,可是須要 Ansible 1.7 以上的版本才能支持.
當使用該功能時,必定要確認密碼文件的權限是安全的,以確保沒有人能夠隨意訪問或者變動密碼文件:
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt ansible-playbook site.yml --vault-password-file ~/.vault_pass.py
密碼存儲一行一個
若是你使用的是腳本而不是普通文件,確保腳本是可執行的,這樣密碼能夠輸出至標準設備.若是你的腳本須要提示輸入數據,那提示能夠被髮送到標準錯誤.
若是你是從持續集成系統(例如Jenkins)中使用 Ansible 的話上面的這種狀況你會用的到.
(–vault-password-file 參數能夠在 Ansible-Pull(拉取配置而非推送配置) 命令中被使用,儘管這將須要分發keys到對應的節點上,
因此 ,瞭解這些隱性問題後 – vault 更傾向使用 push 方式)