Ansible剧本的6个排查技巧

Ansible是一种功能很强大的工具,可以跨服务器、云、网络和容器等更多系统自动化管理各种平台。

成都创新互联公司主营铅山网站建设的网络公司,主营网站建设方案,重庆App定制开发,铅山h5成都小程序开发搭建,铅山网站营销推广欢迎铅山等地区企业咨询

您常常只需重用现有的角色和集合,就可以自动执行想要完成的操作。还有许多模块可供选择,可以在剧本中使用它们。

但是当您开始开发和测试更复杂的剧本时,最终需要一些故障排查方法。比如检查Ansible任务流、确认变量的数据类型,甚至在某个特定点暂停以检查它们的值。

本文讨论的一些技巧仅适用于通过命令行执行Ansible。其他技巧从Ansible Tower运行时也适用。

1. 你的Ansible环境和参数

如果您需要分析为什么某内容在剧本中没有按预期运行,最好先检查您的Ansible环境。

您在运行Ansible二进制文件和Python的哪些版本和路径?

如果您添加了剧本所需的操作系统包或Python模块,Ansible解释器会“看到”它们吗?

可以通过多种不同的方式获取这些基本信息。从命令行运行ansible --version命令。

 
 
 
  1. > ansible --version 
  2.  
  3. ansible 2.9.10 
  4.  
  5.   config file = /etc/ansible/ansible.cfg 
  6.   configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] 
  7.   
  8.  ansible python module location = /usr/lib/python3.6/site-packages/ansible 
  9.   executable location = /usr/bin/ansible 
  10.   python version = 3.6.8 (default, Mar 18 2021, 08:58:41) [GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] 

可以通过运行其他Ansible命令来获取同样的信息,比如使用--version选项的ansible-playbook或ansible-config。

在Ansible Tower中,如果使用VERBOSITY 2(更详细)或更高版本执行作业模板,可显示该信息。

除了Ansible和Python二进制文件的版本和位置之外,仔细检查用于模块的路径总是好事,包括执行是否使用了不是默认的ansible.cfg文件(即不是/etc/ansible /ansible.cfg)。

要调查来自自定义ansible.cfg文件的选项,可以从命令行执行以下操作:

 
 
 
  1. > ansible-config dump --only-changed 
  2. DEFAULT_BECOME(/home/admin/ansible/ansible.cfg) = True 
  3. DEFAULT_BECOME_USER(/home/admin/ansible/ansible.cfg) = root 
  4. DEFAULT_FORKS(/home/admin/ansible/ansible.cfg) = 10 
  5. DEFAULT_HOST_LIST(/home/admin/ansible/ansible.cfg) = ['/home/admin/ansible/inventory'] 
  6. DEFAULT_ROLES_PATH(/home/admin/ansible/ansible.cfg) = ['/home/admin/ansible/roles'] 
  7. HOST_KEY_CHECKING(/home/admin/ansible/ansible.cfg) = False 

顾名思义,这将列出与默认参数不同的参数。

2. 以详细模式运行

下一步是在调试模式下运行剧本,以获取有关任务和变量中所发生情况的更多详细信息。

您可以从命令行添加-v(或-vv、-vvv、-vvvv、-vvvvv)。最高的详细级别有时可能含有太多信息,因此最好在多次执行中逐渐增加详细级别,直至获得所需信息。

排查连接问题时级别4有所帮助,级别5适用于排查WinRM问题。

在Tower中,您可以从作业模板定义中选择VERBOSITY级别。

注意:记得在解决问题后禁用调试模式,因为详细信息仅对排查故障有用。

此外,在调试模式下,除非您在任务中使用no_log选项,否则会显示某些变量(比如密码)的值,因此完成后删除输出。

3.使用调试来显示变量

