快捷搜索:  汽车  科技

ansible操作方法(Ansible使用CallBack插件分析Playbook执行性能)

ansible操作方法(Ansible使用CallBack插件分析Playbook执行性能)不只是剧本可以使用,临时命令的方式也可以使用回调。感兴趣小伙伴可以看看官网那么在Ansible中通过CallBack插件调整对各种事件的响应来扩展 Ansible。其中一些插件也会修改命令行工具(如ansible-playbook 命令)的输出,以提供额外的信息。运维的方式理解:类似Linux开机,启动的第一个进程systemd要引导一些系统必要的启动项,当然内核版本不同,对应的启动规则不同,但是如果你配置的服务设置了开启自启,会在启动级别的target目录下建一个指向服务service文件的软连接,即服务一定是某个启动级别target的正向依赖。这里的配置开启自启的服务可以理解为我们给Ansible配置回调插件。亦或者我们之前讲的 剧本中的任务控制指令pro_task和post_taks,K8s中的 pod hook 通过poststart和prestop,配置在pod创建和死亡的回调处

写在前面
  • 和小伙伴们分享一些Ansible回调插件的笔记
  • 一个好的剧本,执行起来会很是丝滑,良好的执行体验让你甚至感觉不到执行了很久,哈...
  • Ansible提供了callBack插件来处理playbook中的回调事件。我们可以通过回调插件分析剧本资源利用率、消耗时间,从而优化剧本。
  • 博文涉及内容: 查看CallBack插件以及插件说明分析控制节点执行剧本CPU和内存的消耗统计任务和角色剧本的执行时间自定义一个callBack插件实现执行完剧本打开博客
  • 食用方式 了解 ansible 基础知识
  • 理解不足小伙伴帮忙指正

一个好的剧本,执行起来会很是丝滑,良好的执行体验让你甚至感觉不到执行了很久,哈...。--------山河已无恙


对这方面感兴趣的小伙伴可以到官网看下:https://docs.ansible.com/ansible/2.8/plugins/callback.html

什么是Ansible Callback插件

关于回调插件,官网文档中这样讲,Ansible的回调插件可以在响应事件时向 Ansible 添加新行为。默认情况下,回调插件控制在运行命令行程序时看到的大部分输出,但也可用于添加额外的输出、与其他工具集成以及将事件编组到存储后端。如有必要,也可以创建自定义回调插件

开发的方式理解,

  • 从细粒度编码角度理解,可以理解为钩子,回调函数,类比的话,类似后端JVM中的钩子进程,在JVM进程结束时运行的进程。处理一些资源释放。前端VUE的8个生命周期方法,从指令编译到数据加载、模板渲染,DOM挂载等不同时期都会触发对应的回调函数。(Ansible 的回调也同样基于剧本生命周期方法实现)
  • 从粗粒度编程思想理解,类似面向切面编程(AOP),把代码的执行逻辑块之间的连接点看做是一个个切入点,把一些不重要,但是需要的东西做成切面 在必要时织入到逻辑块内。

运维的方式理解:

类似Linux开机,启动的第一个进程systemd要引导一些系统必要的启动项,当然内核版本不同,对应的启动规则不同,但是如果你配置的服务设置了开启自启,会在启动级别的target目录下建一个指向服务service文件的软连接,即服务一定是某个启动级别target的正向依赖。这里的配置开启自启的服务可以理解为我们给Ansible配置回调插件。

亦或者我们之前讲的 剧本中的任务控制指令pro_task和post_taks,K8s中的 pod hook 通过poststart和prestop,配置在pod创建和死亡的回调处理等等。

那么在Ansible中通过CallBack插件调整对各种事件的响应来扩展 Ansible。其中一些插件也会修改命令行工具(如ansible-playbook 命令)的输出,以提供额外的信息。

不只是剧本可以使用,临时命令的方式也可以使用回调。感兴趣小伙伴可以看看官网

需要说明的是Ansible附带的大多数回调默认情况下是禁用的,需要在ansible.cfg文件中列入白名单才能正常工作 通过 callback_whitelist 指令在ansible.cfg中启用这些插件 这里2.8和2.9的版本还有些区别。我们主要看下2.8的版本

ansible.cfg 的配置,下面的配置中,在插件白名单里添加了timer proFile_tasks cgroup_perf_recap这三个回调

[ defaults] inventory=inventory remote_user=devops callback_whitelist=timer profile_tasks cgroup_perf_recap

