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调试相关的资料。