如果您很清楚问题可能出在哪里,可以使用更精准的方法:仅显示您需要查看的变量。

 
 
 
  1.  (...) 
  2.   - name: Display the value of the counter 
  3.      debug: 
  4.       msg: "Counter={{ counter }} / Data type={{ counter | type_debug }}" 
  5. (...) 
  6. TASK [Display the value of the counter]  
  7. *************************************************************************** 
  8. ok: [node1] => { 
  9.     "msg": "Counter=42 / Data type=AnsibleUnicode" 

这就是为什么我无法加大计数。过滤器type_debug显示,数据类型是text,而不是我以为的int。

4. 确保变量有合适的内容和数据类型

可以使用assert模块来确认:变量有预期的内容/类型,如果出了岔子,就促使任务失败。

下列剧本表明了这点:

 
 
 
  1. --- 
  2. - name: Assert examples 
  3.   hosts: node1 
  4.   gather_facts: no 
  5.   vars: 
  6.     var01: 13 
  7.   tasks: 
  8.   - debug: 
  9.       msg: "Parameter 01 is {{ (param01 | type_debug) }}" 
  10.   - name: Make sure that we have the right type of content before proceeding 
  11.     assert: 
  12.       that:  
  13.       - "var01 is defined" 
  14.       - "(var01 | type_debug) == 'int' " 
  15.       - "param01 is defined " 
  16.       - "(param01 | type_debug) == 'int' " 

如果我从命令行运行剧本,不提供额外变量:

 
 
 
  1. > ansible-playbook xassert.yml 
  2. PLAY [Assert examples]  
  3. *************************************************************************** 
  4. TASK [debug]  
  5. *************************************************************************** 
  6. ok: [node1] => { 
  7.     "msg": "Parameter 01 is AnsibleUndefined" 
  8. TASK [Make sure that we have the right type of content before proceeding] *************************************************************************** 
  9. fatal: [node1]: FAILED! => { 
  10.     "assertion": "param01 is defined ", 
  11.     "changed": false, 
  12.     "evaluated_to": false, 
  13.     "msg": "Assertion failed" 
  14. PLAY RECAP  
  15. *************************************************************************** 
  16. node1 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0   

如果我从命令行运行剧本,使用额外变量:

 
 
 
  1. > ansible-playbook xassert.yml -e "param01=99" 
  2. PLAY [Assert examples]  
  3. *************************************************************************** 
  4. TASK [debug]  
  5. *************************************************************************** 
  6. ok: [node1] => { 
  7.     "msg": "Parameter 01 is str" 
  8. TASK [Make sure that we have the right type of content before proceeding] *************************************************************************** 
  9. fatal: [node1]: FAILED! => { 
  10.     "assertion": "(param01 | type_debug) == 'int' ", 
  11.     "changed": false, 
  12.     "evaluated_to": false, 
  13.     "msg": "Assertion failed" 
  14. PLAY RECAP  
  15. ***************************************************************************node1 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0  

看到数据类型显示为str让我很惊讶,但这里给出了解释和解决方法(https://github.com/ansible/ansible/issues/14179)。

另外,如果您从Tower运行同一个剧本,将参数作为额外变量或调查字段来传递,参数的数据类型就会是int。

是的,这有点复杂,但如果您知道找什么,这些“功能”对您来说不成问题。

5. 列出事实和变量

无论您在库存中定义了变量,还是在剧本执行期间创建和赋予了额外变量,它在某个时候对于检查值很有用:

 
 
 
  1. --- 
  2. - name: vars 
  3.   hosts: node1,node2 
  4.   tasks: 
  5.   
  6.   - name: Dump vars 
  7.     copy: 
  8.       content: "{{ hostvars[inventory_hostname] | to_nice_yaml }}" 
  9.       dest: "/tmp/{{ inventory_hostname }}_vars.txt" 
  10.     delegate_to: control 
  11.   - name: Dump facts 
  12.     copy:  
  13.       content: "{{ ansible_facts | to_nice_yaml }}" 
  14.       dest: "/tmp/{{ inventory_hostname }}_facts.txt" 
  15.     delegate_to: control 

这将把变量和事实 (如果您在搜集事实)保存在单独的文件中,供您分析。

6. 使用任务调试器从命令行排查

您还可以使用Ansible调试器,在逐步模式下执行剧本,并以交互方式检查变量和参数的内容。

此外,还可以实时改变变量的值,并继续执行。

可以在任务或剧本层面启用调试器,比如在以下示例中:

 
 
 
  1. --- 
  2. - name: Example using debugger 
  3.   hosts: localhost 
  4.   gather_facts: no 
  5.   vars: 
  6.     radius: "5.3" 
  7.     pi: "3.1415926535" 
  8.   debugger: on_failed 
  9.   tasks: 
  10.   - name: Calculate the area of a circle 
  11.     debug: 
  12.       msg: 
  13.       - "Radius.............: {{ radius }}" 
  14.       - "pi................: {{ pi }}" 
  15.       - "Area of the circle: {{ (pi * (radius * radius)) }}" 

事先声明一下:我将变量定义为字符串,我试图执行计算时这显然会引发错误。

 
 
 
  1. > ansible-playbook xdebugger.yml  
  2. PLAY [Example using debugger]  
  3. *************************************************************************** 
  4. TASK [Calculate the area of a circle]  
  5. *************************************************************************** 
  6. fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on (Area of the circle: {{ (pi * (radius * radius)) }}): can't multiply sequence by non-int of type 'AnsibleUnicode'"} 
  7. [localhost] TASK: Calculate the area of a circle (debug)> p task_vars['pi'] 
  8. '3.1415926535' 
  9. [localhost] TASK: Calculate the area of a circle (debug)> p task_vars['radius'] 
  10.  
  11. '5.3' 
  12.  
  13. [localhost] TASK: Calculate the area of a circle (debug)> task_vars['pi']=3.1415926535 
  14. [localhost] TASK: Calculate the area of a circle (debug)> task_vars['radius']=5.3 
  15. [localhost] TASK: Calculate the area of a circle (debug)> p task_vars['radius'] 
  16.  
  17. 5.3 
  18.  
  19. [localhost] TASK: Calculate the area of a circle (debug)> task_vars['pi']=3.1415926535 
  20. [localhost] TASK: Calculate the area of a circle (debug)> redo 
  21. ok: [localhost] => { 
  22.     "msg": [ 
  23.         "Radius............: 5.3", 
  24.         "pi................: 3.1415926535", 
  25.         "Area of the circle: 88.247337636815" 
  26.     ] 
  27. PLAY RECAP  
  28. *************************************************************************** 
  29. localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0   

这里发生了什么:

1. 起初,任务失败,抱怨是非int变量。

2. 调试器被调用。

3. 我使用了 print (p) 命令来显示变量的值。

4. 在这种情况下,我知道问题出在数据类型上,但有人可能认为值是正确的(如果不注意值两边的引号)。

5. 后来,我更新了变量的内容,为它们赋予了数字。

6. 然后,我使用redo命令用新值重新执行任务,结果成功完成。

这是简单的场景,因为我们知道没人会真正使用Ansible来计算圆的面积。但在较复杂的情况下,在长时间的剧本执行过程中找到变量的内容可能很有用,无需从头开始就能在此后继续下去。

本文标题:Ansible剧本的6个排查技巧
网页URL:http://www.shufengxianlan.com/qtweb/news26/55026.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联