使用ansible-doc -t callback -l命令可以列出可用的插件

$ ansible-doc -t callback -l actionable shows only items that need attention aws_resource_actions summarizes all "resource:actions" completed cgroup_memory_recap Profiles maximum memory usage of tasks and full execution using cgroups cgroup_perf_recap Profiles system activity of tasks and full execution using cgroups context_demo demo callback that adds play/task context counter_enabled adds counters to the output items (tasks and hosts/task) debug formatted stdout/stderr display ..... ..... $

使用ansible-doc -t callback plugin-name查看指定插件的文档:下面是我们查看的timer这个插件

$ ansible-doc -t callback timer > TIMER (/usr/lib/python3.6/site-packages/ansible/plugins/callback/timer.py) This callback just adds total play duration to the play stats. * This module is maintained by The Ansible Community REQUIREMENTS: whitelist in configuration CALLBACK_TYPE: aggregate METADATA: status: - preview supported_by: community 。。。。。。。。。

可以看到,这个插件用于将总的play执行时间添加到当前play的最后输出中。来简单看一下怎么实现的。

[root@foundation0 ~]# cat /usr/lib/python3.6/site-packages/ansible/plugins/callback/timer.py # (c) 2017 Ansible Project # GNU General Public License v3.0 (see copyING or https://www.gnu.org/licenses/gpl-3.0.txt) # Make coding more python3-ish from __future__ import (absolute_import division print_function) __metaclass__ = type DOCUMENTATION = ''' callback: timer callback_type: aggregate requirements: - whitelist in configuration short_description: Adds time to play stats version_added: "2.0" description: - This callback just adds total play duration to the play stats. ''' from datetime import datetime from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): """ This callback module tells you how long your plays ran for. """ CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'aggregate' CALLBACK_NAME = 'timer' CALLBACK_NEEDS_WHITELIST = True def __init__(self): super(CallbackModule self).__init__() self.start_time = datetime.utcnow() def days_hours_minutes_seconds(self runtime): minutes = (runtime.seconds // 60) % 60 r_seconds = runtime.seconds % 60 return runtime.days runtime.seconds // 3600 minutes r_seconds def playbook_on_stats(self stats): self.v2_playbook_on_stats(stats) def v2_playbook_on_stats(self stats): end_time = datetime.utcnow() runtime = end_time - self.start_time self._display.display("Playbook run took %s days %s hours %s minutes %s seconds" % (self.days_hours_minutes_seconds(runtime))) [root@foundation0 ~]#

逻辑很简单,我们可以看到CallbackModule继承了CallbackBase,覆盖了需要回调的方法。

$ cat /usr/lib/python3.6/site-packages/ansible/plugins/callback/__init__.py | grep -A 2 playbook_on_stats def playbook_on_stats(self stats): pass -- def v2_playbook_on_stats(self stats): self.playbook_on_stats(stats)

playbook_on_stats、v2_playbook_on_stats,这两个方法中,后者是在play中分配对象的回调,前者用于在play结束时的回调。 看一下CallbackBase的注释

$ cat /usr/lib/python3.6/site-packages/ansible/plugins/callback/__init__.py | grep -A 6 CallbackBase | tail -n 7 class CallbackBase(AnsiblePlugin): ''' This is a base ansible callback class that does nothing. New callbacks should use this class as a base and override any callback methods they wish to execute custom actions. ''' $

这是一个基本的ansible回调类,它什么都不做。新的回调使用这个类作为基类,重写他们希望执行的任何回调方法自定义操作。

如果需要编写一些自定义的回调插件,我们可以以同样的方法来尝试

下面来看看如何通过利用CallBack插件统计资源消耗和执行时间来分析Playbook的执行性能。

我们编写一个剧本用于测试,

$ cat tags.yaml --- - name: tags Demo 1 hosts: servera tags: - play-tag-1 roles: - role: tag_role tags: - role-tags tasks: - name: task 1 tag shell: echo 'tags to task 1' tags: - task-tags-1 - name: include or import a tasks file include_tasks: file: tasks_file tags: - include-import - block: - name: task 1 in block shell: echo 'task 1 in block' - name: task 2 in block shell: echo 'task 2 in block' tags: - block-tags - name: tags Demo 2 hosts: servera tags: - play-tag-2 tasks: - name: task 2 tag shell: echo 'tags to task 2' tags: - task-tag-2

执行测试一下

