分类信息网站成都搭建,如何建立一个免费网站,竞价网络推广托管,手机端网站开发书籍不一样的Ansible——进阶学习 前言正文概念Ansible CorePlugins和Modules 插件插件类型编写自定义插件基本要求插件选项文档标准编写插件 添加一个本地插件注册为内置插件指定插件目录 其他一些技巧更改Strategy 结语 前言
Ansible 是一个极其简单的 IT 自动化引擎#xff0c… 不一样的Ansible——进阶学习 前言正文概念Ansible CorePlugins和Modules 插件插件类型编写自定义插件基本要求插件选项文档标准编写插件 添加一个本地插件注册为内置插件指定插件目录 其他一些技巧更改Strategy 结语 前言
Ansible 是一个极其简单的 IT 自动化引擎可自动执行云配置、配置管理、应用程序部署、服务内编排和许多其他 IT 需求基本上每一个运维工程师都会听过或者使用过Ansible这是必然的只要你需要管理超过2位数的服务器Ansible基本是一个必备的工具如果你还不知道Ansible是怎么用的一定要找一个环境试试这是一个真正让运维工作自动化并且事半功倍的工具。
Ansible不使用任何代理程序也就是不需要部署agent也不使用额外的自定义安全基础设施因此很容易部署 - 最重要的是使用yaml配置就能编写整个自动化流程不需要学习太多额外的编程知识。
这一部分的内容不是对Ansible做基本介绍的而是对其中一些进阶的或者平时不会知道的东西做一个学习和记录的。比如各种插件的特殊用法、如何在我们自己的Python程序中去使用Ansible、以及一些其他的技巧或者知识点。 本系列文章的所有内容基于Ansible 9编写Ansible 9使用Ansible-core 2.16 正文
概念
Ansible Core
Ansible Core或ansible-core是Ansible的主要构件和架构包含了许多的核心逻辑比如
CLI 工具如 ansible-playbook、ansible-doc 等用于驱动自动化并与之交互。Ansible 语言使用 YAML 创建一套用于开发 Ansible Playbook 的规则包括conditionals, blocks, includes, loops以及其他的一些内容。允许通过Ansible collections进行扩展的架构框架
总结来说Ansible Core提供你目前所熟知的所有Ansible的基础能力并且允许开发者在现有基础上拓展Ansible的功能。
Plugins和Modules
Ansible中非常重要的两个概念插件和模块那么他们有什么区别以及怎么在自己实现拓展功能的时候选择使用哪个特性
Plugins扩展了Ansible Core的功能。大多数插件都在/usr/bin/ansible进程的控制节点上执行。插件为Ansible的核心功能提供选项和扩展转换数据、记录输出、连接Inventory等Modules本质也是一种Plugins但是其特点在于能够在远程服务器上执行自动化任务。模块以独立脚本的形式运行由Ansible在控制节点之外的进程中执行。模块与Ansible的接口主要是 json接受参数并在退出前通过向stdout打印json字符串返回信息。与其他插件必须用 Python 编写不同模块可以用任何语言编写不过Ansible只提供Python和Powershell版本的模块。
这其实很好理解Plugins是用来添加Ansible的核心代码逻辑的因此需要Ansible能够把它加载进来Ansible既然是Python编写的自然也要求Plugins是要用Python编写而Modules是通过ssh分发到受管节点执行的那么他可以是任意程序只要远程服务器能够运行它就可以了默认Ansible的那些模块其实在受管节点也是调用了Python解释器来运行的
插件
插件类型
上面已经介绍了插件是什么在Ansible中有多种插件类型下面将官网的
Action pluginsAction与module一起执行playbook任务所需的动作通常在后台自动运行在模块实际运行前执行一些前期工作Become plugins用于执行命令时进行提权或者用户切换我们最常用的就是借助become完成sudo操作Cache pluginsCache插件允许Ansible存储收集到的受管节点信息或者inventory信息避免因为从源数据检索而影响性能这个最直观的体现就是我们执行playbook时如果没有关闭gather_fact可能会等待很长时间借助cache可以有效减少重复在受管节点执行操作时的这个步骤耗时Callback plugins回调插件可以在Ansible响应事件时添加新的行为。默认情况下回调插件可控制运行命令行程序时看到的大部分输出但也可用于添加额外输出、与其他工具集成以及将事件汇聚到存储后端对于想要对接Ansible做自动化管理的同学来说这个插件很重要Cliconf pluginsCliconf插件是网络设备CLI接口的抽象。它们为Ansible在这些网络设备上执行任务提供了标准接口主机维护不常用我也没用过Connection pluginsConnection插件允许Ansible使用既定方式连接到目标主机以便在上面执行任务Ansible自身附带了许多连接插件比如openssh和paramiko但每台主机一次只能使用一个Docs fragmentsDocs fragments可让使用者在一个地方记录多个插件或模块的通用参数Filter pluginsFilter插件也是一个功能常用的插件他允许对数据进行特定的序列化或者其他自定义的处理比如对字符串进行拆分和连接默认Ansible使用的是jinja2提供的标准Filter功能同时增加了一些特性Httpapi pluginsHttpapi 插件告诉Ansible如何与远程设备基于HTTP的API交互并在设备上执行任务Inventory pluginsInventory插件是一个允许用户指向仓库数据源的插件也就是我们执行ad-hoc命令式的-i参数执行的逻辑Lookup pluginsLookup插件是Jinja2模板语言的Ansible特定扩展。用户可以使用该插件从外部来源文件、数据库、key/value存储、API 和其他服务访问playbook中的数据。与所有模板一样Lookup在 Ansible 控制节点上运行。Ansible使用标准模板系统提供查找插件返回的数据。你可以使用查找插件从外部资源加载变量或模板信息。Modules上文说过Modules也是一种插件所以这里也有它Module utilities包含多个插件使用的共享代码最好把它和Modules一起理解Netconf plugins网络设备Netconf接口抽象用于在网络设备上执行ansible任务Shell pluginsShell插件的作用是确保Ansible运行的基本命令格式正确能够在目标计算机上运行并允许用户配置与Ansible执行任务方式相关的某些行为具体的情况可以跳转到Strategy pluginsStrategy通过handles和受管节点的调度来控制playbook的执行流程具体的策略可以查看更改StrategyTerminal pluginsTerminal插件包含有关如何正确初始化特定网络设备的SSH shell以配合Ansible使用的信息。这通常包括禁用自动分页、检测输出中的错误以及在设备支持和需要的情况下启用特权模式。Test pluginsTest插件可评估模板表达式并返回True或False。有了测试插件用户就可以创建条件比如when关键字来实现tasks、blocks、play、playbooks和roles的逻辑。Ansible使用作为Jinja一部分提供的标准测试并添加了一些专门的测试插件Vars pluginsVars插件拓展了一些变量的使用方式
上面所说的插件其中一部分Action、Cache、Callback、Connection、Filter、Inventory、Lookup、Test、Vars支持开发者进行自定义的编写实现新的功能。
编写自定义插件
基本要求
让我们先来编写一个自定义的插件来为Ansible提供额外的核心能力编写之前我们要知道一个Ansible插件必须要满足的条件
使用Python编写这个在上一节已经说明原因对异常进行合适的处理使用raise抛出异常返回值要是unicode编码的字符串符合Ansible的配置和文档标准
接下来针对上面的要求做一下分别的解释
使用Python编写
使用Python编写插件这样它才能被PluginLoader加载并作为任何模块都能使用的Python对象返回。由于插件将在控制节点上执行因此必须使用兼容的 Python 版本编写插件
使用raise处理异常
在插件执行过程中遇到错误时应通过引发AnsibleError()或类似类来返回错误信息。在将其他异常包装成错误信息时应始终使用to_nativeAnsible函数以确保不同Python版本的字符串兼容下面是一个简单的样例
from ansible.module_utils.common.text.converters import to_nativetry:cause_an_exception()
except Exception as e:raise AnsibleError(Something happened, this was original exception: %s % to_native(e))由于Ansible仅在需要时才会对变量进行解析因此filter插件和test插件应使用jinja2.exceptions.UndefinedError和AnsibleUndefinedVariable异常以确保未定义变量仅在必要时才引起程序的Fatal
返回值符合unicode编码
这个要求是为了保证过程中的字符串str能够在Jinja2中正常运行和解析Ansible提供了响应的方法进行转换
from ansible.module_utils.common.text.converters import to_text
result_string to_text(result_string)插件选项
为了给我们自己的插件定义可配置选项我们需要在Python文件的DOCUMENTATION部分进行描述和声明这种规范可以确保我们插件响应选项的文档时钟保持正确和最新以下是格式定义
options:option_name:description: describe this config optiondefault: default value for this config optionenv:- name: NAME_OF_ENV_VARini:- section: section_of_ansible.cfg_where_this_config_option_is_definedkey: key_used_in_ansible.cfgvars:- name: name_of_ansible_var- name: name_of_second_varversion_added: X.xrequired: True/Falsetype: boolean/float/integer/list/none/path/pathlist/pathspec/string/tmppathversion_added: X.x我们来看一个样例这里以自带的Callback插件中的json.py演示
# (c) 2016, Matt Martz mattsivel.net
# (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__ typeDOCUMENTATION callback: jsonshort_description: Ansible screen output as JSONversion_added: 2.2description:- This callback converts all events into JSON output to stdouttype: stdoutrequirements:- Set as stdout in configoptions:show_custom_stats:version_added: 2.6name: Show custom statsdescription: This adds the custom stats set via the set_stats plugin to the play recapdefault: Falseenv:- name: ANSIBLE_SHOW_CUSTOM_STATSini:- key: show_custom_statssection: defaultstype: boolnotes:- When using a strategy such as free, host_pinned, or a custom strategy, host results willbe added to new task results in .plays[].tasks[]. As such, there will exist duplicatetask objects indicated by duplicate task IDs at .plays[].tasks[].task.id, each with anindividual host result for the task.ok现在假设我们设定好了自己的配置项如果要在插件内部使用对应的配置项一般使用self.get_option(option_name)进行获取不过有些插件的处理方式会有些不同
配置部分遵循了Ansible中值的优先原则当在同一个类别下定义多个值时最后一个值优先比如上述样例的这部分 vars:- name: name_of_ansible_var- name: name_of_second_var此时option_name选项的值使用name_of_second_var如果要对option值进行设置则要使用self.set_option()方法
文档标准
支持嵌入式文档参见 ansible-doc 列表的插件应包含格式良好的文档字符串如果我们继承一个插件则必须在文档中记录被继承插件的选项
编写插件
以Action plugin为例编写一个插件首先编写的插件应该继承自对应的Base类比如
from ansible.plugins.action import ActionBaseclass ActionModule(ActionBase):pass允许使用_execute_module方法来调用内置的Module并获取返回结果
module_return self._execute_module(module_nameNAME_OF_MODULE,module_argsmodule_args,task_varstask_vars, tmptmp)我们以官方文档中的示例为准进行讲解这里添加了一个通过setup模块获取的内容进行服务器时间差异的比对动作的action
from __future__ import (absolute_import, division, print_function)
__metaclass__ typefrom datetime import datetime
from ansible.plugins.action import ActionBaseclass ActionModule(ActionBase):Actiondef run(self, tmpNone, task_varsNone):super().run(tmp, task_vars)module_args self._task.args.copy()module_return self._execute_module(module_namesetup,module_argsmodule_args,task_varstask_vars, tmptmp)ret {}remote_date Noneif not module_return.get(failed):for key, value in module_return[ansible_facts].items():if key ansible_date_time:remote_date value[iso8601]if remote_date:remote_date_obj datetime.strptime(remote_date, %Y-%m-%dT%H:%M:%SZ)time_delta datetime.utcnow() - remote_date_objret[delta_seconds] time_delta.secondsret[delta_days] time_delta.daysret[delta_microseconds] time_delta.microsecondsreturn {ansible_facts: dict(ret)}
在上述代码中调用了内部的setup模块拉取受管节点的信息在其返回值中有这样的数据结构 ansible_date_time: {date: 2024-01-08,day: 08,epoch: 1704704528,epoch_int: 1704704528,hour: 17,iso8601: 2024-01-08T09:02:08Z,iso8601_basic: 20240108T170208306063,iso8601_basic_short: 20240108T170208,iso8601_micro: 2024-01-08T09:02:08.306063Z,minute: 02,month: 01,second: 08,time: 17:02:08,tz: CST,tz_dst: CST,tz_offset: 0800,weekday: Monday,weekday_number: 1,weeknumber: 02,year: 2024},随后在自定义插件逻辑中我们比对了iso8061的值计算出时间的差异值然后返回这个插件的返回值类似以下的格式
172.18.0.25 | SUCCESS {ansible_facts: {delta_days: 0,delta_microseconds: 152565,delta_seconds: 0},changed: false
}如果想要进一步修改插件满足自己的需求只需要在刚才编写的ActionModule中进行变更即可。
添加一个本地插件
上面我们已经编写了一个自定义的插件但是只是把代码写好是没法按照预期的方式通过ad-hoc的方式使用的大概率会出现以下的报错
172.18.0.25 | FAILED! {msg: The module myaction was not found in configured module paths
}而想要直接便利的使用自定义的插件有以下几种方式进行配置
注册为内置插件
这种方法不建议只做介绍直接将编写好的python文件拷贝到ansible的安装目录下比如我们使用虚拟环境通过pip安装的ansible那么我们的ansible安装目录ANSIBLE_INSTALL_DIR大概是这样的$ENV_HOME/lib/python3.9/site-packages/ansible那么只需要把我们的插件放在$ANSIBLE_INSTALL_DIR/plugins/目录下对应的插件类型下 不建议使用这种方法的原因主要是因为我们个人编写的代码在规范性上和官方的多少有些差异最好还是做一些区分这样在出问题的时候排查也会变得容易一些 指定插件目录
这个方式是比较规范的当我们编写的插件是一个提供给全局使用的插件时我们就这样做就可以了编辑ansible的配置文件/etc/ansible/ansible.cfg添加action_plugins配置项
[defaults]
# ...
# 可以自定义为自己需要的目录
action_plugins /usr/share/ansible/plugins/action 然后把我们的插件放在上面配置的目录下就能正常使用了 这种配置便于我们对插件进行管理且配置一次后所有人都能使用 除此之外插件也可以放在Collection中这个在讲到Collection时再单独写
其他一些技巧
更改Strategy
默认情况下Ansible使用linear strategy进行任务的调度除此之外Ansible还提供了以下集中Strategy plugins
debug strategy – 在debug模式下运行Task.free strategy – 不等待其他受管节点完成当前状态直接运行Taskhost_pinned strategy – 尽可能快的在每个受管节点执行play按照serial定义的批次执行默认为全部除非一个play可以在不被其他主机Task中断的情况下完成否则Ansible不会给一个新的主机启动play即拥有执行中的play的受管节点数量不超过forks规定的数量linear strategy – 默认的策略线性执行这个线性是指Task也是我们熟知的一个 Task会在所有服务器执行完后再执行下一个Task
假设我们希望每个节点都能速度拉满我们可以把策略改成free通过在playbook中指定或者更改配置文件都可以实现先看更改playbook
- hosts: allstrategy: freetasks:# ...或者更改ansible.cfg
[defaults]
strategy free结语
本篇文章主要抛砖引玉说明了Ansible中模块和插件的区别以及如何自己编写一个简单的Action Ansible插件接下来会再多讲解一些其他类型的插件编写方法。 文章转载自: http://www.morning.lpzqd.cn.gov.cn.lpzqd.cn http://www.morning.xckdn.cn.gov.cn.xckdn.cn http://www.morning.cknws.cn.gov.cn.cknws.cn http://www.morning.phechi.com.gov.cn.phechi.com http://www.morning.dfffm.cn.gov.cn.dfffm.cn http://www.morning.rtlrz.cn.gov.cn.rtlrz.cn http://www.morning.mjzgg.cn.gov.cn.mjzgg.cn http://www.morning.woyoua.com.gov.cn.woyoua.com http://www.morning.mnqz.cn.gov.cn.mnqz.cn http://www.morning.mrcpy.cn.gov.cn.mrcpy.cn http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn http://www.morning.jltmb.cn.gov.cn.jltmb.cn http://www.morning.hkpyp.cn.gov.cn.hkpyp.cn http://www.morning.dkbsq.cn.gov.cn.dkbsq.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.cfcdr.cn.gov.cn.cfcdr.cn http://www.morning.yqsq.cn.gov.cn.yqsq.cn http://www.morning.qbkw.cn.gov.cn.qbkw.cn http://www.morning.rbbyd.cn.gov.cn.rbbyd.cn http://www.morning.yqsr.cn.gov.cn.yqsr.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.hpjpy.cn.gov.cn.hpjpy.cn http://www.morning.tfrlj.cn.gov.cn.tfrlj.cn http://www.morning.qnyf.cn.gov.cn.qnyf.cn http://www.morning.wdjcr.cn.gov.cn.wdjcr.cn http://www.morning.bpmdx.cn.gov.cn.bpmdx.cn http://www.morning.lqklf.cn.gov.cn.lqklf.cn http://www.morning.mqfw.cn.gov.cn.mqfw.cn http://www.morning.dpplr.cn.gov.cn.dpplr.cn http://www.morning.msgnx.cn.gov.cn.msgnx.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn http://www.morning.bcjbm.cn.gov.cn.bcjbm.cn http://www.morning.srgyj.cn.gov.cn.srgyj.cn http://www.morning.ndxss.cn.gov.cn.ndxss.cn http://www.morning.burpgr.cn.gov.cn.burpgr.cn http://www.morning.qpsft.cn.gov.cn.qpsft.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.xnnxp.cn.gov.cn.xnnxp.cn http://www.morning.lfpzs.cn.gov.cn.lfpzs.cn http://www.morning.xjmpg.cn.gov.cn.xjmpg.cn http://www.morning.snxbf.cn.gov.cn.snxbf.cn http://www.morning.lmyq.cn.gov.cn.lmyq.cn http://www.morning.qnftc.cn.gov.cn.qnftc.cn http://www.morning.kbqws.cn.gov.cn.kbqws.cn http://www.morning.drywd.cn.gov.cn.drywd.cn http://www.morning.sbdqy.cn.gov.cn.sbdqy.cn http://www.morning.wkrkb.cn.gov.cn.wkrkb.cn http://www.morning.bmqls.cn.gov.cn.bmqls.cn http://www.morning.hhpbj.cn.gov.cn.hhpbj.cn http://www.morning.nhrkl.cn.gov.cn.nhrkl.cn http://www.morning.lynkz.cn.gov.cn.lynkz.cn http://www.morning.rwpfb.cn.gov.cn.rwpfb.cn http://www.morning.mngyb.cn.gov.cn.mngyb.cn http://www.morning.qmpbs.cn.gov.cn.qmpbs.cn http://www.morning.jppb.cn.gov.cn.jppb.cn http://www.morning.rjmb.cn.gov.cn.rjmb.cn http://www.morning.nbpqx.cn.gov.cn.nbpqx.cn http://www.morning.smkxm.cn.gov.cn.smkxm.cn http://www.morning.rsjng.cn.gov.cn.rsjng.cn http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.tdttz.cn.gov.cn.tdttz.cn http://www.morning.qrsm.cn.gov.cn.qrsm.cn http://www.morning.lzwfg.cn.gov.cn.lzwfg.cn http://www.morning.ttshf.cn.gov.cn.ttshf.cn http://www.morning.xmpbh.cn.gov.cn.xmpbh.cn http://www.morning.spbp.cn.gov.cn.spbp.cn http://www.morning.rszwc.cn.gov.cn.rszwc.cn http://www.morning.xpwdf.cn.gov.cn.xpwdf.cn http://www.morning.xpgwz.cn.gov.cn.xpgwz.cn http://www.morning.gkdhf.cn.gov.cn.gkdhf.cn http://www.morning.rnxw.cn.gov.cn.rnxw.cn http://www.morning.fhtbk.cn.gov.cn.fhtbk.cn http://www.morning.gfmpk.cn.gov.cn.gfmpk.cn http://www.morning.gmmxh.cn.gov.cn.gmmxh.cn http://www.morning.jgcrr.cn.gov.cn.jgcrr.cn http://www.morning.qncqd.cn.gov.cn.qncqd.cn http://www.morning.sbrrf.cn.gov.cn.sbrrf.cn http://www.morning.qhfdl.cn.gov.cn.qhfdl.cn http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn