ansible簡單但功能強大。ansible的簡單意思是操做容易理解和遵循。可以理解和遵循對於在調試不但願的行爲的時候就很是重要了。本章,咱們將探索各類能夠用於檢查、反思、修改、以及調試ansible操做的各類方法:python
增長ansible輸出贅言能夠解決不少問題。從無效模塊參數到不正確的鏈接命令,增長贅言對於指出錯誤源頭相當重要。劇本日誌和贅言在第二章大體上討論了關於在執行劇本時如何保護祕密值。這一節會深刻描述贅言和日誌。linux
當使用ansible-playbook執行劇本的時候,輸出會顯示到標準輸出。使用默認級別的贅言,顯示很是少的信息。劇情在執行的時候,ansible-playbook會打印帶劇情名字的PLAY頭。而後每一個任務,會打印帶有任務名的TASK頭。每一個主機執行任務的時候,主機名和任務狀態會一塊兒打印出來,任務狀態可能有ok, fatal, changed幾種。沒有更多的任務信息會打印出來,例如被執行的模塊,提供給模塊的參數,或者執行返回的數據。這對於優秀的劇原本說很好了,但我更傾向於更多的瞭解個人劇情。本書以前的例子中,咱們都使用了一個贅言級別爲2(-vv),所以咱們能看到模塊、模塊參數、以及返回數據。nginx
總共有五種級別的贅言級別:shell
增長贅言能夠幫助準確指出錯誤可能發生的地方,以及提供更多瞭解ansible如何執行它的操做的額外信息。api
超過1的贅言可能會致使敏感信息輸出,所以在潛在共享環境下增長贅言級別的時候要當心些。cookie
默認狀況下,ansible-playbook會將日誌輸出到標準輸出,輸出量可能超出終端模擬器使用的緩衝大小;所以,有必要將輸出保存到指定文件中。各類shell都提供了一些機制能對輸出進行重定向,更優雅的解決方法是將ansible-playbook日誌重定向到文件。能夠經過在ansible.cfg文件中配置log_path參數或使用環境變量ANSIBLE_LOG_PATH來設置。二者的值都是一個日誌文件的路徑。若是路徑不存在,ansible會嘗試建立這個文件。若是文件不存在,ansible會嘗試建立文件。若是文件存在,那麼,ansible會將輸出附加到文件末尾,容許合併多個劇本執行日誌。app
使用日誌文件和將日誌在終端標準輸出是不互相排斥的。二者同時發生,而且提供的贅言級別對二者都有影響。python2.7
開發ansible劇本常見的問題就是對變量值的不恰當使用或無效假設。這點對於使用任務結果註冊變量,並將其使用到後續的任務或模版中的時候就更加常見了。若是結果的指望元素沒有正確訪問,最終結果將是步伐預料的,或者甚至是有害的。ssh
要檢查不正確變量的使用,變量值的監測是關鍵。監測變量值最簡單的方法就是使用debug模塊。debug模塊容許在屏幕上顯示自由格式的文本,並與其餘任務同樣,模塊參數也能夠利用Jinja2模版語法。讓咱們來演示一下,建立一個執行任務的簡單劇本,註冊結果,而後用使用Jinja2語法呈現變量的調試語句展現結果:工具
--- - name: variable introspection demo hosts: localhost gather_facts: false tasks: - name: do a thing uri: url: https://derpops.bike register: derpops - name: show deppops debug: msg: "derpops value is {{ derpops }}"
運行劇本後,輸出大體以下:
PLAYBOOK: introspection.yaml *************************************************************************************************************************************************** 1 plays in introspection.yaml PLAY [variable introspection demo] ********************************************************************************************************************************************* META: ran handlers TASK [do a thing] ************************************************************************************************************************************************************** task path: /Users/apple/Sites/workspace/k8s-cluster/ansibledemo/introspection.yaml:7 ok: [localhost] => {"changed": false, "connection": "close", "content_length": "2", "content_type": "text/plain;charset=UTF-8", "cookies": {}, "cookies_string": "", "date": "Sun, 12 Aug 2018 15:23:37 GMT", "msg": "OK (2 bytes)", "redirected": false, "server": "nginx", "status": 200, "url": "http://xxxx"} TASK [show deppops] ************************************************************************************************************************************************************ task path: /Users/apple/Sites/workspace/k8s-cluster/ansibledemo/introspection.yaml:11 ok: [localhost] => { "msg": "derpops value is {u'status': 200, u'content_length': u'2', u'cookies': {}, u'url': u'https://xxxx', u'changed': False, u'server': u'nginx', 'failed': False, u'connection': u'close', u'content_type': u'text/plain;charset=UTF-8', u'date': u'Sun, 12 Aug 2018 15:23:37 GMT', u'redirected': False, u'cookies_string': u'', u'msg': u'OK (2 bytes)'}" } META: ran handlers META: ran handlers PLAY RECAP ********************************************************************************************************************************************************************* localhost : ok=2 changed=0 unreachable=0 failed=0
debug模塊具備不一樣的選項,可能會很是有用。接下來咱們不直接打印debug模版使用的自由格式的字符串,這個模塊能夠直接簡單的打印任意變量的值。咱們可使用var參數代替msg參數。 接着咱們重複上面的例子,可是此次,咱們使用var參數,咱們將訪問derpops變量的server子元素:
--- - name: variable introspection demo hosts: localhost gather_facts: false tasks: - name: do a thing uri: url: http://hzzdnb.zjtech.cc/cbapi/dev-batch-reg-result register: derpops - name: show deppops debug: var: derpops.server
而後執行劇本後,能夠看到能夠看到server的值以下:
TASK [show deppops] ************************************************************************************************************************************************************ task path: /Users/apple/Sites/workspace/k8s-cluster/ansibledemo/introspection.yaml:11 ok: [localhost] => { "derpops.server": "nginx" }
注意,使用msg參數的時候,變量名須要使用模版中變量的語法,外邊用雙大括號包圍;而使用var參數的時候,咱們就不用對變量進行包裝了。這是由於msg指望接受的是字符串,所以ansible須要呈現模版爲字符串。然而,var指望的是單個未呈現變量。
另一個在劇本中常常出錯的是對複雜變量的子元素的不恰當引用。複雜變量不是字符串;它多是列表或哈希。一般會引用錯誤的子元素,或者元素使用不一樣的類型不恰當的引用了。
列表很容易使用,哈希表明一些惟一挑戰。哈希是無序key-value集合。
有時候只對變量數據進行日誌和監測不足夠定位問題。若是發生這樣的狀況,有必要深刻ansible的內核。有兩種重要的ansible代碼集合:
本地ansible代碼是與ansible一塊兒出現的最大一部分代碼。全部的劇本、劇情、角色、以及任務解析代碼都在本地。全部的任務結果處理代碼以及傳輸代碼都在本地。全部的代碼除了傳輸給遠程主機的裝配模塊代碼都位於本地。
本地ansible代碼能夠分爲三個主要部分:
庫存代碼處理解析來自目錄樹中主機文件、動態庫存腳本、或二者組合中的庫存數據。劇本代碼用於將劇本yaml代碼解析爲ansible內部的python對象。運行器代碼是處理進程fork、鏈接主機、執行模塊、處理結果、以及不少其餘事情的核心API。學習啓動調試的通常區域是在實踐中進行的,可是這裏描述的只是通常領域的一個起點。
由於ansible是用python實現的,調試本地代碼執行的是python debugger, pdb。這個工具可讓咱們給ansible代碼裏邊插入斷點,並逐行的進行交互執行代碼。這對於在執行本地代碼時檢查ansible內部狀態很是有用。有不少書籍和網站都介紹了pdb的使用,你能夠經過python pdb進行搜索,這裏不作重複了。基礎是編輯源代碼來調試,插入新代碼行建立斷點,而後執行代碼。 代碼執行會在斷點處中止,並提供提示來探索代碼的狀態。
庫存代碼處理查找庫存源、讀取或執行發現的文件、解析庫存數據到庫存對象、以及從庫存加載變量數據。要調試ansible如何處理庫存,必須在inventory/__init__.py或inventory/子目錄中的其餘文件中添加斷點。
對於linux系統或mac系統,咱們能夠經過下面的方式查找ansible源碼所在的目錄:
pip show ansible
我本身的ansible源碼位於/usr/local/lib/python2.7/site-packages/ansible。
斷點調試回頭整理pdb調試相關的資料。