$ ansible-playbook copy_task.yaml PLAY [Deploy the w eb content on the web servers] ****************************************************************** TASK [copy demo] *************************************************************************************************** ok: [servera] ok: [serverc] ok: [serverd] ok: [serverf] ok: [serverb] ok: [servere] PLAY RECAP ********************************************************************************************************* servera : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 serverb : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 serverc : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 serverd : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 servere : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 serverf : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 Playbook run took 0 days 0 hours 0 minutes 1 seconds 统计Playbook执行性能(控制节点 CPU 和内存)

cgroup_perf_recap 插件可以分析playbook运行期间的控制节点性能。在playbook执行结束时,它将显示全局摘要和每个任务的摘要。这些摘要包括 CPU 和内存消耗,以及在 playbook 和 tasks 执行期间启动的进程 的最大数量。

来看下插件文档,= is mandatory修饰的变量为强制需要,所以我们还需要定义变量用于执行中那个控制组下执行

$ ansible-doc -t callback cgroup_perf_recap > CGROUP_PERF_RECAP (/usr/lib/python3.6/site-packages/ansible/plugins/callback/cgroup_perf_recap.py) This is an ansible callback plugin utilizes cgroups to profile system activity of ansible and individual tasks and display a recap at the end of the playbook execution * This module is maintained by The Ansible Community OPTIONS (= is mandatory): = control_group Name of cgroups control group set_via: env: - name: CGROUP_CONTROL_GROUP ini: - key: control_group section: callback_cgroup_perf_recap ......

cgroup_perf_recap CallBack插件依赖于 Linux 控制组(cgroup)功能来监控和分析 ansible-playbook命令。

在 Linux 系统上,可以使用控制组来限制和监控一组进程可以消耗的资源,如内存或 CPU。若要设置这些限值,可以创建⼀个新组,设置限值,然后将进程添加到该组中。

需要安装cgcreate所在的安装包

$ sudo yum provides */cgcreate Last metadata expiration check: 0:00:45 ago on Sun 14 Aug 2022 08:35:18 PM CST. libcgroup-tools-0.41-19.el8.x86_64 : Command-line utility programs services and daemons for libcgroup Repo : rhel-8.0-for-x86_64-baseos-rpms Matched from: Filename : /usr/bin/cgcreate $ yum -y install libcgroup-tools-0.41-19.el8.x86_64

使用 root 用户通过 cgcreate 命令创建专用控制组:

$ sudo cgcreate-a user:user-t user:user -g cpuacct memory pids:ansible_profile

$ sudo cgcreate -a student:student -t student:student -g cpuacct memory pids:ansible_profile [sudo] password for student:

  • -a 和 -t 选项显示可以访问和管理控制组的用户和组。
  • -g 选项指定新控制组的名称

下一步,是在ansible.cfg文件中启用插件:

[defaults] inventory=inventory remote_user=devops roles_path=roles gathering=explicit forks=10 callback_whitelist = cgroup_perf_recap [callback_cgroup_perf_recap] control_group=ansible_profile [privilege_escalation] become=True become_method=sudo become_user=root become_ask_pass=False

在新控制组中运行ansible-playbook命令:

