Ansible16:Playbook高级用法
目錄
- 本地執行
- 任務委托
- 任務暫停
- 滾動執行
- 只執行一次
- 設置環境變量
- 交互式提示
本地執行
如果希望在控制主機本地運行一個特定的任務,可以使用local_action語句。
假設我們需要配置的遠程主機剛剛啟動,如果我們直接運行playbook,可能會因為sshd服務尚未開始監聽而導致失敗,我們可以在控制主機上使用如下示例來等待被控端sshd端口監聽:
- name: wait for ssh server to be runningwait_forport: 22 host: "{{ inventory_hostname }}" search_regex: OpenSSHconnection: local任務委托
在有些時候,我們希望運行與選定的主機或主機組相關聯的task,但是這個task又不需要在選定的主機或主機組上執行,而需要在另一臺服務器上執行。
這種特性適用于以下場景:
- 在告警系統中啟用基于主機的告警
- 向負載均衡器中添加或移除一臺主機
- 在dns上添加或修改針對某個主機的解析
- 在存儲節點上創建一個存儲以用于主機掛載
- 使用一個外部程序來檢測主機上的服務是否正常
可以使用delegate_to語句來在另一臺主機上運行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的時候,等價于local_action
任務暫停
有些情況下,一些任務的運行需要等待一些狀態的恢復,比如某一臺主機或者應用剛剛重啟,我們需要需要等待它上面的某個端口開啟,此時就需要將正在運行的任務暫停,直到其狀態滿足要求。
Ansible提供了wait_for模塊以實現任務暫停的需求
wait_for模塊常用參數:
- connect_timeout:在下一個任務執行之前等待連接的超時時間
- delay:等待一個端口或者文件或者連接到指定的狀態時,默認超時時間為300秒,在這等待的300s的時間里,wait_for模塊會一直輪詢指定的對象是否到達指定的狀態,delay即為多長時間輪詢一次狀態。
- host:wait_for模塊等待的主機的地址,默認為127.0.0.1
- port:wait_for模塊待待的主機的端口
- path:文件路徑,只有當這個文件存在時,下一任務才開始執行,即等待該文件創建完成
- state:等待的狀態,即等待的文件或端口或者連接狀態達到指定的狀態時,下一個任務開始執行。當等的對象為端口時,狀態有started,stoped,即端口已經監聽或者端口已經關閉;當等待的對象為文件時,狀態有present或者started,absent,即文件已創建或者刪除;當等待的對象為一個連接時,狀態有drained,即連接已建立。默認為started
- timeout:wait_for的等待的超時時間,默認為300秒
示例:
#等待8080端口已正常監聽,才開始下一個任務,直到超時 - wait_for: port: 8080 state: started #等待8000端口正常監聽,每隔10s檢查一次,直至等待超時 - 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文件已創建 - wait_for: path: /tmp/foo #等待/tmp/foo文件已創建,而且該文件中需要包含completed字符串 - wait_for: path: /tmp/foo search_regex: completed #等待/var/lock/file.lock被刪除 - wait_for: path: /var/lock/file.lock state: absent #等待指定的進程被銷毀 - wait_for: path: /proc/3466/status state: absent #等待openssh啟動,10s檢查一次 - wait_for: port: 22 host: "{{ ansible_ssh_host | default(inventory_hostname) }}" search_regex: OpenSSH delay: 10滾動執行
默認情況下,ansible會并行的在所有選定的主機或主機組上執行每一個task,但有的時候,我們會希望能夠逐臺運行。最典型的例子就是對負載均衡器后面的應用服務器進行更新時。通常來講,我們會將應用服務器逐臺從負載均衡器上摘除,更新,然后再添加回去。我們可以在play中使用serial語句來告訴ansible限制并行執行play的主機數量。
下面是一個在amazon EC2的負載均衡器中移除主機,更新軟件包,再添加回負載均衡的配置示例:
- 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,即表示在某一個時間段內,play只在一臺主機上執行。如果為2,則同時有2臺主機運行play。
一般來講,當task失敗時,ansible會停止執行失敗的那臺主機上的任務,但是繼續對其他 主機執行。在負載均衡的場景中,我們會更希望ansible在所有主機執行失敗之前就讓play停止,否則很可能會面臨所有主機都從負載均衡器上摘除并且都執行失敗導致服務不可用的場景。這個時候,我們可以使用serial語句配合max_fail_percentage語句使用。max_fail_percentage表示當最大失敗主機的比例達到多少時,ansible就讓整個play失敗。示例如下:
- name: upgrade pkgs on fservers behind load balancerhosts: myhostsserial: 1max_fail_percentage: 25tasks:......假如負載均衡后面有4臺主機,并且有一臺主機執行失敗,這時ansible還會繼續運行,要讓Play停止運行,則必須超過25%,所以如果想一臺失敗就停止執行,我們可以將max_fail_percentage的值設為24。如果我們希望只要有執行失敗,就放棄執行,我們可以將max_fail_percentage的值設為0。
只執行一次
某些時候,我們希望某個task只執行一次,即使它被綁定到了多個主機上。例如在一個負載均衡器后面有多臺應用服務器,我們希望執行一個數據庫遷移,只需要在一個應用服務器上執行操作即可。
可以使用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配合使用,讓這個只執行一次的任務在指定的機器上運行:
- name: run the task locally, only oncecommand: /opt/my-custom-commandrun_once: truedelegate_to: app.a1-61-105.dev.unp設置環境變量
我們在命令行下執行某些命令的時候,這些命令可能會需要依賴環境變量。比如在安裝某些包的時候,可能需要通過代理才能完成完裝。或者某個腳本可能需要調用某個環境變量才能完成運行。
ansible 支持通過environment關鍵字來定義一些環境變量。
在如下場景中可能需要用到環境變量:
- 運行shell的時候,需要設置path變量
- 需要加載一些庫,這些庫不在系統的標準庫路徑當中
下面是一個簡單示例:
--- - 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事實上,environment也可以存儲在變量當中:
- 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交互式提示
在少數情況下,ansible任務運行的過程中需要用戶輸入一些數據,這些數據要么比較秘密不方便,或者數據是動態的,不同的用戶有不同的需求,比如輸入用戶自己的賬戶和密碼或者輸入不同的版本號會觸發不同的后續操作等。ansible的vars_prompt關鍵字就是用來處理上述這種與用戶交互的情況的。
- 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常用選項說明:
- private: 默認為yes,表示用戶輸入的值在命令行不可見
- default:定義默認值,當用戶未輸入時則使用默認值
- confirm:如果設置為yes,則會要求用戶輸入兩次,適合輸入密碼的情況
轉載于:https://www.cnblogs.com/breezey/p/10996651.html
總結
以上是生活随笔為你收集整理的Ansible16:Playbook高级用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新手使用vue-router传参时注意事
- 下一篇: 几款让你爱不释手的语音转文字软件