Ansible16:Playbook高级用法
目錄
- 本地執(zhí)行
- 任務(wù)委托
- 任務(wù)暫停
- 滾動(dòng)執(zhí)行
- 只執(zhí)行一次
- 設(shè)置環(huán)境變量
- 交互式提示
本地執(zhí)行
如果希望在控制主機(jī)本地運(yùn)行一個(gè)特定的任務(wù),可以使用local_action語句。
假設(shè)我們需要配置的遠(yuǎn)程主機(jī)剛剛啟動(dòng),如果我們直接運(yùn)行playbook,可能會(huì)因?yàn)閟shd服務(wù)尚未開始監(jiān)聽而導(dǎo)致失敗,我們可以在控制主機(jī)上使用如下示例來等待被控端sshd端口監(jiān)聽:
- name: wait for ssh server to be runningwait_forport: 22 host: "{{ inventory_hostname }}" search_regex: OpenSSHconnection: local任務(wù)委托
在有些時(shí)候,我們希望運(yùn)行與選定的主機(jī)或主機(jī)組相關(guān)聯(lián)的task,但是這個(gè)task又不需要在選定的主機(jī)或主機(jī)組上執(zhí)行,而需要在另一臺(tái)服務(wù)器上執(zhí)行。
這種特性適用于以下場景:
- 在告警系統(tǒng)中啟用基于主機(jī)的告警
- 向負(fù)載均衡器中添加或移除一臺(tái)主機(jī)
- 在dns上添加或修改針對(duì)某個(gè)主機(jī)的解析
- 在存儲(chǔ)節(jié)點(diǎn)上創(chuàng)建一個(gè)存儲(chǔ)以用于主機(jī)掛載
- 使用一個(gè)外部程序來檢測主機(jī)上的服務(wù)是否正常
可以使用delegate_to語句來在另一臺(tái)主機(jī)上運(yùn)行task:
- name: enable alerts for web servershosts: webserverstasks:- name: enable alertsnagios: action=enable_alerts service=web host="{{ inventory_hostname }}"delegate_to: nagios.example.com如果delegate_to: 127.0.0.1的時(shí)候,等價(jià)于local_action
任務(wù)暫停
有些情況下,一些任務(wù)的運(yùn)行需要等待一些狀態(tài)的恢復(fù),比如某一臺(tái)主機(jī)或者應(yīng)用剛剛重啟,我們需要需要等待它上面的某個(gè)端口開啟,此時(shí)就需要將正在運(yùn)行的任務(wù)暫停,直到其狀態(tài)滿足要求。
Ansible提供了wait_for模塊以實(shí)現(xiàn)任務(wù)暫停的需求
wait_for模塊常用參數(shù):
- connect_timeout:在下一個(gè)任務(wù)執(zhí)行之前等待連接的超時(shí)時(shí)間
- delay:等待一個(gè)端口或者文件或者連接到指定的狀態(tài)時(shí),默認(rèn)超時(shí)時(shí)間為300秒,在這等待的300s的時(shí)間里,wait_for模塊會(huì)一直輪詢指定的對(duì)象是否到達(dá)指定的狀態(tài),delay即為多長時(shí)間輪詢一次狀態(tài)。
- host:wait_for模塊等待的主機(jī)的地址,默認(rèn)為127.0.0.1
- port:wait_for模塊待待的主機(jī)的端口
- path:文件路徑,只有當(dāng)這個(gè)文件存在時(shí),下一任務(wù)才開始執(zhí)行,即等待該文件創(chuàng)建完成
- state:等待的狀態(tài),即等待的文件或端口或者連接狀態(tài)達(dá)到指定的狀態(tài)時(shí),下一個(gè)任務(wù)開始執(zhí)行。當(dāng)?shù)鹊膶?duì)象為端口時(shí),狀態(tài)有started,stoped,即端口已經(jīng)監(jiān)聽或者端口已經(jīng)關(guān)閉;當(dāng)?shù)却膶?duì)象為文件時(shí),狀態(tài)有present或者started,absent,即文件已創(chuàng)建或者刪除;當(dāng)?shù)却膶?duì)象為一個(gè)連接時(shí),狀態(tài)有drained,即連接已建立。默認(rèn)為started
- timeout:wait_for的等待的超時(shí)時(shí)間,默認(rèn)為300秒
示例:
#等待8080端口已正常監(jiān)聽,才開始下一個(gè)任務(wù),直到超時(shí) - wait_for: port: 8080 state: started #等待8000端口正常監(jiān)聽,每隔10s檢查一次,直至等待超時(shí) - wait_for: port: 8000 delay: 10 #等待8000端口直至有連接建立 - wait_for: host: 0.0.0.0 port: 8000 delay: 10 state: drained#等待8000端口有連接建立,如果連接來自10.2.1.2或者10.2.1.3,則忽略。 - wait_for: host: 0.0.0.0 port: 8000 state: drained exclude_hosts: 10.2.1.2,10.2.1.3 #等待/tmp/foo文件已創(chuàng)建 - wait_for: path: /tmp/foo #等待/tmp/foo文件已創(chuàng)建,而且該文件中需要包含completed字符串 - wait_for: path: /tmp/foo search_regex: completed #等待/var/lock/file.lock被刪除 - wait_for: path: /var/lock/file.lock state: absent #等待指定的進(jìn)程被銷毀 - wait_for: path: /proc/3466/status state: absent #等待openssh啟動(dòng),10s檢查一次 - wait_for: port: 22 host: "{{ ansible_ssh_host | default(inventory_hostname) }}" search_regex: OpenSSH delay: 10滾動(dòng)執(zhí)行
默認(rèn)情況下,ansible會(huì)并行的在所有選定的主機(jī)或主機(jī)組上執(zhí)行每一個(gè)task,但有的時(shí)候,我們會(huì)希望能夠逐臺(tái)運(yùn)行。最典型的例子就是對(duì)負(fù)載均衡器后面的應(yīng)用服務(wù)器進(jìn)行更新時(shí)。通常來講,我們會(huì)將應(yīng)用服務(wù)器逐臺(tái)從負(fù)載均衡器上摘除,更新,然后再添加回去。我們可以在play中使用serial語句來告訴ansible限制并行執(zhí)行play的主機(jī)數(shù)量。
下面是一個(gè)在amazon EC2的負(fù)載均衡器中移除主機(jī),更新軟件包,再添加回負(fù)載均衡的配置示例:
- name: upgrade pkgs on servers behind load balancerhosts: myhostsserial: 1tasks:- name: get the ec2 instance id and elastic load balancer idec2_facts:- name: take the host out of the elastic load balancer idlocal_action: ec2_elbargs:instance_id: "{{ ansible_ec2_instance_id }}"state: absent- name: upgrade pkgsapt: update_cache: yes upgrade: yes- name: put the host back n the elastic load balancerlocal_action: ec2_elbargs:instance_id: "{{ ansible_ec2_instance_id }}"state: presentec2_elbs: "{{ items }}"with_items: ec2_elbs在上述示例中,serial的值為1,即表示在某一個(gè)時(shí)間段內(nèi),play只在一臺(tái)主機(jī)上執(zhí)行。如果為2,則同時(shí)有2臺(tái)主機(jī)運(yùn)行play。
一般來講,當(dāng)task失敗時(shí),ansible會(huì)停止執(zhí)行失敗的那臺(tái)主機(jī)上的任務(wù),但是繼續(xù)對(duì)其他 主機(jī)執(zhí)行。在負(fù)載均衡的場景中,我們會(huì)更希望ansible在所有主機(jī)執(zhí)行失敗之前就讓play停止,否則很可能會(huì)面臨所有主機(jī)都從負(fù)載均衡器上摘除并且都執(zhí)行失敗導(dǎo)致服務(wù)不可用的場景。這個(gè)時(shí)候,我們可以使用serial語句配合max_fail_percentage語句使用。max_fail_percentage表示當(dāng)最大失敗主機(jī)的比例達(dá)到多少時(shí),ansible就讓整個(gè)play失敗。示例如下:
- name: upgrade pkgs on fservers behind load balancerhosts: myhostsserial: 1max_fail_percentage: 25tasks:......假如負(fù)載均衡后面有4臺(tái)主機(jī),并且有一臺(tái)主機(jī)執(zhí)行失敗,這時(shí)ansible還會(huì)繼續(xù)運(yùn)行,要讓Play停止運(yùn)行,則必須超過25%,所以如果想一臺(tái)失敗就停止執(zhí)行,我們可以將max_fail_percentage的值設(shè)為24。如果我們希望只要有執(zhí)行失敗,就放棄執(zhí)行,我們可以將max_fail_percentage的值設(shè)為0。
只執(zhí)行一次
某些時(shí)候,我們希望某個(gè)task只執(zhí)行一次,即使它被綁定到了多個(gè)主機(jī)上。例如在一個(gè)負(fù)載均衡器后面有多臺(tái)應(yīng)用服務(wù)器,我們希望執(zhí)行一個(gè)數(shù)據(jù)庫遷移,只需要在一個(gè)應(yīng)用服務(wù)器上執(zhí)行操作即可。
可以使用run_once語句來處理:
- name: run the database migrateionscommand: /opt/run_migrateionsrun_once: true還可以與local_action配合使用,如下:
- name: run the task locally, only oncecommand: /opt/my-custom-commandconnection: localrun_once: true還可以與delegate_to配合使用,讓這個(gè)只執(zhí)行一次的任務(wù)在指定的機(jī)器上運(yùn)行:
- name: run the task locally, only oncecommand: /opt/my-custom-commandrun_once: truedelegate_to: app.a1-61-105.dev.unp設(shè)置環(huán)境變量
我們在命令行下執(zhí)行某些命令的時(shí)候,這些命令可能會(huì)需要依賴環(huán)境變量。比如在安裝某些包的時(shí)候,可能需要通過代理才能完成完裝。或者某個(gè)腳本可能需要調(diào)用某個(gè)環(huán)境變量才能完成運(yùn)行。
ansible 支持通過environment關(guān)鍵字來定義一些環(huán)境變量。
在如下場景中可能需要用到環(huán)境變量:
- 運(yùn)行shell的時(shí)候,需要設(shè)置path變量
- 需要加載一些庫,這些庫不在系統(tǒng)的標(biāo)準(zhǔn)庫路徑當(dāng)中
下面是一個(gè)簡單示例:
--- - name: upload a remote file to aws s3hosts: testtasks:- name: install pipyum:name: python-pipstate: installed- name: install the aws toolspip:name: awsclistate: present- name upload file to s3shell aws s3 put-object --bucket=my-test-bucket --key={{ ansible_hostname }}/fstab --body=/etc/fstab --region=eu-west-1environment:AWS_ACCESS_KEY_ID: xxxxxxAWS_SECRET_ACCESS_KEY: xxxxxx事實(shí)上,environment也可以存儲(chǔ)在變量當(dāng)中:
- hosts: allremote_user: rootvars:proxy_env:http_proxy: http://proxy.example.com:8080https_proxy: http://proxy.bos.example.com:8080tasks:- apt: name=cobbler state=installedenvironment: proxy_env交互式提示
在少數(shù)情況下,ansible任務(wù)運(yùn)行的過程中需要用戶輸入一些數(shù)據(jù),這些數(shù)據(jù)要么比較秘密不方便,或者數(shù)據(jù)是動(dòng)態(tài)的,不同的用戶有不同的需求,比如輸入用戶自己的賬戶和密碼或者輸入不同的版本號(hào)會(huì)觸發(fā)不同的后續(xù)操作等。ansible的vars_prompt關(guān)鍵字就是用來處理上述這種與用戶交互的情況的。
- hosts: allremote_user: rootvars_prompt:- name: share_userprompt: "what is your network username?"private: yes- name: share_passprompt: "what is your network password"private: yestasks:- debug:var: share_user- debug:var: share_passvars_prompt常用選項(xiàng)說明:
- private: 默認(rèn)為yes,表示用戶輸入的值在命令行不可見
- default:定義默認(rèn)值,當(dāng)用戶未輸入時(shí)則使用默認(rèn)值
- confirm:如果設(shè)置為yes,則會(huì)要求用戶輸入兩次,適合輸入密碼的情況
轉(zhuǎn)載于:https://www.cnblogs.com/breezey/p/10996651.html
總結(jié)
以上是生活随笔為你收集整理的Ansible16:Playbook高级用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新手使用vue-router传参时注意事
- 下一篇: 几款让你爱不释手的语音转文字软件