$ ansible-playbook tags.yaml PLAY [tags Demo 1] *************************************************************************************** TASK [tag_role : tags roles] ***************************************************************************** changed: [servera] TASK [task 1 tag] **************************************************************************************** changed: [servera] TASK [include or import a tasks file] ******************************************************************* included: /home/student/DO447/labs/task-execution/tasks_file for servera TASK [task 1] ******************************************************************************************** changed: [servera] TASK [task 2] ******************************************************************************************** changed: [servera] TASK [task 1 in block] *********************************************************************************** changed: [servera] TASK [task 2 in block] *********************************************************************************** changed: [servera] PLAY [tags Demo 2] *************************************************************************************** TASK [task 2 tag] **************************************************************************************** changed: [servera] PLAY RECAP *********************************************************************************************** servera : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 CGROUP PERF RECAP **************************************************************************************** Memory Execution Maximum: 17.70MB cpu Execution Maximum: 0.00% pids Execution Maximum: 0.00 memory: tag_role : tags roles (52540000-fa09-85ab-8a5c-000000000010): 17.70MB task 1 tag (52540000-fa09-85ab-8a5c-000000000012): 17.70MB include or import a tasks file (52540000-fa09-85ab-8a5c-000000000013): 17.70MB task 1 (52540000-fa09-85ab-8a5c-000000000033): 17.70MB task 2 (52540000-fa09-85ab-8a5c-000000000034): 17.70MB task 1 in block (52540000-fa09-85ab-8a5c-000000000015): 17.70MB task 2 in block (52540000-fa09-85ab-8a5c-000000000016): 17.70MB task 2 tag (52540000-fa09-85ab-8a5c-000000000019): 17.70MB cpu: tag_role : tags roles (52540000-fa09-85ab-8a5c-000000000010): 0.00% task 1 tag (52540000-fa09-85ab-8a5c-000000000012): 0.00% include or import a tasks file (52540000-fa09-85ab-8a5c-000000000013): 0.00% task 1 (52540000-fa09-85ab-8a5c-000000000033): 0.00% task 2 (52540000-fa09-85ab-8a5c-000000000034): 0.00% task 1 in block (52540000-fa09-85ab-8a5c-000000000015): 0.00% task 2 in block (52540000-fa09-85ab-8a5c-000000000016): 0.00% task 2 tag (52540000-fa09-85ab-8a5c-000000000019): 0.00% pids: tag_role : tags roles (52540000-fa09-85ab-8a5c-000000000010): 0.00 task 1 tag (52540000-fa09-85ab-8a5c-000000000012): 0.00 include or import a tasks file (52540000-fa09-85ab-8a5c-000000000013): 0.00 task 1 (52540000-fa09-85ab-8a5c-000000000033): 0.00 task 2 (52540000-fa09-85ab-8a5c-000000000034): 0.00 task 1 in block (52540000-fa09-85ab-8a5c-000000000015): 0.00 task 2 in block (52540000-fa09-85ab-8a5c-000000000016): 0.00 task 2 tag (52540000-fa09-85ab-8a5c-000000000019): 0.00 $ 统计任务和角色阶段耗时

timer、profile_tasks 和 profile_roles CallBack插件可⽤于确定速度较慢的任务和角色。

  • timer 插件显示playbook执行的持续时间。
  • profile_tasks 添加每个任务的开始时间,并在 playbook 执行结束时显示每个任务所用的时间,按降序排列。
  • profile_roles 在结束时显示每个角色所用的时间,按降序排列。

激活这些插件需要在ansible.cfg文件中添加或更新callback_whitelist指令:

[defaults] inventory=inventory remote_user=devops roles_path=roles gathering=explicit forks=10 callback_whitelist = timer profile_roles profile_tasks [privilege_escalation] become=True become_method=sudo become_user=root become_ask_pass=False

执行的输出:

$ ansible-playbook tags.yaml PLAY [tags Demo 1] *************************************************************************************** TASK [tag_role : tags roles] ***************************************************************************** Monday 15 August 2022 23:46:17 0800 (0:00:00.021) 0:00:00.021 ********* Monday 15 August 2022 23:46:17 0800 (0:00:00.021) 0:00:00.021 ********* changed: [servera] TASK [task 1 tag] **************************************************************************************** Monday 15 August 2022 23:46:18 0800 (0:00:01.154) 0:00:01.176 ********* Monday 15 August 2022 23:46:18 0800 (0:00:01.154) 0:00:01.176 ********* changed: [servera] TASK [include or import a tasks file] ******************************************************************* Monday 15 August 2022 23:46:19 0800 (0:00:00.341) 0:00:01.518 ********* Monday 15 August 2022 23:46:19 0800 (0:00:00.341) 0:00:01.518 ********* included: /home/student/DO447/labs/task-execution/tasks_file for servera TASK [task 1] ******************************************************************************************** Monday 15 August 2022 23:46:19 0800 (0:00:00.018) 0:00:01.537 ********* Monday 15 August 2022 23:46:19 0800 (0:00:00.019) 0:00:01.537 ********* changed: [servera] TASK [task 2] ******************************************************************************************** Monday 15 August 2022 23:46:19 0800 (0:00:00.333) 0:00:01.871 ********* Monday 15 August 2022 23:46:19 0800 (0:00:00.333) 0:00:01.870 ********* changed: [servera] TASK [task 1 in block] *********************************************************************************** Monday 15 August 2022 23:46:19 0800 (0:00:00.345) 0:00:02.216 ********* Monday 15 August 2022 23:46:19 0800 (0:00:00.345) 0:00:02.216 ********* changed: [servera] TASK [task 2 in block] *********************************************************************************** Monday 15 August 2022 23:46:20 0800 (0:00:00.332) 0:00:02.548 ********* Monday 15 August 2022 23:46:20 0800 (0:00:00.332) 0:00:02.548 ********* changed: [servera] PLAY [tags Demo 2] *************************************************************************************** TASK [task 2 tag] **************************************************************************************** Monday 15 August 2022 23:46:20 0800 (0:00:00.344) 0:00:02.893 ********* Monday 15 August 2022 23:46:20 0800 (0:00:00.344) 0:00:02.893 ********* changed: [servera] PLAY RECAP *********************************************************************************************** servera : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 Monday 15 August 2022 23:46:20 0800 (0:00:00.348) 0:00:03.241 ********* =============================================================================== shell ------------------------------------------------------------------- 2.05s tag_role ---------------------------------------------------------------- 1.15s include_tasks ----------------------------------------------------------- 0.02s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ total ------------------------------------------------------------------- 3.22s Monday 15 August 2022 23:46:20 0800 (0:00:00.348) 0:00:03.241 ********* =============================================================================== tag_role : tags roles ----------------------------------------------------------------------------- 1.15s task 2 tag ---------------------------------------------------------------------------------------- 0.35s task 2 -------------------------------------------------------------------------------------------- 0.35s task 2 in block ----------------------------------------------------------------------------------- 0.34s task 1 tag ---------------------------------------------------------------------------------------- 0.34s task 1 -------------------------------------------------------------------------------------------- 0.33s task 1 in block ----------------------------------------------------------------------------------- 0.33s include or import a tasks file ------------------------------------------------------------------- 0.02s Playbook run took 0 days 0 hours 0 minutes 3 seconds $

我们可以在剧本输出中看到每个任务的执行时间。对于时间长的可以调整剧本优化,关于优化方式,小伙伴可以看看我之前的文章 关于其他的插件,小伙伴可以官网看看。具体的版本不同,插件使用方式略有差异。

自定义一个callBack插件

上面的都是社区或者官方的一些插件,下面我们看看如何自己编写一个插件

这里我们做一个简单Demo,所以这个插件的的功能就是在剧本执行完,在浏览器打开我的博客,…………

# -*- encoding: utf-8 -*- """ @File : disblog.py @Time : 2022/09/01 00:09:06 @Author : Li Ruilong @Version : 1.0 @Contact : 1224965096@qq.com @Desc : ansible callback plugins 执行完剧本浏览器打开我的博客 """ # here put the import lib from __future__ import (absolute_import division print_function) __metaclass__ = type DOCUMENTATION = ''' callback: disblog callback_type: aggregate requirements: - whitelist in configuration short_description: 执行完剧本浏览器打开我的博客 version_added: "2.0" description: - 执行完剧本浏览器打开我的博客 ''' from datetime import datetime import webbrowser from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): """ 执行完剧本浏览器打开我的博客 """ CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'aggregate' CALLBACK_NAME = 'disblog' CALLBACK_NEEDS_WHITELIST = True def __init__(self): super(CallbackModule self).__init__() def playbook_on_stats(self stats): webbrowser.open('https://liruilong.blog.csdn.net/');

放到:/usr/lib/python3.6/site-packages/ansible/plugins/callback/ 目录下

我们可以通过命令查看插件

$ ansible-doc -t callback -l | grep disblog disblog Adds time to play stats $ vim disblog.py $ ansible-doc -t callback -l | grep disblog disblog 执行完剧本浏览器打开我的博客

$ ansible-doc -t callback disblog > DISBLOG (/usr/lib/python3.6/site-packages/ansible/plugins/callback/disblog.py) 执行完剧本浏览器打开我的博客 * This module is maintained by The Ansible Community REQUIREMENTS: whitelist in configuration CALLBACK_TYPE: aggregate METADATA: status: - preview supported_by: community $

配置文件添加插件到白名单

[root@foundation0 resource_stat]# cat ansible.cfg [defaults] inventory = ./inventory remote_user = devops ask_pass = false callback_whitelist = disblog [privilege_escalation] become = false become_method = sudo become_user = root become_ask_pass = false [root@foundation0 resource_stat]#

在剧本执行完后,直接打开了我的博客主页,当前这里需要考虑启动级别

ansible操作方法(Ansible使用CallBack插件分析Playbook执行性能)(1)

博文参考

《Red Hat Ansible Engine 2.8 DO447》

猜您喜欢: