没有合适的资源?快使用搜索试试~ 我知道了~
首页Ansible运维管理平台部署、维护与调优之详解
Ansible运维管理平台是一种开源的自动化运维管理软件,它基于OpenSSH,具有简单易用的特点,可以用于系统配置、软件部署和高级IT任务编排。在《Ansible运维管理平台部署、维护与调优.pdf》这本教程中,作者详细介绍了Ansible的软件架构、管理方式和系统架构,并与其他主流的开源自动化运维软件进行了对比和优缺点分析。
在本教程中,作者首先介绍了Ansible的价值和学习目标。通过学习本章节,读者可以了解到Ansible的软件架构模式,包括控制机和被管机,控制机是安装和执行维护指令的服务器或工作站,被管机是运行业务服务的服务器。
接着,作者详细介绍了Ansible的功能特性。首先,Ansible具有简单易用的特点,无需在被管机上安装客户端,只需在控制机上安装Ansible工具软件即可进行管理操作。其次,Ansible支持多种操作系统,包括各种Linux发行版、Windows和UNIX等。此外,Ansible还提供了丰富的模块和插件,可以满足各种不同的运维需求。另外,Ansible还支持多种配置管理工具和云平台,能够与其他工具和平台进行无缝集成。此外,Ansible还提供了强大的扩展性和灵活性,可以根据具体需求进行定制和扩展。最后,Ansible还具有高度的安全性和可靠性,能够保护用户的数据和系统的稳定性。
在本教程的后续内容中,作者详细讲解了Ansible的安装和配置过程,以及常用的操作和命令。作者还介绍了Ansible的剧本(playbook)和角色(role)的概念,以及如何使用它们进行任务编排和自动化运维管理。此外,作者还介绍了Ansible的高级特性,包括主机动态管理、变量和模板、错误处理和日志记录等。最后,作者还讲解了Ansible的调优技巧和最佳实践,以提高系统的性能和稳定性。
在本教程的最后一部分,作者对比了Ansible与其他主流的开源自动化运维软件,包括SaltStack、Puppet和Chef,并分析了它们的优缺点。通过比较,读者可以了解不同软件的特点和适用场景,以便选择合适的工具进行运维管理。
综上所述,《Ansible运维管理平台部署、维护与调优.pdf》是一本详细介绍Ansible运维管理平台的教程,涵盖了软件架构、功能特性、安装配置、常用操作、任务编排和调优技巧等内容。通过学习本教程,读者可以全面了解Ansible的使用和优势,并掌握在实际工作中使用Ansible进行运维管理的技能。无论是开发人员、系统管理员还是IT经理,都可以从本教程中获得实际帮助和价值。
1 Ansible软件简介
1.1 本章价值
通过本章节,您将学习到Ansible的软件架构模式、管理方式和系统架构等内容,同时您将了解到Ansi-
ble的六大功能特性,和其他主流的开源自动化运维软件的对比,与优缺点分析等。
1.2 Ansible软件架构
Ansible是一个开源的基于OpenSSH的自动化运维管理软件。可以用它来配置系统、部署软件和编排更
高级的IT任务,比如持续部署或零停机更新。Ansible的主要目标是简单和易用,并且它还高度关注安全性和
可靠性。基于这样的目标,Ansible适用于开发人员、系统管理员、发布工程师、IT经理,以及介于两者之间
的所有人。Ansible适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。
Ansible软件架构模式通常由控制机和被管机组成,控制机是用来安装Ansible工具软件、执行维护指令
的服务器或工作站,也称之为Ansible服务端,它是Ansible维护的核心。被管机是运行业务服务的服务器,
也称为Ansible客户端,由控制机通过SSH来进行管理。
Ansible管理方式
Ansible是一个模型驱动的配置管理器,支持多节点发布、远程任务执行,默认使用SSH进行远程连接。
无需在被管节点上安装附加软件,可使用各种编程语言进行扩展。Ansible管理系统由控制主机和一组被管
节点组成,控制主机直接通过SSH控制被管节点,被管节点通过Ansible的资源清单来进行分组管理。
Ansible系统架构
Ansible集合了众多优秀运维工具(Puppet、Cfengine、Chef、Fune、Fabric)的优点,实现了批量系
统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作的,本身没有批量部署的能力。真
正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。Ansible的系统架构见下图,用户可
以通过Ansible编排引擎操作公有云/私有云或CMDB(配置管理数据库)中的主机。从图中可以看到,Ansi-
ble由以下各部分组成:
核心引擎:即Ansible。
核心模块(Core Modules):这些都是Ansible自带的模块,Ansible 模块资源分发到远程节点使其执行
特定任务或匹配一个特定的状态。Ansible遵循“Batteries Included“哲学,所以你可以有各种各样任务的核心
模块。这意味着模块是最新的,你不需要寻找一个在你平台上工作的实现。你可以认为模块库的工具箱里充
满了有用的系统管理工具,和Playbook一起构建自动化运维系统的基础源材料。
白定义模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加自定义模块。
插件(Plugins):完成模块功能的补充,借助于插件完成记录日志、邮件等功能。
剧本(Playbook):定义Ansible任务的配置文件,可以将多个任务定义在一个剧本中,由 Ansible自动
执行,剧本执行支持多个任务,可以由控制主机运行多个任务,同时对多台远程主机进行管理。Playbook是
Ansible的配置、部署和编排语言,可以描述一个你想要的远程系统执行策略,或一组步骤的一般过程。如
果Ansible模块作为你的工作室工具,PlayBook则是你的设计方案。在基本层面上,剧本可用于管理配置和
部署远程机器。在更高级的应用中,可以序列多层应用及滚动更新,并可以把动作委托给其他主机,与监控
服务器和负载平衡器交互。
连接插件(Connectior Plugins) : Ansible基于连接插件连接到各个主机上,负责和被管节点实现通信。
虽然Ansible是使用SSH连接到各被管节点,但它还支持其他的连接方法,所以需要有连接插件。
主机清单(Host Inventory):定义Ansible管理的主机策略,默认是在Ansible Hosts配置文件中定义被
管节点,同时也支持自定义动态主机清单和指定配置文件的位置。
1.3 Ansible软件特性
Ansible是基于一致性、安全性、高可靠性设计的轻量级自动化工具,具有功能强大、部署便捷、描述
清晰等特性。对于管理员、开发者、IT经理等都容易上手,学习曲线较低,能够快速理解、掌握 Ansible的
自动化体系,满足不同技术级别的用户需求。同时Ansible 是一款满足当代大规模、复杂环境的IT基础架构
自动化管理的工具。
Ansible相对与其他自动化解决方案,在核心能力上效率更高。也很好地解决了统一配置、统一部署、
流程编排等复杂的IT自动化管理问题。下面就介绍其功能特性以及与其他工具的对比。
Ansible功能特性
从功能上看,Ansible可以实现以下目标:
应用代码自动化部署。
系统管理配置自动化。
支持持续交付自动化。
支持云计算、大数据平台(如AWS、OpenStack、CloudStack、VMWare等)环境。
轻量级,无需在客户端安装Agent,更新时只需在控制机上进行一次更新即可。
批量任务执行可以写成脚本,不用分发到远程就可以执行。
使用Python编写,维护更简单,而Ruby语法过于复杂。
支持非root用户管理操作,支持sudo。
实现上述目标是很有挑战性的工作,需要满足健壮性、易于管理的架构,这在应用维度一直没能很好地
解决,因为管理工具不能对被管环境施加额外的影响,而Ansible很好地解决了这些问题。Ansible作为优秀
管理工具具备以下一些特点:
1.语法简单、易读
Ansible的配置管理脚本Playbook语法基于YAML,它是一种可读性高、用来表达数据序列的格式标准。
YAML参考了XML、C、Python、Perl以及电子邮件格式RFC2822等其他多种语言,可读性好、交互性强,
使用了实现语言的数据类型,有一个一致的信息模型,可以基于流方式来处理,具有表达能力强、扩展性好
等特点。可以把Playbook称为“可执行的文档”,就像README文件一样描述你需要部署软件的指令,由于这
些代码是可以直接执行的,这些指令永远不会过时。
2.不需要在被管节点安装客户端软件
Ansible运维管理系统的核心是通过 SSH来连接被管节点,可以使用Paramiko(一个Python库)或使用
原生的OpenSSH(带参数-c ssh)。当使用SSH客户端连接的时候,默认的OpenSSH连接是可以重用的。无
论哪种方式,SSH都是作为一种传输方式,不是作为一种执行的Shell。
Ansible模块是包含一些参数的Ansible小程序,通过SCP或SFTP传送到远端被管机器的临时目录中进行
执行,然后再删除。这些模块通过标准的输出方式返回JSON格式的数据,这些返回的数据通过控制主机上
的Ansible程序进行处理。这种方式能管理非常多远程活动,并且只需要很小的交互流量。模块按照“幕等资
源”的方式进行管理,也就是发起多次执行也不会给服务带来负面响应。它不是简单的命令或脚本,例如一
个模块可以确定应该安装某个特定版本的软件包,但如果这个系统已经有合适的工作状态,就不会再执行任
何命令。这种方式有如下优点:
提高网络安全:由于不需要在远端被管节点上运行Agent,因此 Ansible遭受攻击的机会很少。只需要运
行OpenSSH一个后台进程,OpenSSH在全球范围内是最严格审查的程序之一。Ansible知道做好加密是一项
极其艰难的事情,因此没有考虑使用自己的后台进程和认证方式,而是依赖可用的最安全的远程管理方式。
OpenSSH极其广泛地在各种系统中使用,属于非常轻量级。一旦Open SSH出现安全问题,将会非常快速地
推出补丁修复。
可以使用非root用户访问(可用sudo) : Ansible Playbook能够用任何用户账号登录远程系统,可以用初
始连接的用户来运行程序,也可以使用sudo切换到其他用户(包括root)。如果需要,可以直接用root登
录,sudo可以需要口令,也可以不需要口令,当管理的一些系统根本不能使用root登录的时候,或者不允
root登录但可以通过sudo切换到root的,这种方式是非常合适的。
限制传输潜在敏感数据:Ansible总是尽量把最少的数据传输到被管节点,由于控制服务器是逻辑控制
中心,只有远端被管节点必要的变量才送给它。例如,有个全局变量叫foo,只有在远端被管节点中明确在
资源或模板中使用它,否则它不会发送到该远端节点。这种Ansible的推送方式,只给远端节点需要看到的
最少数据。类似地,Ansible没有包含客户文件服务器的实现,只通过SFTP、SCP、Rsync(基于SSH)传
输文件,并且只有Playbook需要的文件才传输。结果是被管节点请求的文件或模板可以提供,但敏感数据不
会提供给。也就是不能给一台远程主机查看将要提供给其他被管节点的数据。这使得Ansible适用于带有敏
感数据的环境,包括社会科学工作、健康医疗、政府政务等应用。
(Credential Segregation凭证隔离): Ansible适用于不同用户有不同安全级别的环境。可以定义管理主
机的通用变量,然后使用自己的凭证访问远端节点。例如,允许研发工程师管理开发的服务器,QA工程师
管理QA的服务器,系统管理员管理生产环境服务器,不存在研发工程师把代码推送到生产环境的风险。
去中心化:由于Ansible Playbook需要用户的凭证来执行,不存在中心点,只是通过访问配置内容、管
理软件链条,不需要访问SSH密钥,就可以接管建立“僵死网络”,避免使它成为攻击的目标。用户可以加
密自己的密钥,不需与任何人使用相同密码。在可选的管理形式中,访问授权的软件资源都有可能导致部
署系统自动化。要使用Ansible,用户需要两个条件:能够访问到资源库,具有管理远端节点的凭证。当使
用锁定的密钥(甚至是密码)时,不存在暴露安全漏洞中心被攻击点,也不允许从远端硬件来访问管理服
务器。
没有“管理的管理程序”的问题:许多配置管理解决方案的主要问题之一是“管理的管理”,为了开始管
理服务器必须先在远端节点上安装软件。当更新管理软件的时候,通常各种Agent需要先更新(许多系统是
无法自己自动更新的)。有时会产生管理服务器与Agent软件版本兼容性问题,或Agent与运行语言版本问
题,Ansible通过基于SSH传输模块避免了这类问题。SSH二进制代码已经是OS的一部分了,并且是每个主
流操作系统的核心。不需要任何Agent,也就不存在Agent以任何方式崩溃的问题,因此服务器存在的安全
风险是非常小的。
管理服务器的可扩展性:由于Ansible使用推送方式来管理远端节点(当然,也很容易配置成远端节点
查询更新的方式),因此Ansible对于“羊群效应”的管理问题是有免疫能力的。在其他的一些解决方案中,
管理Agent周期性检查会对管理服务造成破坏,经常会超过管理服务器的运行负荷,导致需要对管理服务器
进行横向或纵向扩展。频繁管理服务器需要为远端节点消耗昂贵的计算资源。为了解决这个问题,Ansible
通过推送的方式,通过配置每次推送节点数量来做限制。均衡了远程节点需要的管理服务器的负载能力,可
以让计算系统负载更加均衡,即使个人笔记本电脑也可以作为Ansible系统的控制服务器。
资源的利用:在Ansible不管理远端节点时,这些远端节点什么也不做,也就是没有后台进程在消耗
CPU、内存。曾经报道过,某些应用服务器在唤醒配置窗口时会产生明显的降低性能,某些 Agent可能会占
用超过400MB的内存。在虚拟化环境中,这些资源的消耗可能会快速叠加,就会增加对硬件的支出。Ansi-
ble能最大限度让你的关键性能负荷使用所有的计算资源,你也可以选用间隔方式运行管理程序,也不存在
由于内存泄漏或Agent软件崩溃导致无法管理远端节点的问题。
防火墙的友好性和确定性:不像某些基于消息总线的系统,Ansible不需要长时间在控制节点与被管主机
之间建立连接。在生产环境,这种长连接可能受限于防火墙,防火墙一般不喜欢长连接,Ansible很好地规避
了这个问题。当管理服务与应用之间的连接被断开又没法重置的时候,就只能等到重启Agent端服务了,
Ansible没有这个问题。没有严格意义上的无代理系统,Ansible也避免在这些架构中的其他问题,获得确定
性的响应。并不是只有出现响应节点才管理,对于你要管理但无法达到的就静默了。如果一个节点宕机,运
行Ansible时你就会知道,将会返回一个失效信息,这个你可能忽略或修复。这对于你给所有节点或部分子
集部署软件更新,是很重要的信息,知道哪些节点无法连接是非常重要的。
3.基于推送(Push)方式
有些运维管理工具(如Chef、Puppet、Saltstack等)是使用代理模式的,它们默认基于拉(Pull)方
式。被管节点上安装代理后,代理服务将周期性检查中心控制主机的服务,并从控制主机上取来配置信息。
被管节点的变更过程大致如下:
修改配置管理脚本。
把修改好的管理配置脚本推送到中心控制主机上。
被管节点的代理服务周期性触发检查。
被管节点连接配置管理的控制主机。
被管节点下载新的配置管理脚本。
被管节点在本地执行配置管理脚本,被管节点状态相应地变化。
而Ansible默认基于推送(Push)方式,管理过程如下:
增加或修改Playbook。
执行新的Playbook。
控制节点的Ansible连接被管节点并执行修改被管节点状态的模块。
一旦你执行ansible-playbook命令,Ansible就会连接到远程的被管节点并按照脚本要求执行。基于推送
方式有很大的优势,你能控制什么时候让远程被管节点发生变更,不需要等到被管节点上周期性的时间。拉
方式的支持者声称拉方式具有管理服务器规模数量的优势,新被管节点随时可以在线添加。但是Ansible已经
在管理超过上万台节点规模的系统,很方便地动态增减或删除被管节点。当然,如果你一定要使用拉方式,
Ansible官方也已经支持这种拉方式,可以使用ansible-pull这个工具。
4.方便管理小规模场景
Ansible能够管理成千上万台主机,但如何管理缩小规模的场景呢?其实,用Ansible也很容易配置小规
模集群甚至单台主机,你只要简单编写一个Playbook即可。
5.大量内置模块
使用Ansible能够在被管节点上执行任何Shell命令,但是 Ansible真正的威力在于内置大量的模块。使用这
些模块可以完成如软件包安装、重启服务、拷贝配置文件等操作。Ansible模块是声明式的(Declarative),
你只需使用这些模块描述被管节点期望达到的状态。例如,你可以用user模块对用户授权,确保系统有一个
deploy用户,并且属于web组,代码如下:user: name=deploy group=web
Ansible内置模块都是等幕性的(Idempotent)。这就是如果系统中没有用户deploy, Ansible将会创建一
个deploy账号;如果这个账号已经存在,则Ansible什么也不做。等幕性对于自动化维护是非常重要的特性,
这样在被管节点上多次执行AnsiblePlaybook 也能达到同样效果。相对于直接执行操作系统脚本的方式是巨
大的改进,操作系统脚本再执行一次可能就会产生不同的、非预期的结果。
6.非常轻量级的抽象层
有些配置管理工具通过一个抽象层,可以把相同的脚本在不同的操作系统上管理。例如,安装软件包有
yum、apt工具,对于配置管理工具就可能抽象成package。Ansible不同于这种方式,你需要使用apt模块来
安装基于apt软件管理的系统,用yum模块来安装基于 yum软件管理的系统。这听起来也许不太方便,在实
践中我们发现这使得Ansible更方便使用。Ansible不需要再学新知识来屏蔽不同操作系统的差异性、新的抽
象环境。这相对减少了Ansible要求的知识领域。这样,你不需要了解太多就可以编写Playbook了。如果你
确实需要,你也可以在Ansible Playbook中对不同被管节点的操作系统编写不同的动作脚本。但不太建议这
么做,建议编写针对特定操作系统的Playbook,如CentOS、Ubuntu。
1.4 Ansible与其他运维管理工具的对比
当前几款与Ansible功能类似的主流配置管理软件有Chef、Puppet、SaltStack等,这里只对各个软件的
技术特性做个简单对比,其中不针对各个软件的性能作比较。具体内容见下表:
与其他的自动化工具相比较,Ansible不需要安装管理客户端就能轻松地管理、配置你的基础架构。它
们各自的优缺点见下表所示:
这些自动化管理软件都具备强大的功能、灵活的系统管理和状态配置,都提供丰富的模板及API,对云
计算平台、大数据都有很好的支持。Puppet、Chef、SaltStack设置比较复杂,有代理和服务,有远程被管
节点需要长期运行管理进程,而且很多术语和概念都是自己一套。Ansible相对于其他产品要简单得多,本
质上混合了声明式和命令式。不仅适用于大规模的IT环境,而且对于一些规模较小的环境(20-50台机器)
Ansible也是很实用的。
2 Ansible软件部署与配置
2.1 本章价值
通过本章节,您将学习到如何通过安装包的方式安装Ansible软件(YUM源配置,依赖模块及安装包安
装),配置Ansible相关参数,建立Ansible服务端与客户端互信,进行必要的Ansible服务端与客户端连通性
测试,极快速地搭建一整套基于Ansible的自动化运维环境。另外,对于客户端Python版本不符合要求的,
本章节也将介绍如何快速批量完成安装。
2.2 Ansible软件安装
Ansible软件安装的方式较多,非常灵活,可以满足各种环境的部署需求。一般可以直接用源码进行安
装,包括从GitHub源码库安装方式、TAR包安装、制作RPM包安装等。也可用操作系统软件包管理工具进
行安装,包括YUM安装(适合Fedora、RHEL、CentOS)、APT安装(适合Ubuntu)、Homebrew安装(适
合Mac OS X)、PIP安装等。其中大部分安装方式需要服务端连通公网,下面不一一介绍,仅详细介绍如
何在生产环境,无法连接外部互联网的条件下,通过TAR包的安装方式,快速搭建Ansible整套环境,包含
一套Ansible服务端和千余个生产环境Ansible客户端环境。整个搭建耗时约1-2天。下面演示的服务端操作
系统版本为RHEL6.6x86_64,该操作系统自带Python2.6.6(要求Version>=2.6),所有安装包的下载地址
为:http://www.talkwithtrend.com/Document/detail/tid/404677
1.配置YUM源
如果有专门的YUM服务器,可以直接配置如下:
cat /etc/yum.repos.d/rhel-source.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
如果没有专门的YUM服务器,可以先将RHEL6.6的ISO文件传至服务端,并用以下命令挂载:
mount -o loop -o ro /tmp/rhel6.6_x86_64.iso /mnt
再配置本地YUM源:
cat /etc/yum.repos.d/rhel-local.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
2.ansible依赖模块及安装包的安装
安装setuptools-7.0
tar -xvf setuptools-7.0.tar
cd setuptools-7.0
python setup.py instal
安装pycrypto-2.6.1
gzip -dc pycrypto-2.6.1.tar.gz|tar -xvf -
cd pycrypto-2.6.1
python setup.py install
安装包错解决:
报错1:
running install
running build
running build_py
running build_ext
running build_configure
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ansible/pycrypto-2.6.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
解决办法:yum install gcc
报错2:
解决办法:yum install python-devel
最后pycrypto安装成功。
安装PyYAML模块
安装yaml-0.1.5:
tar -xvf yaml-0.1.5.tar
cd yaml-0.1.5
./configure --prefix=/usr/local
make --jobs=`grep processor /proc/cpuinfo|wc -l`
make install
安装PyYAML-3.11:
gzip -dc PyYAML-3.11.tar.gz|tar -xvf -
cd PyYAML-3.11
python setup.py install
安装Jinja2模块
安装MarkupSafe-0.9.3:
tar -xvf MarkupSafe-0.9.3.tar
cd MarkupSafe-0.9.3
python setup.py install
安装Jinja2-2.7.3
gzip -dc Jinja2-2.7.3.tar.gz|tar -xvf -
cd Jinja2-2.7.3
python setup.py install
安装Paramiko模块
安装ecdsa-0.11:
gzip -dc ecdsa-0.11.tar.gz|tar -xvf -
cd ecdsa-0.11
python setup.py installs
安装paramiko-1.15.1:
gzip -dc paramiko-1.15.1.tar.gz|tar -xvf -
cd paramiko-1.15.1
python setup.py install
安装ansible-stable-2.3
unzip ansible-stable-2.3.zip
cd ansible-stable-2.3
python setup.py install
至此,Ansible软件在服务端的安装工作全部完成。
2.3 Ansible软件配置
1.配置Ansible变量环境
Ansible配置文件是以ini格式存储配置数据的,在Ansible中,几乎所有的配置项都可以通过Ansible的
Playbook或者环境变量来重新赋值,在运行Ansible命令时,命令将会按照预先设定的顺序查找配置文件,
如下所示:
ANSIBLE_CONFIG:首先,Ansible命令会检查该环境变量,及这个环境变量所指向的配置文件。
./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件。
~/.ansible.cfg:再次,将会检查当前用户home目录下的ansible.cfg配置文件。
/etc/ansible/ansible.cfg:最后,将会检查在用软件包管理工具安装Ansible时自动产生的配置文件。
在这里我们在/etc/profile中,增加一行:
export ANSIBLE_CONFIG=/etc/ansible/ansible.cfg
在用户登录时,都将设置该环境变量。
2.配置Ansible配置文件
由于是TAR包安装,Ansible的目录及相关文件都需要自己创建:
mkdir /etc/ansible
cd /etc/ansible
touch ansible.cfg hosts
修改/etc/ansible/ansible.cfg的内容:
cat /etc/ansible/ansible.cfg
#defaults这一行是需要的
[defaults]
#inventory代表所管理的主机清单的文件位置
inventory = /etc/ansible/hosts
#library参数就是指向存放ansible模块的目录(ansible基于模块工作,本身没有批量部署的能力,真正
具有批量部署的ansible所运行的模块)
library = /usr/share/ansible/my_modules
#设置默认情况下ansible最多能有多少个进程同时工作
forks = 50
#设置默认执行命令的用户,可以在playbook中重新指定该参数
sudo_user = ansible
#指定连接被管节点的ssh端口,可以在hosts文件中,单独指定被管主机的ssh端口
remote_port = 22
#设置模块的语言
module_lang = C
#设置ansible服务端连接客户端的私有ssh key文件位置
private_key_file = /root/.ssh/id_rsa
#设置是否检查ssh主机的密钥
host_key_checking = False
#设置ssh连接的超时时间,单位秒
timeout = 60
#设置把ansible系统的输出记录到日志文件中
log_path = /tmp/ansible.log
2.4 Ansible客户端互信配置
按照以下步骤建立Ansible服务端与客户端间的互信关系,可以是root用户和root用户,也可以是非root
用户和非root用户间。
在Ansible服务端生成ssh public和private key:
ssh-keygen
将ssh public key下发到被管节点的.ssh目录:
ssh-copy-id -i /root/.ssh/id_rsa.pub client_ip
为了提高效率,可以将所有需要添加互信的client的ip地址编入文件/tmp/clienthosts.txt,并批量
下发到被管节点。
a=`cat /tmp/clienthosts.txt`
for i in $a
do
ssh-copy-id -i /root/.ssh/id_rsa.pub $i
done
然后每个建立互信过程时,输入“yes”和client密码,这样下次服务端就可以直接通过ssh连接客户
端了。
2.5 Ansible客户端Python与Simplejson环境安装
1.Ansible客户端环境的需求
被管理的服务器(Ansible客户端)需要安装python2.4以上的版本,如果python版本低于2.5,但不想安
装更高版本的python,对于Linux操作系统而言,可以安装python-simplejson模块来解决。
2.AIX操作系统python的批量安装
为了加快Ansible客户端环境的部署效率,可以通过以下批量python环境的安装步骤进行:
将以下AIX python的安装文件传至Ansible服务端的/tmp目录,版本满足要求即可:
gdbm-1.8.3-2.aix5.1.ppc.rpm
readline-4.3-2.aix5.1.ppc.rpm
expat-2.0.1-2.aix5.3.ppc.rpm
python-2.6.2-2.aix6.1.ppc.rpm
编辑文件/tmp/clienthosts_aix.txt将所有AIX的IP地址输入至该文件,并运行命令:
b=`cat /tmp/clienthosts_aix.txt`
for i in $b
do
scp /tmp/gdbm-1.8.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/readline-4.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/expat-2.0.1-2.aix5.3.ppc.rpm $i:/tmp
scp /tmp/python-2.6.2-2.aix6.1.ppc.rpm $i:/tmp
done
检查AIX客户端是否已经安装了python
for i in $b
do
ssh $i which python
done
如果安装了python,版本也大于等于2.6,可以重新编辑/tmp/clienthosts_aix.txt将该ip地址去掉。
未安装python的AIX客户端开始安装:
c=`cat /tmp/clienthosts_aix.txt`
for i in $c
do
ansible $i -m raw -a "cd /tmp;rpm -ivh gdbm-1.8.3-2.aix5.1.ppc.rpm;rpm -ivh readline-4.3-2.aix
5.1.ppc.rpm;rpm -ivh expat-2.0.1-2.aix5.3.ppc.rpm;rpm -ivh python-2.6.2-2.aix6.1.ppc.rpm"
done
由于Ansible服务端需要和安装了python的客户端才能通信,但是在客户端没有安装python前,可以通
过Ansible的raw模块直接通信,并安装python,用这种方式实现批量安装的目的。
3.Linux批量安装simplejson
Linux操作系统基本都自带python环境,所以只需要关注python版本即可,对于Linux python version<2.5
的操作系统环境,可以通过安装simplejson解决。
单机安装simplejson-3.6.5:
gzip -dc simplejson-3.6.5.tar.gz|tar -xvf -
cd simplejson-3.6.5
python setup.py install
批量安装simplejson-3.6.5:
将simplejson-3.6.5.tar.gz传至Ansible服务端的/tmp目录
拷贝simplejson-3.6.5.tar.gz至需要安装的客户端
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
scp /tmp/simplejson-3.6.5.tar.gz $i:/tmp
done
开始批量安装simplejson
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
ansible $i -m raw -a "gzip -dc simplejson-3.6.5.tar.gz|tar -xvf –;cd simplejson-3.6.5; python
setup.py install"
done
批量安装都是用类似的方法,这里也不再一一举例。
2.6 Ansible服务端与客户端连通性测试
1.查看ansible版本
"failed": true,
"module_stderr":"Shared connection to X.X.X.X closed.\r\n",
"module_stdout": "/bin/sh: /usr/bin/python: not found.\r\n"
"msg": "MODULE FAILURE",
"rc": 0
}
如果遇到这些报错,这里只需要按照上面所介绍的批量安装方式安装即可。
3 Ansible软件配置优化
3.1 本章价值
鉴于Ansible服务端使用了默认的SSH无代理方式与客户端通信,效率远低于有代理的通讯方式,然而
通过本章节,您将学习到如何通过配置优化,来加速Ansible的执行速度,以提高自动化运维的工作效率,
做到等同于有代理通讯方式的效率:包括如何开启SSH长连接,避免SSH短连接的通信开销;开启Pipelin-
ing,利用SSH会话来缩短PUT脚本至远端客户端执行的流程;开启Accelerate模式,利用远端客户端上运行
的守护进程,优化Ansible的执行流程;在Playbook中修改Ansible的执行策略,减少多主机批量执行过程的
等待;在Playbook中使用异步特性,减少执行任务的同步等待;设置Facts缓存,通过提前将Facts信息缓存
于本地JSON文件、Redis或Memcached内存数据库中,来提高PlayBook的执行效率。
3.2 Ansible执行速度过慢问题
在测试连通性的过程中,利用前面的默认配置,发现有一个问题非常困扰,就是通过Ansible服务端向
客户端执行命令非常缓慢,主要体现在创建SSH的通道很慢,虽然Ansible在同一个task里面是并行的控制
多台受管端,但是每一个task都需要和受控端创建SSH通道,非常影响效率。由下面也能看出,一个简单的
PING命令都要耗时13秒以上。
time ansible test -m ping
X.X.X.X | SUCCESS => {
"changed": false,
"ping": "pong"
}
real 0m13.030s
user 0m1.147s
sys 0m0.263s
这种执行效率显然是无法接收的,那么接下来如何通过配置优化来提升Ansible的执行效率是势在
必行。
3.3 开启SSH长连接
我们知道Ansible模式是使用SSH和远端主机进行通信,所以Ansible对于SSH的依赖性非常强,下面我
们第一步就从SSH入手来优化Ansible。OpenSSH在5.6版本以后支持了Multiplexing(多路复用)功能,它支
持同一主机的多个SSH会话共享单一TCP连接进行通讯,一旦第一个连接建立,后续连接就不再需要凭证,
从而消除了每次连接同一机器都需要键入密码的麻烦并且大幅度节省了服务器端的资源,这种功能也称作长
连接机制。
如果Ansible中控机的SSH -V版本高于5.6时,我们可以直接在ansible.cfg文件中设置SSH长连接即
可。设置参数如下:
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=5d
Contro1Persist=5d这个参数是设置整个长连接的保持时间,默认值为60秒,这里设置为5天,如果开
启后,通过SSH连接过的设备都会在用户当前目录的~/ansible/cp/目录下生成一个socket文件,每个会话一
个文件,以便相同连接复用,也可以通过netstat命令查看,会发现有一个ESTABLISHED状态的连接一直与
远端设备进行着TCP连接。如果长连接时间超过Contro1Persist的设定值,连接将被断开,socket文件也将
被清理。另外,如果不仅仅需要Ansible开启SSH长连接,SSH命令也保持长连接的话,可以修改Ansible中
控端的SSH CLIENT的全局性配置文件:/etc/ssh/ssh_config,或者修改当前用户的~/.ssh/config文件,仅
使本用户生效:
ServerAliveInterval 30
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 5d
其中ServerAliveInterval表示client每隔30秒发送一次请求给server,然后server响应,从而保持连接;
ServerAliveCountMax表示client发出请求后,服务器端没有响应的次数达到3,就自动断开连接;ControlPath
表示socket的存放和复用路径。
如果我们的Ansible中控机SSH-V版本低于5.6时,则需要升级到5.6版本后才能启用SSH Multiplex-
ing特性。
通过SSH-V命令查看了下当前演示环境的OpenSSH的版本为:OpenSSH_5.3p1,这次需要将openssh
版本升级到OpenSSH_6.7p1,安装包的下载地址为:
http://www.linuxfromscratch.org/blfs/view/7.7/postlfs/openssh.html
升级过程如下:
查看是否缺少依赖包:
rpm -qa|egrep “gcc|make|perl|pam|pam-devel”
缺少了依赖包,可以通过YUM源直接安装这些缺少的包:
yum –y install gcc* make perl pam pam-devel
上传安装包:openssh-6.7p1.tar.gz
备份ssh:
mv /etc/ssh /etc/ssh.bak
编译安装新版本OpenSSH
gzip -dc openssh-6.7p1.tar.gz|tar -xvf –
cd openssh-6.7p1
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-zlib --with-md5-passwords
make
卸载旧版本OpenSSH
rpm -a|grep openssh
rpm -e `rpm –qa|grep openssh` --nodeps
安装新版本OpenSSH
make install
配置OpenSSH,主要是保证ssh-copy-id等命令能够正常使用
cd openssh-6.7p1
install -v -m755 contrib/ssh-copy-id /usr/bin
install -v -m644 contrib/ssh-copy-id.1 /usr/share/man/man1
install -v -m755 -d /usr/share/doc/openssh-6.7p1
install -v -m644 INSTALL LICENCE OVERVIEW README* /usr/share/doc/openssh-6.7p1
查看是否升级到了新版本
ssh –V
OpenSSH_6.7p1, OpenSSL 1.0.1e-fips 11 Feb 2013
复制启动脚本到/etc/init.d
cp /root/openssh-6.7p1/contrib/redHat/sshd.init /etc/init.d/sshd
将sshd加入开机自启动
chkconfig --add sshd
重新启动sshd
service sshd restart
执行速度验证
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:17 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m4.228s
user 0m2.591s
sys 0m0.327s
通过OpenSSH的版本升级,我们发现速度优化较为明显,执行速度为4秒左右。我们当然不然满足于
此,看看按照前面介绍的方式,开启Multiplexing功能特性后的Ansible执行速度又如何:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:31 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m3.075s
user 0m2.532s
sys 0m0.310s
执行速度又降低了1秒,看来复用了长连接,减少SSH的TCP通信开销还是有效果的。
3.4 开启Pipelining
Pipelining也是OpenSSH的一个特性,在Ansible的整个执行流程中,包含三个步骤:
首先,基于调用的模块生成一个Python脚本
其次,再将Python脚本复制到主机上
最后,在远端服务器上执行这个Python脚本
我们可以看到,其中有一个流程就是把生成好的本地Python脚本PUT到远端服务器执行,如果开启了
Pipelining,Ansible执行Python脚本的时候并不会复制它,而是通过管道传递给SSH会话,Ansible使用的
SSH会话将减少到一个,这样可以大大提高整个执行效率。尤其是在在部署大规模服务器或引用模块非常多
时,开启Pipelining特性会给Ansible带来更加显著的性能提升。下面我们通过一个示例展示整个过程。首先
在ansible.cfg配置文件中设置Pipelining。
[ssh_connection]
pipelining = True
再来看开启了Pipelining之后整个Ansible的执行流程有什么变化:
开启Pipelining之前的流程如下:
开启Pipelining之后的流程如下:
我们可以看到开启了Pipelining之后整个流程少了一个PUT脚本和SFTP去远端服务器的流程,且大量减
少了SSH连接次数,第一步就是直接调用ssh执行脚本。那么经过优化后的耗时又如何呢:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
ansible --version
ansible 2.3.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) [GCC 4.4.7 20120313 (Red Hat4.4.7-4)]
2.测试ansible服务端与客户端连通性
Ansible all -m ping
这时由于并非所有客户端都具备相应的条件,要么python未安装、要么python版本不符合要求,要么没
有安装ssh等,会报如下错误:
客户端python版本不符合要求:
X.X.X.X | FAILED! => {
"changed": false,
"failed": true,
"msg": "Error: ansible requires the stdlib json or simplejson module, neither was found!"
}
客户端未安装ssh:
X.X.X.X | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host x.x.x.x port 22: Connection
refused\r\n",
"unreachable": true
}
客户端未安装python:
X.X.X.X | FAILED! => {
"changed": false,
15:38:26 up 881 days, 17:13, 0 users, load average: 0.00,0.00, 0.00
real 0m1.741s
user 0m1.429s
sys 0m0.176s
耗时又降低了1.3秒。
但是我们要注意,如果在Ansible中使用sudo命令的话,例如:ssh user@host sudo cmd,需要在被控
节点的/etc/sudoers中禁用"requiretty"。这是因为ssh远程执行命令时,它的环境是非登录式非交互式
shell,默认不会分配tty,没有tty,ssh的sudo就无法关闭密码回显(业可以在Ansible命令行中使用"-tt"参
数来强制SSH分配tty)。所以出于安全考虑,/etc/sudoers中默认是开启requiretty的,它要求只有拥有tty
的用户才能使用sudo,也就是说ssh连接过去不允许执行sudo。所以我们需要编辑sudo配置文件,通过注
释该选项来禁用它。如果我们在Playbook中不适用sudo越权功能,则不需要在被控节点的sudo配置文件中
禁用该选项。
3.5 开启Accelerate模式
除了OpenSSH上述两个功能之外,Ansible还有一个Accelerate模式,这和前面SSH Multiplexing功能有
点类似,因为都依赖Ansible中控机跟远端机器有一个长连接。但是Accelerate是使用Python程序在远端机器
上运行一个守护进程,然后Ansible会通过这个守护进程监听的端口进行通信。开启Accelerate模式很简单,
只要在Playbook中配置accelerate:true即可开启。但是需要注意,如果开启Accelerate模式,则需要在
Ansible中控机与远端机器都安装python-keyczar软件包,软件包的下载地址如下:
http://rpm.pbone.net/index.php3/stat/4/idpl/49957349/dir/redhat_el_6/com/python-keyczar-0.71c-
1.el6.noarch.rpm.html
安装python-keyczar软件包,中控机和远端都需要安装。远程批量安装可以参考采用之前所介绍的
方式实施。
yum install python-pyasn1
rpm -ivh python-keyczar-0.71c-1.el6.noarch.rpm
定义ansible.cfg文件中Accelerate参数,例如远端机器的监昕端口以及timeout设置。当然这些参数
也可以在写playbook的时候再定义:
[accelerate]
accelerate_port = 5099
accelerate_timeout= 30
accelerate_connect_timeout= 5.0
在Playbook中定义Accelerate,例如:
---
- hosts: all
accelerate: true
accelerate_port: 5099
然而,RedHat官方目前不赞成使用Accelerate模式。因为在启用ControlPersist和Pipelining管道的情况
下,Ansible的执行效率比较高。Accelerate功能在后面的Ansible版本中将被删除。
3.6 修改Ansible执行策略
默认Ansible在远程执行任务是按批并行执行的,一批控制多少台主机由命令行的-f参数或ansible.cfg配
置中的--forks选项控制。例如,默认的并行进程数是5,如果有20台被控主机,那么只有在每5台全部执行
完一个任务才继续下一批的5台执行该任务,即使中间某台机器性能较好,完成速度较快,它也会空闲地等
待在那,直到所有20台主机都执行完该任务才会以同样的方式继续下一个任务。
在Ansible 2.0版本后,添加了一个策略控制选项strategy,默认值为"linear",即上面按批并行处理的方
式。我们还可以设置strategy的值为"free"。在free模式下,Ansible会尽可能快的切入到下一个主机。同样
是上面的例子,首先每5台并行执行一个任务,当其中某一台机器由于性能较好提前完成了该任务,它不会
等待其他4台完成,而是会跳出该任务让Ansible切入到下一台机器来执行该任务。也就是说,这种模式下,
一台主机完成一个任务后,另一台主机会立即执行任务,它是"前赴后继"的方式。所以这种策略的执行结果
给人感觉是无序的甚至是杂乱无章的,而且每次执行结果的Task显示顺序很可能不一样。利用Playbook,
这两种策略的设置的方式如下:
---
- hosts: all
strategy: free
tasks:
...
3.7 任务执行优化
默认情况下Playbook中的任务在执行时会一直保持连接,直到该任务在每个主机节点都执行完毕,下一
个任务才会开始执行。有时这是不必要的,比如有些操作运行时间比SSH超时时间还要长。解决该问题最简
单的方式是一起执行它们,然后轮询直到任务执行完毕,简单的意思就是,像下面的例子,执行任务后,
Ansible就不等它了,往下执行下一个任务,然后每隔5秒钟去看看它执行完成没,超时时间为45秒,async
参数值代表了这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。如果
async参数若未设置,则为同步执行。我们也可以对执行时间非常长(有可能遭遇超时)的操作使用异步模
式。为了异步启动一个任务,可以指定其最大超时时间以及轮询其状态的频率。如果没有为 poll 指定值,那么
默认的轮询频率是10秒钟。
---
- hosts: all
remote_user: root
tasks:
- name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
command: /bin/sleep 15
async: 45
poll: 5
在异步执行任务时,需要注意那些有依赖性的任务。对于那些对资源要求占有排它锁的任务,如yum,
不应该将Poll的间隔设置为0。如果设置为0,很可能会导致资源阻塞。总结来说,大概有以下一些场景需要使
用到Ansible的异步特性:
某个Task需要运行很长的时间,这个Task很可能会达到ssh连接的Timeout。
没有任务是需要等待它才能完成的,即没有任务依赖此任务是否完成的状态。
需要尽快返回当前shell的。
当然也有一些场景不适合使用异步特性:
这个任务是需要运行完后才能继续另外的任务的。
申请排它锁的任务。
3.8 设置Facts缓存
当我们用ansible-playbook执行Playbook的时候,我们会发现,默认第一个Task都是GATHERING
FACTS,这个过程就是Ansible收集每台主机的Facts信息,方便我们在Playbook中直接引用Facts里的信息。
当然如果我们的Playbook中不需要Facts信息,可以在Playbook中设置gather_facts: False来提高Playbook的
效率:
---
- hosts: 10.0.108.2
gather_facts: no
tasks:
...
也可以在ansible.cfg文件中添加如下配置来默认禁用Facts采集:
[defaults]
gathering = explicit
但是如果我们既想每次执行Playbook的时候都能收集Facts信息,又想加速这个收集过程,这时候可以
设置Facts的缓存。例如,在空闲的时候收集Facts,缓存下来,在需要的时候直接读取缓存进行引用,直到
缓存过期。目前Ansible支持使用Json文件,Redis、Memcached内存数据库来存储Facts信息。
Json文件缓存Fact信息
使用Json文件作为Fact缓存后端时,Ansible将会把采集的Fact写入Ansible中控机的上的文件中。如果
系统中已经存在这个文件,那么Ansible将使用这个文件中的数据,而不再连接到主机去采集Fact。下面我
们首先通过示例来了解如何使用Json文件存储Facts信息,在ansible.cfg文件中添加:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_fact_cache
Ansible的配置文件中可以修改gathering的值为smart、implicit或者explicit。
smart表示默认收集Facts,但Facts已有的情况下不会收集,即使用缓存Facts;
implicit表示默认收集Facts,要禁止收集,必须使用gather_facts: False;
explicit表示默认不收集,要显式收集,必须使用gather_facts: Ture;
在使用Facts缓存时(即设置为smart),Ansible支持两种Facts缓存:redis和jsonfile。这里设置Facts过期
时间为86400秒(会根据文件的最后修改时间来确定Facts信息是否过期),Json文件存放在/tmp/ansi-
ble_fact_ cache下,下面我们执行一下Playbook:
我们再执行Playbook的时候就没有Facts收集这个过程了。直接从Json文件中读取Facts缓存信息:
可以看到10台受控机的执行耗时仅1.8秒,效率是非常不错的。
Redis缓存Fact信息
由于目前Ansible Facts缓存还不支持远端,所以需要在 Ansible中控机上安装Redis服务,并安装Redis
Python模块。
如何安装在,这里不再赘述,有兴趣可以去下载安装包安装。Redis配置ansible.cfg文件如下所示:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
Memcache缓存Fact信息
Ansible Facts存储还支持Memcached 存储,配置方法也很简单,在安装完Memcached服务并运行后,
同时安装Python的Memcached依赖包,最后配置ansible.cfg即可:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = memcached
4 Ansible软件日常维护和使用
4.1 本章价值
通过本章节,您将学习到如何维护Ansible的Inventory,来管理不同业务的不同机器,以便后续灵活的
对它们进行自动化运维操作;同时您也将学习到如何使用Ansible的一些常用组件,包括如何通过AD-Hoc命
令行的方式使用Ansible的各种模块,完成一些基本的自动化运维工作;如何编写和使用Playbook,来完成
复杂环境下的自动化运维工作;如何利用Facts组件来采集被管客户端的设备信息,来实现配置管理系统(
CMDB)的自动采集能力等等。
4.2 Ansible Inventory维护
Inventory文件
在日常维护中,Ansible通过Inventory(可管理的主机集合),对远端服务器或者主机进行统一操作和
管理。在Ansible中,描述主机的默认方法是将他们列在一个文本文件中,这个文件称为Inventory文件,默
认的路径和文件为:/etc/ansible/hosts,可以通过ANSIBLE_HOSTS环境变量来指定,也可以在ansible.cfg
文件中通过inventory参数指定,或者在运行ansible和ansible-playbook的时候使用-i参数来临时指定。
下面举例说明,如何在inventory组件的/etc/ansible/hosts文件中定义主机和主机组:
1 X.X.X.100 ansible_ssh_pass='123456'
2 [groupname1]
3 X.X.X.10[1:9]
4 X.X.X.20[1:9]
5 [groupname1:vars]
6 ansible_ssh_pass='123456'
7 [groupname2:children]
8 groupname1
第一行定义了一个主机X.X.X.100,并使用inventory内置变量ansible_ssh_pass定义了该主机的登录密
码,如果建立了互信,则不需要这个参数;
第二、三、四行定义了一个名为groupname1的主机组,其中包含X.X.X.101-X.X.X.109,
X.X.X.201-X.X.X.209共计18台主机;
第五、六行为groupname1的主机组定义了一个共同的变量:ansible_ssh_pass,以定义该组内所有主
机的登录密码;
第七、八行定义了一个更大的组:groupname2,其下包含了groupname1组下的所有主机。
定义好之后,我们在ansible命令行和ansible-playbook中,可以非常灵活的使用,便于批量操作。例如
批量查看groupname1组下所有主机的当前时间:
ansible groupname1 -a date
Inventory内置参数
除了前面介绍的ansible_ssh_pass参数,Ansible Inventory内置了一些参数,这些参数在我们实际工作
中也会经常使用,我们可以直接在Inventory文件中定义它。
我们也可以在ansible.cfg文件中的[defaults]部分更改一些Inventory内置参数的默认值,可以支持更改
的有:
动态Inventory
在实际的应用中,会存在大量的主机列表信息,如果手动维护Ansible中的Inventory文件将会非常的繁
琐,所以支持动态Inventory将会让问题变得统一、清晰、简单许多。动态Inventory也就是Ansible所有的
Inventory文件里面的主机列表和变量信息都支持从外部拉取,例如我们常用的CMDB,我们可以通过定义的
脚本,将外部CMDB等其他运维系统中的主机信息同步至Ansible中。在实际的配置中仅需要更改ansible.cfg
文件中的inventory参数为一个可执行的脚本即可。
[defaults]
inventory = /etc/ansible/inventory.sh
脚本的内容不受任何编程语言限制,但该脚本必须支持以下规范的参数,脚本的执行结果也有一定的
要求:
--list或者-l,脚本运行该参数须显示所有主机和组的信息(Json格式)。
--host或者-H,脚本的该参数后需指定一个主机,运行结果也会返回该主机的所有信息(同样也必须
为Json格式)。
脚本调试好之后,ansible将利用inventory变量所指向的脚本,获取主机和组信息(或者通过-i参数指
定),来向主机执行命令。
Inventory分割
如果我们想要同时使用常规Inventory文件和动态Inventory脚本,或者按不同业务/系统分割成的多个
Inventory文件,我们可以把所有这些文件全部都放到同一个目录,并配置ansible.cfg文件的hostfile参数,让
Ansible使用hostfile参数所指定的目录作为Inventory即可,也可以在命令行中使用-i命令来指定特定的
Inventory文件。Ansible将会处理目录里所有的文件并将结果合并为一个完整的Inventory。
[defaults]
hostfile = /etc/ansible/inventory
4.3 Ansible Ad-Hoc命令使用
Ansible系统由控制主机对被管节点的操作方式可分为两类,即 Ad-Hoc和Playbook:
Ad-Hoc模式使用单个模块,支持批量执行单条命令。
Playbook模式是Ansible主要管理方式,也是Ansible功能强大的关键所在,Playbook通过多个Task集合
完成一类功能,如 Web 服务的安装部署、数据库服务器的批量备份等,可以简单地把 Playbook理解为通过
组合多条Ad-Hoc操作的配置文件。
下面将通过两个小节的内容,来说明如何使用Ad-Hoc和Playbook。其中Ad-Hoc将重点介绍命令参数
和几个常用的模块。
通常我们会以命令行的形式使用Ansible模块,或者将Ansible命令嵌入到脚本中去执行。Ansible自带了
很多模块,我们可以直接使用他们。当我们不知道如何使用这些模块时,可以ansible-doc命令获取帮助,
例如:使用“ansible-doc -l”命令可以显示所有自带的模块和相关简介,使用“ansible-doc 模块名”命令可以
显示该模块的参数及用法等内容。
Ansible Ad-Hoc命令参数
我们可以使用“ansible -h”命令来列出所有的命令参数,下面列举了常用的一些参数,部分参数如果不
指定将采用ansible.cfg中的设置值,或者采用原始默认值。
Ansible常用模块介绍
连通性测试
通常采用Ping模块来测试远程主机的运行状态:
ansible ip -m ping
执行命令
执行命令可以采用四种方式,第一种方式是利用Command模块在远程主机上执行命令,但Command
模块不支持管道命令,例如,查看某个主机的日期:
ansible ip -m command -a date -o
值得注意的是,Ansible默认的模块是Command,所以上面的命令可以简化为:
ansible ip -a date -o
第二种方式是利用Shell模块,切换到某个Shell执行远程主机上的Shell/Python脚本,或者执行命令,
Shell支持管道命令,功能较Command更强大灵活,例如:
ansible ip -m shell -a 'bash /root/test.sh' -o
ansible ip -m shell -a 'echo "123456"|passwd --stdin root'
第三种方式是利用Raw模块,Raw支持管道命令。Raw有很多地方和Shell类似,但是如果是使用老版本
Python(低于2.4),无法通过Ansible的其他模块执行命令,则需要先用到Raw模块远程安装Python-sim-
plejson后才能受管;又或者是受管端是路由设备,因为没有安装Python环境,那就更需要使用Raw模块去
管控了。例如:
ansible ip -m raw -a "cd /tmp;pwd"
第四种方式是利用Script模块,传输Ansible中控端上的Shell/Python脚本到远端主机上执行,即使远端
主机没有安装Python也可以执行,有点类似Raw模块。但Script只能执行脚本,不能调用其他指令,且不支
持管道命令,例如:
ansible ip -m script -a '/root/test.sh' -o
removes参数用来判断远端主机上是不是存在test.sh文件,如果存在,就执行管控机上的test.sh,不存
在就不执行:
ansible ip -m script -a 'removes=/root/test.sh /root/test.sh' -o
creates用来判断远端主机上是不是存在test.sh文件,如果存在,就不执行,不存在就执行管控机上的
test.sh文件:
ansible ip -m script -a 'creates=/root/test.sh /root/test.sh' -o
复制文件
常用的文件操作模块就是Copy模块,它主要用于将本地或远程机器上的文件拷贝到远程主机上。其主
要参数有以下几个:
复制本地文件的到远程主机:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh'
复制并修改文件的权限:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755'
复制并修改文件的属主:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755 owner=root'
复制文件前备份:
ansible ip -m copy -a 'src=test.sh backup=yes dest=/tmp'
服务管理
在Ansible Ad-Hoc中,Service模块可以帮助我们管理远程主机上的服务。例如,启动或停止远程主机
中的某个服务。但是该服务本身必须要能够通过操作系统的管理服务的组件所管理,例如Redhat6中默认通
过SysV进行服务管理,Redhat7中默认通过Systemd管理服务,如果该服务本身都不能被操作系统的服务管
理组件所管理,那么也不能被Service模块管理。该模块的几个常用参数如下:
启动服务:
ansible all -m service -a "name=sshd state=started"
停止服务:
ansible all -m service -a "name=sshd state=stopped"
开启服务自启动:
ansible all -m service -a "name=sshd enable=yes"
安装包管理
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
安装软件包:
ansible all -m yum -a 'name=nginx state=installed’
卸载软件包:
ansible all -m yum -a 'name=nginx state=removed'
临时启用local yum源安装最新版软件包:
ansible all -m yum -a 'name=nginx state=latest enablerepo=local'
用户管理
在Ansible Ad-Hoc中,可以通过User模块帮助我们管理远程主机上的用户,比如创建用户、修改用户、
删除用户、为用户创建密钥对等操作。该模块的几个常用参数如下:
增加用户、组和密码:
ansible ip -m group -a "name=testg”
ansible ip -m user -a "name=test group=testg password=123456 home=/home/test”
删除用户和用户主目录:
ansible ip -m user -a "name=test state=absent remove=yes"
4.4 Ansible Playbook使用
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
我们在使用Ansible时,绝大部分时间将花费在编写Playbook上,Playbook是一个Ansible术语,指的是
用于配置管理的脚本。Ansible的Playbook是使用YAML语法编写的。YAML是一种类似于Json的文件格式,
不过YAML更适合人来读写。我们在开始编写Playbook时,需要对YAML的语法有一定的了解,否则将经常
碰到语法错误。下面首先通过一个安装和配置ntpd服务的Playbook案例来介绍:
1 ---
2 - hosts: all
3 tasks:
4 - name: install ntpd Package
5 yum: name=ntp state=present
6 - name: copy ntp.conf
7 template: src=/tmp/ntp.conf.j2 dest=/etc/ntp.confowner=root group=root mode=0644
8 notify:
9 - restart ntpd service
10 handlers:
11 - name: restart ntpd service
12 service: name=ntpd state=restarted
第一行仅表示该文件为YAML格式文件,非必须。
第二行定义了该Playbook所针对的主机,all表示所有,也可以填写Inventory文件中的IP地址或者主机组
名称。
第三行表示下面开始定义Task任务。
第四、五行定义了一个具体Task任务(通过Yum安装ntpd服务),包含任务名称和执行动作,其中任
务名称为非必须,可以直接定义执行动作。
第六、七、八、九行定义了另一个具体Task任务(同步ntpd配置文件模板),并更改文件的属主、属
组和文件权限。notify和下面的handlers为配对使用,当ntpd配置文件模板同步至远端主机后,文件的MD5
值将发生变化,触发restart ntpd service这个handler。
第十、十一、十二行定义了上述handler的具体内容,包括名称和执行动作,也就是利用service模块来
重启ntpd服务。
编制好了Playbook,我们需要使用--syntax-check参数来对该脚本进行语法检查:
ansible-playbook ntpd.yaml --syntax-check
playbook: ntpd.yaml
语法检测过后,可以用--list-task参数来查看该Playbook中的所有Task:
ansible-playbook ntpd.yaml --list-task
playbook: ntpd.yaml
play #1 (X.X.X.2): X.X.X.2 TAGS: []
tasks:
install ntpd Package TAGS: []
copy ntp.conf TAGS: []
确认无误后,开始使用命令运行名为ntpd.yaml的Playbook:
ansible-playbook ntpd.yaml
后续如果我们的ntpd.conf.j2配置模板需要变更,并需要批量分发下去,我们可以指定copy ntp.conf这
个Task,只运行该Task:
ansible-playbook ntpd.yaml --start-at-task=’copy ntp.conf’
除了上述参数之外,ansible-playbook还有几个常用的参数:
--step同一时间只执行一个Task,每个Task执行前都会提示确认一遍。
--tags=TAGS当Play和Task的Tag为该参数指定的值时才执行,多个Tag以逗号分隔。
--skip-tags=SKIP_TAGS当Play和Task的Tag不匹配该参数指定的值时才执行。
根据前面的案例,我们对Playbook的大体写法和用法有了一个大致的认识,下面重点介绍几个Play-
book常用的使用要点:
Playbook的组成
一个Playbook包括一个或多个Play。一个Play由Host的无序集合与Task的有序列表组成。每一个Task
仅由一个模块构成。见下图所示:
Tasks List和Action
Play的主体部分是Task列表,Task列表中的各任务按次序逐个在Hosts中指定的主机上执行,即在所有
主机上完成第一个任务后再开始第二个任务。在运行Playbook时(从上到下执行),如果一个Host执行
Task失败,整个Task都会回滚,我们需要修正Playbook中的错误,然后重新执行即可。Task的目的是使用
指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等等,这意味着多次执行是安全的,因
为其结果一致。
另外,按照规范写法,每一个Task必须有一个名称Name,虽然这不是必须的,但这样在运行Playbook
时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个Task。如果没有定义Name,Action的值将
会用作输出信息中标记特定的Task,结果不好分辨。定义一个Task,常见的格式为“module: options”,例
如:“yum: name=httpd”。值得注意的是,Ansible的自带模块中,Command模块和Shell模块无需使用
key=value格式,直接编写要执行的命令即可。
Handlers
Handlers也是一些Task的列表,和一般的Task并没有什么区别。它是由通知者进行的Notify,如果没有
被Notify,则Handlers不会执行,如果被Notify了,则Handlers被执行。不管有多少个通知者进行了Notify,
等到Play中的所有Task都执行完成之后,Handlers也只会被执行一次。例如:
变量引用
我们可以在PlayBook中通过“vars: 变量名”的方式声明变量,并通过“{{变量名}}”的方式使用已声明的变
量。另外,我们还可以直接引用Ansible的变量,包括采集到的主机Fact中的变量,例如:通过ansi-
ble_all_ipv4_address来获取IPV4地址,或者通过ansible_distribution、ansible_distribution_version来获取操
作类型和版本信息。除此之外,还能引用已编辑好的Inventory文件中定义的主机变量,这样当安装完一些软
件,需要根据主机中定义的变量来做一些自动化配置时,将会非常好用。例如:
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
X.X.108.2 hostname="test"
上面的案例是通过vars的方式定义了package和service两个变量,并在下面的yum和service两个Task中
进行引用,第三个Task则是直接引用setup生成的Fact变量和来自Inventory文件中定义的主机变量host-
name,来实现将内容信息传递至远端主机的文件中,输出结果如下:
cat /tmp/test.txt
test:RedHat 7.2
条件判断
我们可以在PlayBook中通过“when: 变量==值”的方式声明一个条件判断,可以看出when的值是一个条
件表达式,如果条件判断成立,Task就执行,如果判断不成立,则task不执行。例如当我们需要根据变量、
Facts(setup)或此前任务的执行结果来作为某Task执行与否的前提时,则要用到条件判断,这时可以在
Playbook中使用when子句:在Task后添加when子句。另外,when子句支持jinjia2表达式或语法。
迭代
当我们有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变
量引用,并通过with_items语句指明迭代的元素列表即可。例如:
Templates
Jinja是基于Python的模板引擎。Template类是Jinja的另一个重要组件,可以看作一个编译过的模块文
件,用来生产目标文本,我们可以传递Python的变量给模板去替换模板中的标记。例如,我们在做Nginx安
装与配置时,有些监听端口、服务名称等配置可以通过变量的方式在Inventroy文件中为不同主机预定义好,
当我们定义好了一个模板,并将模板中的监听端口和服务名称设置为变量后,在运行Template这个Task时,
将会把不同主机的这些变量信息传递到模板中使用,实现配置的自动化。例如:
vi /tmp/httpd.conf.j2 #定义模板中的变量
Listen {{http_port}}
ServerName {{server_name}}
MaxClients {{access_num}}
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
[test]
X.X.X.2 http_port=X.X.X.2:80 access_num=50 server_name="test:80"
安装Nginx时,将把Inventory文件中主机定义好的变量与值传递到模板中,并拷贝至该远端主机:
Tags
在一个Playbook中,我们一般会定义很多个Task,如果我们只想执行其中的某一个Task或多个Task时
就可以使用Tags标签功能了,例如:
ansible-playbook test.yml --tags="nginx"
4.5 Ansible Facts使用
Facts组件是Ansible用于采集被管主机设备信息的一个功能,当Ansible采集Fact的时候,它会收集被管
主机的各种详细信息:CPU架构、操作系统、IP地址、内存信息、磁盘信息等,这些信息保存在被称作Fact
的变量中。Ansible使用一个名为Setup的特殊模块来实现Fact的收集,在Playbook中默认会调用这个模块进
行Fact收集,在命令行中可以通过“ansible ip -m setup”来进行手动收集,整个Facts信息被包装JSON格式
的数据结构中, Ansible Facts是最上层的值。例如:
Facts还支持通过filter参数来查看指定信息,例如下面只查看远端主机的操作系统和版本:
查看远端主机的CPU和内存大小:
查看远端主机的各文件系统大小和剩余容量:
在Playbook中,Facts组件默认会收集很多的主机的基础信息,可以通过前面的Fact缓存机制,将这些
信息缓存到本地目录或者内存数据库中,在做配置管理的时候进行引用,也可以用来将获取的主机基础信息
自动同步到CMDB中去,实现基础信息的自动采集功能。下面通过通过演示,说明如何通过ansible-cmdb
插件,实现远端主机CPU自动同步至外部CMDB系统中。
首先,我们需要安装ansible-cmdb插件,下载链接如下:
其次,开始安装ansible-cmdb插件:
gzip -dc ansible-cmdb-1.27.tar.gz|tar -xvf -
cd ansible-cmdb-1.27
python setup.py install
生成所有主机的Fact信息并用filter过滤出主机CPU值:
ansible all -m setup -t /tmp/factout
ansible all -m setup -a “filter=ansible_processor_count” -t /tmp/cpu
通过ansible-cmdb插件以csv或sql格式输出IP地址和CPU颗数值:
PATH=/usr/local/bin:$PATH
ansible-cmdb -t csv -c name,cpus /tmp/cpu >/tmp/cpu.csv
ansible-cmdb -t sql /tmp/cpu >/tmp/cpu.sql
以csv格式或者sql格式导入信息至外部CMDB系统中(根据支持方式灵活选用),这里以postgres数据
库为例,通过转csv格式为sql格式导入至外部CMDB系统:
cpuinfo=$(cat /tmp/cpu.csv)
for cpu_info in $cpuinfo
do
ip=$(echo "$cpu_info" |awk -F"," '{print $1}'|sed 's/"//g')
cpu=$(echo "$cpu_info" |awk -F"," '{print $2}'|sed 's/"//g')
echo "update \"VirtualMachine\" set \"VCPU\"='$cpu' where \"IP\"='$cpuip' and \"Status\"='A';"
>>/tmp/cpu_info.sql
done
su - postgres -c "export PGPASSWORD=postgres;/opt/PostgreSQL/9.3/bin/psql -d cmdbuild -f
/tmp/cpu_info.sql"
当然,以上仅仅是简单的示例,事实上,我们可以利用好Ansible Fact的功能,实现更加复杂的CMDB
自动化采集功能。
05
运维技术岗岗位学习教程
1 Ansible软件简介
1.1 本章价值
通过本章节,您将学习到Ansible的软件架构模式、管理方式和系统架构等内容,同时您将了解到Ansi-
ble的六大功能特性,和其他主流的开源自动化运维软件的对比,与优缺点分析等。
1.2 Ansible软件架构
Ansible是一个开源的基于OpenSSH的自动化运维管理软件。可以用它来配置系统、部署软件和编排更
高级的IT任务,比如持续部署或零停机更新。Ansible的主要目标是简单和易用,并且它还高度关注安全性和
可靠性。基于这样的目标,Ansible适用于开发人员、系统管理员、发布工程师、IT经理,以及介于两者之间
的所有人。Ansible适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。
Ansible软件架构模式通常由控制机和被管机组成,控制机是用来安装Ansible工具软件、执行维护指令
的服务器或工作站,也称之为Ansible服务端,它是Ansible维护的核心。被管机是运行业务服务的服务器,
也称为Ansible客户端,由控制机通过SSH来进行管理。
Ansible管理方式
Ansible是一个模型驱动的配置管理器,支持多节点发布、远程任务执行,默认使用SSH进行远程连接。
无需在被管节点上安装附加软件,可使用各种编程语言进行扩展。Ansible管理系统由控制主机和一组被管
节点组成,控制主机直接通过SSH控制被管节点,被管节点通过Ansible的资源清单来进行分组管理。
Ansible系统架构
Ansible集合了众多优秀运维工具(Puppet、Cfengine、Chef、Fune、Fabric)的优点,实现了批量系
统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作的,本身没有批量部署的能力。真
正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。Ansible的系统架构见下图,用户可
以通过Ansible编排引擎操作公有云/私有云或CMDB(配置管理数据库)中的主机。从图中可以看到,Ansi-
ble由以下各部分组成:
核心引擎:即Ansible。
核心模块(Core Modules):这些都是Ansible自带的模块,Ansible 模块资源分发到远程节点使其执行
特定任务或匹配一个特定的状态。Ansible遵循“Batteries Included“哲学,所以你可以有各种各样任务的核心
模块。这意味着模块是最新的,你不需要寻找一个在你平台上工作的实现。你可以认为模块库的工具箱里充
满了有用的系统管理工具,和Playbook一起构建自动化运维系统的基础源材料。
白定义模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加自定义模块。
插件(Plugins):完成模块功能的补充,借助于插件完成记录日志、邮件等功能。
剧本(Playbook):定义Ansible任务的配置文件,可以将多个任务定义在一个剧本中,由 Ansible自动
执行,剧本执行支持多个任务,可以由控制主机运行多个任务,同时对多台远程主机进行管理。Playbook是
Ansible的配置、部署和编排语言,可以描述一个你想要的远程系统执行策略,或一组步骤的一般过程。如
果Ansible模块作为你的工作室工具,PlayBook则是你的设计方案。在基本层面上,剧本可用于管理配置和
部署远程机器。在更高级的应用中,可以序列多层应用及滚动更新,并可以把动作委托给其他主机,与监控
服务器和负载平衡器交互。
连接插件(Connectior Plugins) : Ansible基于连接插件连接到各个主机上,负责和被管节点实现通信。
虽然Ansible是使用SSH连接到各被管节点,但它还支持其他的连接方法,所以需要有连接插件。
主机清单(Host Inventory):定义Ansible管理的主机策略,默认是在Ansible Hosts配置文件中定义被
管节点,同时也支持自定义动态主机清单和指定配置文件的位置。
1.3 Ansible软件特性
Ansible是基于一致性、安全性、高可靠性设计的轻量级自动化工具,具有功能强大、部署便捷、描述
清晰等特性。对于管理员、开发者、IT经理等都容易上手,学习曲线较低,能够快速理解、掌握 Ansible的
自动化体系,满足不同技术级别的用户需求。同时Ansible 是一款满足当代大规模、复杂环境的IT基础架构
自动化管理的工具。
Ansible相对与其他自动化解决方案,在核心能力上效率更高。也很好地解决了统一配置、统一部署、
流程编排等复杂的IT自动化管理问题。下面就介绍其功能特性以及与其他工具的对比。
Ansible功能特性
从功能上看,Ansible可以实现以下目标:
应用代码自动化部署。
系统管理配置自动化。
支持持续交付自动化。
支持云计算、大数据平台(如AWS、OpenStack、CloudStack、VMWare等)环境。
轻量级,无需在客户端安装Agent,更新时只需在控制机上进行一次更新即可。
批量任务执行可以写成脚本,不用分发到远程就可以执行。
使用Python编写,维护更简单,而Ruby语法过于复杂。
支持非root用户管理操作,支持sudo。
实现上述目标是很有挑战性的工作,需要满足健壮性、易于管理的架构,这在应用维度一直没能很好地
解决,因为管理工具不能对被管环境施加额外的影响,而Ansible很好地解决了这些问题。Ansible作为优秀
管理工具具备以下一些特点:
1.语法简单、易读
Ansible的配置管理脚本Playbook语法基于YAML,它是一种可读性高、用来表达数据序列的格式标准。
YAML参考了XML、C、Python、Perl以及电子邮件格式RFC2822等其他多种语言,可读性好、交互性强,
使用了实现语言的数据类型,有一个一致的信息模型,可以基于流方式来处理,具有表达能力强、扩展性好
等特点。可以把Playbook称为“可执行的文档”,就像README文件一样描述你需要部署软件的指令,由于这
些代码是可以直接执行的,这些指令永远不会过时。
2.不需要在被管节点安装客户端软件
Ansible运维管理系统的核心是通过 SSH来连接被管节点,可以使用Paramiko(一个Python库)或使用
原生的OpenSSH(带参数-c ssh)。当使用SSH客户端连接的时候,默认的OpenSSH连接是可以重用的。无
论哪种方式,SSH都是作为一种传输方式,不是作为一种执行的Shell。
Ansible模块是包含一些参数的Ansible小程序,通过SCP或SFTP传送到远端被管机器的临时目录中进行
执行,然后再删除。这些模块通过标准的输出方式返回JSON格式的数据,这些返回的数据通过控制主机上
的Ansible程序进行处理。这种方式能管理非常多远程活动,并且只需要很小的交互流量。模块按照“幕等资
源”的方式进行管理,也就是发起多次执行也不会给服务带来负面响应。它不是简单的命令或脚本,例如一
个模块可以确定应该安装某个特定版本的软件包,但如果这个系统已经有合适的工作状态,就不会再执行任
何命令。这种方式有如下优点:
提高网络安全:由于不需要在远端被管节点上运行Agent,因此 Ansible遭受攻击的机会很少。只需要运
行OpenSSH一个后台进程,OpenSSH在全球范围内是最严格审查的程序之一。Ansible知道做好加密是一项
极其艰难的事情,因此没有考虑使用自己的后台进程和认证方式,而是依赖可用的最安全的远程管理方式。
OpenSSH极其广泛地在各种系统中使用,属于非常轻量级。一旦Open SSH出现安全问题,将会非常快速地
推出补丁修复。
可以使用非root用户访问(可用sudo) : Ansible Playbook能够用任何用户账号登录远程系统,可以用初
始连接的用户来运行程序,也可以使用sudo切换到其他用户(包括root)。如果需要,可以直接用root登
录,sudo可以需要口令,也可以不需要口令,当管理的一些系统根本不能使用root登录的时候,或者不允
root登录但可以通过sudo切换到root的,这种方式是非常合适的。
限制传输潜在敏感数据:Ansible总是尽量把最少的数据传输到被管节点,由于控制服务器是逻辑控制
中心,只有远端被管节点必要的变量才送给它。例如,有个全局变量叫foo,只有在远端被管节点中明确在
资源或模板中使用它,否则它不会发送到该远端节点。这种Ansible的推送方式,只给远端节点需要看到的
最少数据。类似地,Ansible没有包含客户文件服务器的实现,只通过SFTP、SCP、Rsync(基于SSH)传
输文件,并且只有Playbook需要的文件才传输。结果是被管节点请求的文件或模板可以提供,但敏感数据不
会提供给。也就是不能给一台远程主机查看将要提供给其他被管节点的数据。这使得Ansible适用于带有敏
感数据的环境,包括社会科学工作、健康医疗、政府政务等应用。
(Credential Segregation凭证隔离): Ansible适用于不同用户有不同安全级别的环境。可以定义管理主
机的通用变量,然后使用自己的凭证访问远端节点。例如,允许研发工程师管理开发的服务器,QA工程师
管理QA的服务器,系统管理员管理生产环境服务器,不存在研发工程师把代码推送到生产环境的风险。
去中心化:由于Ansible Playbook需要用户的凭证来执行,不存在中心点,只是通过访问配置内容、管
理软件链条,不需要访问SSH密钥,就可以接管建立“僵死网络”,避免使它成为攻击的目标。用户可以加
密自己的密钥,不需与任何人使用相同密码。在可选的管理形式中,访问授权的软件资源都有可能导致部
署系统自动化。要使用Ansible,用户需要两个条件:能够访问到资源库,具有管理远端节点的凭证。当使
用锁定的密钥(甚至是密码)时,不存在暴露安全漏洞中心被攻击点,也不允许从远端硬件来访问管理服
务器。
没有“管理的管理程序”的问题:许多配置管理解决方案的主要问题之一是“管理的管理”,为了开始管
理服务器必须先在远端节点上安装软件。当更新管理软件的时候,通常各种Agent需要先更新(许多系统是
无法自己自动更新的)。有时会产生管理服务器与Agent软件版本兼容性问题,或Agent与运行语言版本问
题,Ansible通过基于SSH传输模块避免了这类问题。SSH二进制代码已经是OS的一部分了,并且是每个主
流操作系统的核心。不需要任何Agent,也就不存在Agent以任何方式崩溃的问题,因此服务器存在的安全
风险是非常小的。
管理服务器的可扩展性:由于Ansible使用推送方式来管理远端节点(当然,也很容易配置成远端节点
查询更新的方式),因此Ansible对于“羊群效应”的管理问题是有免疫能力的。在其他的一些解决方案中,
管理Agent周期性检查会对管理服务造成破坏,经常会超过管理服务器的运行负荷,导致需要对管理服务器
进行横向或纵向扩展。频繁管理服务器需要为远端节点消耗昂贵的计算资源。为了解决这个问题,Ansible
通过推送的方式,通过配置每次推送节点数量来做限制。均衡了远程节点需要的管理服务器的负载能力,可
以让计算系统负载更加均衡,即使个人笔记本电脑也可以作为Ansible系统的控制服务器。
资源的利用:在Ansible不管理远端节点时,这些远端节点什么也不做,也就是没有后台进程在消耗
CPU、内存。曾经报道过,某些应用服务器在唤醒配置窗口时会产生明显的降低性能,某些 Agent可能会占
用超过400MB的内存。在虚拟化环境中,这些资源的消耗可能会快速叠加,就会增加对硬件的支出。Ansi-
ble能最大限度让你的关键性能负荷使用所有的计算资源,你也可以选用间隔方式运行管理程序,也不存在
由于内存泄漏或Agent软件崩溃导致无法管理远端节点的问题。
防火墙的友好性和确定性:不像某些基于消息总线的系统,Ansible不需要长时间在控制节点与被管主机
之间建立连接。在生产环境,这种长连接可能受限于防火墙,防火墙一般不喜欢长连接,Ansible很好地规避
了这个问题。当管理服务与应用之间的连接被断开又没法重置的时候,就只能等到重启Agent端服务了,
Ansible没有这个问题。没有严格意义上的无代理系统,Ansible也避免在这些架构中的其他问题,获得确定
性的响应。并不是只有出现响应节点才管理,对于你要管理但无法达到的就静默了。如果一个节点宕机,运
行Ansible时你就会知道,将会返回一个失效信息,这个你可能忽略或修复。这对于你给所有节点或部分子
集部署软件更新,是很重要的信息,知道哪些节点无法连接是非常重要的。
3.基于推送(Push)方式
有些运维管理工具(如Chef、Puppet、Saltstack等)是使用代理模式的,它们默认基于拉(Pull)方
式。被管节点上安装代理后,代理服务将周期性检查中心控制主机的服务,并从控制主机上取来配置信息。
被管节点的变更过程大致如下:
修改配置管理脚本。
把修改好的管理配置脚本推送到中心控制主机上。
被管节点的代理服务周期性触发检查。
被管节点连接配置管理的控制主机。
被管节点下载新的配置管理脚本。
被管节点在本地执行配置管理脚本,被管节点状态相应地变化。
而Ansible默认基于推送(Push)方式,管理过程如下:
增加或修改Playbook。
执行新的Playbook。
控制节点的Ansible连接被管节点并执行修改被管节点状态的模块。
一旦你执行ansible-playbook命令,Ansible就会连接到远程的被管节点并按照脚本要求执行。基于推送
方式有很大的优势,你能控制什么时候让远程被管节点发生变更,不需要等到被管节点上周期性的时间。拉
方式的支持者声称拉方式具有管理服务器规模数量的优势,新被管节点随时可以在线添加。但是Ansible已经
在管理超过上万台节点规模的系统,很方便地动态增减或删除被管节点。当然,如果你一定要使用拉方式,
Ansible官方也已经支持这种拉方式,可以使用ansible-pull这个工具。
4.方便管理小规模场景
Ansible能够管理成千上万台主机,但如何管理缩小规模的场景呢?其实,用Ansible也很容易配置小规
模集群甚至单台主机,你只要简单编写一个Playbook即可。
5.大量内置模块
使用Ansible能够在被管节点上执行任何Shell命令,但是 Ansible真正的威力在于内置大量的模块。使用这
些模块可以完成如软件包安装、重启服务、拷贝配置文件等操作。Ansible模块是声明式的(Declarative),
你只需使用这些模块描述被管节点期望达到的状态。例如,你可以用user模块对用户授权,确保系统有一个
deploy用户,并且属于web组,代码如下:user: name=deploy group=web
Ansible内置模块都是等幕性的(Idempotent)。这就是如果系统中没有用户deploy, Ansible将会创建一
个deploy账号;如果这个账号已经存在,则Ansible什么也不做。等幕性对于自动化维护是非常重要的特性,
这样在被管节点上多次执行AnsiblePlaybook 也能达到同样效果。相对于直接执行操作系统脚本的方式是巨
大的改进,操作系统脚本再执行一次可能就会产生不同的、非预期的结果。
6.非常轻量级的抽象层
有些配置管理工具通过一个抽象层,可以把相同的脚本在不同的操作系统上管理。例如,安装软件包有
yum、apt工具,对于配置管理工具就可能抽象成package。Ansible不同于这种方式,你需要使用apt模块来
安装基于apt软件管理的系统,用yum模块来安装基于 yum软件管理的系统。这听起来也许不太方便,在实
践中我们发现这使得Ansible更方便使用。Ansible不需要再学新知识来屏蔽不同操作系统的差异性、新的抽
象环境。这相对减少了Ansible要求的知识领域。这样,你不需要了解太多就可以编写Playbook了。如果你
确实需要,你也可以在Ansible Playbook中对不同被管节点的操作系统编写不同的动作脚本。但不太建议这
么做,建议编写针对特定操作系统的Playbook,如CentOS、Ubuntu。
1.4 Ansible与其他运维管理工具的对比
当前几款与Ansible功能类似的主流配置管理软件有Chef、Puppet、SaltStack等,这里只对各个软件的
技术特性做个简单对比,其中不针对各个软件的性能作比较。具体内容见下表:
与其他的自动化工具相比较,Ansible不需要安装管理客户端就能轻松地管理、配置你的基础架构。它
们各自的优缺点见下表所示:
这些自动化管理软件都具备强大的功能、灵活的系统管理和状态配置,都提供丰富的模板及API,对云
计算平台、大数据都有很好的支持。Puppet、Chef、SaltStack设置比较复杂,有代理和服务,有远程被管
节点需要长期运行管理进程,而且很多术语和概念都是自己一套。Ansible相对于其他产品要简单得多,本
质上混合了声明式和命令式。不仅适用于大规模的IT环境,而且对于一些规模较小的环境(20-50台机器)
Ansible也是很实用的。
2 Ansible软件部署与配置
2.1 本章价值
通过本章节,您将学习到如何通过安装包的方式安装Ansible软件(YUM源配置,依赖模块及安装包安
装),配置Ansible相关参数,建立Ansible服务端与客户端互信,进行必要的Ansible服务端与客户端连通性
测试,极快速地搭建一整套基于Ansible的自动化运维环境。另外,对于客户端Python版本不符合要求的,
本章节也将介绍如何快速批量完成安装。
2.2 Ansible软件安装
Ansible软件安装的方式较多,非常灵活,可以满足各种环境的部署需求。一般可以直接用源码进行安
装,包括从GitHub源码库安装方式、TAR包安装、制作RPM包安装等。也可用操作系统软件包管理工具进
行安装,包括YUM安装(适合Fedora、RHEL、CentOS)、APT安装(适合Ubuntu)、Homebrew安装(适
合Mac OS X)、PIP安装等。其中大部分安装方式需要服务端连通公网,下面不一一介绍,仅详细介绍如
何在生产环境,无法连接外部互联网的条件下,通过TAR包的安装方式,快速搭建Ansible整套环境,包含
一套Ansible服务端和千余个生产环境Ansible客户端环境。整个搭建耗时约1-2天。下面演示的服务端操作
系统版本为RHEL6.6x86_64,该操作系统自带Python2.6.6(要求Version>=2.6),所有安装包的下载地址
为:http://www.talkwithtrend.com/Document/detail/tid/404677
1.配置YUM源
如果有专门的YUM服务器,可以直接配置如下:
cat /etc/yum.repos.d/rhel-source.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
如果没有专门的YUM服务器,可以先将RHEL6.6的ISO文件传至服务端,并用以下命令挂载:
mount -o loop -o ro /tmp/rhel6.6_x86_64.iso /mnt
再配置本地YUM源:
cat /etc/yum.repos.d/rhel-local.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
2.ansible依赖模块及安装包的安装
安装setuptools-7.0
tar -xvf setuptools-7.0.tar
cd setuptools-7.0
python setup.py instal
安装pycrypto-2.6.1
gzip -dc pycrypto-2.6.1.tar.gz|tar -xvf -
cd pycrypto-2.6.1
python setup.py install
安装包错解决:
报错1:
running install
running build
running build_py
running build_ext
running build_configure
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ansible/pycrypto-2.6.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
解决办法:yum install gcc
报错2:
解决办法:yum install python-devel
最后pycrypto安装成功。
安装PyYAML模块
安装yaml-0.1.5:
tar -xvf yaml-0.1.5.tar
cd yaml-0.1.5
./configure --prefix=/usr/local
make --jobs=`grep processor /proc/cpuinfo|wc -l`
make install
安装PyYAML-3.11:
gzip -dc PyYAML-3.11.tar.gz|tar -xvf -
cd PyYAML-3.11
python setup.py install
安装Jinja2模块
安装MarkupSafe-0.9.3:
tar -xvf MarkupSafe-0.9.3.tar
cd MarkupSafe-0.9.3
python setup.py install
安装Jinja2-2.7.3
gzip -dc Jinja2-2.7.3.tar.gz|tar -xvf -
cd Jinja2-2.7.3
python setup.py install
安装Paramiko模块
安装ecdsa-0.11:
gzip -dc ecdsa-0.11.tar.gz|tar -xvf -
cd ecdsa-0.11
python setup.py installs
安装paramiko-1.15.1:
gzip -dc paramiko-1.15.1.tar.gz|tar -xvf -
cd paramiko-1.15.1
python setup.py install
安装ansible-stable-2.3
unzip ansible-stable-2.3.zip
cd ansible-stable-2.3
python setup.py install
至此,Ansible软件在服务端的安装工作全部完成。
2.3 Ansible软件配置
1.配置Ansible变量环境
Ansible配置文件是以ini格式存储配置数据的,在Ansible中,几乎所有的配置项都可以通过Ansible的
Playbook或者环境变量来重新赋值,在运行Ansible命令时,命令将会按照预先设定的顺序查找配置文件,
如下所示:
ANSIBLE_CONFIG:首先,Ansible命令会检查该环境变量,及这个环境变量所指向的配置文件。
./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件。
~/.ansible.cfg:再次,将会检查当前用户home目录下的ansible.cfg配置文件。
/etc/ansible/ansible.cfg:最后,将会检查在用软件包管理工具安装Ansible时自动产生的配置文件。
在这里我们在/etc/profile中,增加一行:
export ANSIBLE_CONFIG=/etc/ansible/ansible.cfg
在用户登录时,都将设置该环境变量。
2.配置Ansible配置文件
由于是TAR包安装,Ansible的目录及相关文件都需要自己创建:
mkdir /etc/ansible
cd /etc/ansible
touch ansible.cfg hosts
修改/etc/ansible/ansible.cfg的内容:
cat /etc/ansible/ansible.cfg
#defaults这一行是需要的
[defaults]
#inventory代表所管理的主机清单的文件位置
inventory = /etc/ansible/hosts
#library参数就是指向存放ansible模块的目录(ansible基于模块工作,本身没有批量部署的能力,真正
具有批量部署的ansible所运行的模块)
library = /usr/share/ansible/my_modules
#设置默认情况下ansible最多能有多少个进程同时工作
forks = 50
#设置默认执行命令的用户,可以在playbook中重新指定该参数
sudo_user = ansible
#指定连接被管节点的ssh端口,可以在hosts文件中,单独指定被管主机的ssh端口
remote_port = 22
#设置模块的语言
module_lang = C
#设置ansible服务端连接客户端的私有ssh key文件位置
private_key_file = /root/.ssh/id_rsa
#设置是否检查ssh主机的密钥
host_key_checking = False
#设置ssh连接的超时时间,单位秒
timeout = 60
#设置把ansible系统的输出记录到日志文件中
log_path = /tmp/ansible.log
2.4 Ansible客户端互信配置
按照以下步骤建立Ansible服务端与客户端间的互信关系,可以是root用户和root用户,也可以是非root
用户和非root用户间。
在Ansible服务端生成ssh public和private key:
ssh-keygen
将ssh public key下发到被管节点的.ssh目录:
ssh-copy-id -i /root/.ssh/id_rsa.pub client_ip
为了提高效率,可以将所有需要添加互信的client的ip地址编入文件/tmp/clienthosts.txt,并批量
下发到被管节点。
a=`cat /tmp/clienthosts.txt`
for i in $a
do
ssh-copy-id -i /root/.ssh/id_rsa.pub $i
done
然后每个建立互信过程时,输入“yes”和client密码,这样下次服务端就可以直接通过ssh连接客户
端了。
2.5 Ansible客户端Python与Simplejson环境安装
1.Ansible客户端环境的需求
被管理的服务器(Ansible客户端)需要安装python2.4以上的版本,如果python版本低于2.5,但不想安
装更高版本的python,对于Linux操作系统而言,可以安装python-simplejson模块来解决。
2.AIX操作系统python的批量安装
为了加快Ansible客户端环境的部署效率,可以通过以下批量python环境的安装步骤进行:
将以下AIX python的安装文件传至Ansible服务端的/tmp目录,版本满足要求即可:
gdbm-1.8.3-2.aix5.1.ppc.rpm
readline-4.3-2.aix5.1.ppc.rpm
expat-2.0.1-2.aix5.3.ppc.rpm
python-2.6.2-2.aix6.1.ppc.rpm
编辑文件/tmp/clienthosts_aix.txt将所有AIX的IP地址输入至该文件,并运行命令:
b=`cat /tmp/clienthosts_aix.txt`
for i in $b
do
scp /tmp/gdbm-1.8.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/readline-4.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/expat-2.0.1-2.aix5.3.ppc.rpm $i:/tmp
scp /tmp/python-2.6.2-2.aix6.1.ppc.rpm $i:/tmp
done
检查AIX客户端是否已经安装了python
for i in $b
do
ssh $i which python
done
如果安装了python,版本也大于等于2.6,可以重新编辑/tmp/clienthosts_aix.txt将该ip地址去掉。
未安装python的AIX客户端开始安装:
c=`cat /tmp/clienthosts_aix.txt`
for i in $c
do
ansible $i -m raw -a "cd /tmp;rpm -ivh gdbm-1.8.3-2.aix5.1.ppc.rpm;rpm -ivh readline-4.3-2.aix
5.1.ppc.rpm;rpm -ivh expat-2.0.1-2.aix5.3.ppc.rpm;rpm -ivh python-2.6.2-2.aix6.1.ppc.rpm"
done
由于Ansible服务端需要和安装了python的客户端才能通信,但是在客户端没有安装python前,可以通
过Ansible的raw模块直接通信,并安装python,用这种方式实现批量安装的目的。
3.Linux批量安装simplejson
Linux操作系统基本都自带python环境,所以只需要关注python版本即可,对于Linux python version<2.5
的操作系统环境,可以通过安装simplejson解决。
单机安装simplejson-3.6.5:
gzip -dc simplejson-3.6.5.tar.gz|tar -xvf -
cd simplejson-3.6.5
python setup.py install
批量安装simplejson-3.6.5:
将simplejson-3.6.5.tar.gz传至Ansible服务端的/tmp目录
拷贝simplejson-3.6.5.tar.gz至需要安装的客户端
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
scp /tmp/simplejson-3.6.5.tar.gz $i:/tmp
done
开始批量安装simplejson
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
ansible $i -m raw -a "gzip -dc simplejson-3.6.5.tar.gz|tar -xvf –;cd simplejson-3.6.5; python
setup.py install"
done
批量安装都是用类似的方法,这里也不再一一举例。
2.6 Ansible服务端与客户端连通性测试
1.查看ansible版本
"failed": true,
"module_stderr":"Shared connection to X.X.X.X closed.\r\n",
"module_stdout": "/bin/sh: /usr/bin/python: not found.\r\n"
"msg": "MODULE FAILURE",
"rc": 0
}
如果遇到这些报错,这里只需要按照上面所介绍的批量安装方式安装即可。
3 Ansible软件配置优化
3.1 本章价值
鉴于Ansible服务端使用了默认的SSH无代理方式与客户端通信,效率远低于有代理的通讯方式,然而
通过本章节,您将学习到如何通过配置优化,来加速Ansible的执行速度,以提高自动化运维的工作效率,
做到等同于有代理通讯方式的效率:包括如何开启SSH长连接,避免SSH短连接的通信开销;开启Pipelin-
ing,利用SSH会话来缩短PUT脚本至远端客户端执行的流程;开启Accelerate模式,利用远端客户端上运行
的守护进程,优化Ansible的执行流程;在Playbook中修改Ansible的执行策略,减少多主机批量执行过程的
等待;在Playbook中使用异步特性,减少执行任务的同步等待;设置Facts缓存,通过提前将Facts信息缓存
于本地JSON文件、Redis或Memcached内存数据库中,来提高PlayBook的执行效率。
3.2 Ansible执行速度过慢问题
在测试连通性的过程中,利用前面的默认配置,发现有一个问题非常困扰,就是通过Ansible服务端向
客户端执行命令非常缓慢,主要体现在创建SSH的通道很慢,虽然Ansible在同一个task里面是并行的控制
多台受管端,但是每一个task都需要和受控端创建SSH通道,非常影响效率。由下面也能看出,一个简单的
PING命令都要耗时13秒以上。
time ansible test -m ping
X.X.X.X | SUCCESS => {
"changed": false,
"ping": "pong"
}
real 0m13.030s
user 0m1.147s
sys 0m0.263s
这种执行效率显然是无法接收的,那么接下来如何通过配置优化来提升Ansible的执行效率是势在
必行。
3.3 开启SSH长连接
我们知道Ansible模式是使用SSH和远端主机进行通信,所以Ansible对于SSH的依赖性非常强,下面我
们第一步就从SSH入手来优化Ansible。OpenSSH在5.6版本以后支持了Multiplexing(多路复用)功能,它支
持同一主机的多个SSH会话共享单一TCP连接进行通讯,一旦第一个连接建立,后续连接就不再需要凭证,
从而消除了每次连接同一机器都需要键入密码的麻烦并且大幅度节省了服务器端的资源,这种功能也称作长
连接机制。
如果Ansible中控机的SSH -V版本高于5.6时,我们可以直接在ansible.cfg文件中设置SSH长连接即
可。设置参数如下:
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=5d
Contro1Persist=5d这个参数是设置整个长连接的保持时间,默认值为60秒,这里设置为5天,如果开
启后,通过SSH连接过的设备都会在用户当前目录的~/ansible/cp/目录下生成一个socket文件,每个会话一
个文件,以便相同连接复用,也可以通过netstat命令查看,会发现有一个ESTABLISHED状态的连接一直与
远端设备进行着TCP连接。如果长连接时间超过Contro1Persist的设定值,连接将被断开,socket文件也将
被清理。另外,如果不仅仅需要Ansible开启SSH长连接,SSH命令也保持长连接的话,可以修改Ansible中
控端的SSH CLIENT的全局性配置文件:/etc/ssh/ssh_config,或者修改当前用户的~/.ssh/config文件,仅
使本用户生效:
ServerAliveInterval 30
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 5d
其中ServerAliveInterval表示client每隔30秒发送一次请求给server,然后server响应,从而保持连接;
ServerAliveCountMax表示client发出请求后,服务器端没有响应的次数达到3,就自动断开连接;ControlPath
表示socket的存放和复用路径。
如果我们的Ansible中控机SSH-V版本低于5.6时,则需要升级到5.6版本后才能启用SSH Multiplex-
ing特性。
通过SSH-V命令查看了下当前演示环境的OpenSSH的版本为:OpenSSH_5.3p1,这次需要将openssh
版本升级到OpenSSH_6.7p1,安装包的下载地址为:
http://www.linuxfromscratch.org/blfs/view/7.7/postlfs/openssh.html
升级过程如下:
查看是否缺少依赖包:
rpm -qa|egrep “gcc|make|perl|pam|pam-devel”
缺少了依赖包,可以通过YUM源直接安装这些缺少的包:
yum –y install gcc* make perl pam pam-devel
上传安装包:openssh-6.7p1.tar.gz
备份ssh:
mv /etc/ssh /etc/ssh.bak
编译安装新版本OpenSSH
gzip -dc openssh-6.7p1.tar.gz|tar -xvf –
cd openssh-6.7p1
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-zlib --with-md5-passwords
make
卸载旧版本OpenSSH
rpm -a|grep openssh
rpm -e `rpm –qa|grep openssh` --nodeps
安装新版本OpenSSH
make install
配置OpenSSH,主要是保证ssh-copy-id等命令能够正常使用
cd openssh-6.7p1
install -v -m755 contrib/ssh-copy-id /usr/bin
install -v -m644 contrib/ssh-copy-id.1 /usr/share/man/man1
install -v -m755 -d /usr/share/doc/openssh-6.7p1
install -v -m644 INSTALL LICENCE OVERVIEW README* /usr/share/doc/openssh-6.7p1
查看是否升级到了新版本
ssh –V
OpenSSH_6.7p1, OpenSSL 1.0.1e-fips 11 Feb 2013
复制启动脚本到/etc/init.d
cp /root/openssh-6.7p1/contrib/redHat/sshd.init /etc/init.d/sshd
将sshd加入开机自启动
chkconfig --add sshd
重新启动sshd
service sshd restart
执行速度验证
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:17 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m4.228s
user 0m2.591s
sys 0m0.327s
通过OpenSSH的版本升级,我们发现速度优化较为明显,执行速度为4秒左右。我们当然不然满足于
此,看看按照前面介绍的方式,开启Multiplexing功能特性后的Ansible执行速度又如何:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:31 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m3.075s
user 0m2.532s
sys 0m0.310s
执行速度又降低了1秒,看来复用了长连接,减少SSH的TCP通信开销还是有效果的。
3.4 开启Pipelining
Pipelining也是OpenSSH的一个特性,在Ansible的整个执行流程中,包含三个步骤:
首先,基于调用的模块生成一个Python脚本
其次,再将Python脚本复制到主机上
最后,在远端服务器上执行这个Python脚本
我们可以看到,其中有一个流程就是把生成好的本地Python脚本PUT到远端服务器执行,如果开启了
Pipelining,Ansible执行Python脚本的时候并不会复制它,而是通过管道传递给SSH会话,Ansible使用的
SSH会话将减少到一个,这样可以大大提高整个执行效率。尤其是在在部署大规模服务器或引用模块非常多
时,开启Pipelining特性会给Ansible带来更加显著的性能提升。下面我们通过一个示例展示整个过程。首先
在ansible.cfg配置文件中设置Pipelining。
[ssh_connection]
pipelining = True
再来看开启了Pipelining之后整个Ansible的执行流程有什么变化:
开启Pipelining之前的流程如下:
开启Pipelining之后的流程如下:
我们可以看到开启了Pipelining之后整个流程少了一个PUT脚本和SFTP去远端服务器的流程,且大量减
少了SSH连接次数,第一步就是直接调用ssh执行脚本。那么经过优化后的耗时又如何呢:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
ansible --version
ansible 2.3.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) [GCC 4.4.7 20120313 (Red Hat4.4.7-4)]
2.测试ansible服务端与客户端连通性
Ansible all -m ping
这时由于并非所有客户端都具备相应的条件,要么python未安装、要么python版本不符合要求,要么没
有安装ssh等,会报如下错误:
客户端python版本不符合要求:
X.X.X.X | FAILED! => {
"changed": false,
"failed": true,
"msg": "Error: ansible requires the stdlib json or simplejson module, neither was found!"
}
客户端未安装ssh:
X.X.X.X | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host x.x.x.x port 22: Connection
refused\r\n",
"unreachable": true
}
客户端未安装python:
X.X.X.X | FAILED! => {
"changed": false,
项目 Puppet SaltStack Ansible
开发语言 Ruby Python Python
是否有客户端 有 有 无
是否支持二次开发 不支持 支持 支持
服务器与远程机器
是否相互验证
是 是 是
服务器与远程机器
通信是否加密
是,标准 SSL 协议
是,使用 AES 加密 是,使用 OpenSSH
平台支持 支持 AIX、BSD、HP-UX
、
Linux、Mac OS X、
Solaris、Windows
支持 BSD、Linux、
Mac OS X、Solaris
、
Windows
支持 AIX、BSD、HP-UX
、
Linux、Mac OS X、
Solaris
是有提供 WEBUI 提供 提供 提供,不过是商业版本
配置文件格式 Ruby 语法格式 YAML YAML
命令行执行 不支持,但可通过配置
模块实现
支持 支持
产品 优势 劣势 成本
Puppet 1.模块由 Ruby 或 Ruby 子集编写
2.Push 命令能够立即触发变更
3.WEB 界面生成处理报表、资源
清单、实时节点管理
4.在代理运行端进行详细、深入
的报告和对节点进行配置
1.需要学习 Puppet
的 DSL 或 Ruby
2.安装过程缺少错
误检查和产生错误
报表
1.开源版本是免费的
2.Puppet 企 业 版 需
要每年每台花费$100
SaltStack 1.状态文件可以用简单的 YAML
配 置 模 板 或 复 杂 的
Python/PyDSL 脚本
2.与客户端通信可以基于 SSH 或
在被管节点安装代理
3.WEB 界面 可 以 看到运行的工
作、Minion 状态、事件日志、可
以在客户端执行命令
4.扩展能力极强
1.WEB 界 面 相对于
竞争产品还不太完
整、稳定
2.缺乏生成深度报
告的能力
1.开源软件是免费的
2.SaltStack 企业版
每年每个节点花费约
$150,随着数量增加
将有优惠折扣
Ansible
1.模块可以用任何语言开发
2.被管节点不需要安装代理
3.有 WEB 管理界面,可以配置用
户 、 组 、 资 源 清 单 和 执 行
Playbook
4.安装、运行极其简单
1. 对 被 管 节 点 是
Windows 的 管 理 有
待加强
2.WEB 管 理 界面是
内置 Ansible 的一
部分
3.需要导入资源清
1.开源版本是免费的
2.Ansible Tower 小
于 10 台时被管节点
免费
3.超过 10 台之后每
年 每 台 需 要 支 付
$100-$250 的支持服
15:38:26 up 881 days, 17:13, 0 users, load average: 0.00,0.00, 0.00
real 0m1.741s
user 0m1.429s
sys 0m0.176s
耗时又降低了1.3秒。
但是我们要注意,如果在Ansible中使用sudo命令的话,例如:ssh user@host sudo cmd,需要在被控
节点的/etc/sudoers中禁用"requiretty"。这是因为ssh远程执行命令时,它的环境是非登录式非交互式
shell,默认不会分配tty,没有tty,ssh的sudo就无法关闭密码回显(业可以在Ansible命令行中使用"-tt"参
数来强制SSH分配tty)。所以出于安全考虑,/etc/sudoers中默认是开启requiretty的,它要求只有拥有tty
的用户才能使用sudo,也就是说ssh连接过去不允许执行sudo。所以我们需要编辑sudo配置文件,通过注
释该选项来禁用它。如果我们在Playbook中不适用sudo越权功能,则不需要在被控节点的sudo配置文件中
禁用该选项。
3.5 开启Accelerate模式
除了OpenSSH上述两个功能之外,Ansible还有一个Accelerate模式,这和前面SSH Multiplexing功能有
点类似,因为都依赖Ansible中控机跟远端机器有一个长连接。但是Accelerate是使用Python程序在远端机器
上运行一个守护进程,然后Ansible会通过这个守护进程监听的端口进行通信。开启Accelerate模式很简单,
只要在Playbook中配置accelerate:true即可开启。但是需要注意,如果开启Accelerate模式,则需要在
Ansible中控机与远端机器都安装python-keyczar软件包,软件包的下载地址如下:
http://rpm.pbone.net/index.php3/stat/4/idpl/49957349/dir/redhat_el_6/com/python-keyczar-0.71c-
1.el6.noarch.rpm.html
安装python-keyczar软件包,中控机和远端都需要安装。远程批量安装可以参考采用之前所介绍的
方式实施。
yum install python-pyasn1
rpm -ivh python-keyczar-0.71c-1.el6.noarch.rpm
定义ansible.cfg文件中Accelerate参数,例如远端机器的监昕端口以及timeout设置。当然这些参数
也可以在写playbook的时候再定义:
[accelerate]
accelerate_port = 5099
accelerate_timeout= 30
accelerate_connect_timeout= 5.0
在Playbook中定义Accelerate,例如:
---
- hosts: all
accelerate: true
accelerate_port: 5099
然而,RedHat官方目前不赞成使用Accelerate模式。因为在启用ControlPersist和Pipelining管道的情况
下,Ansible的执行效率比较高。Accelerate功能在后面的Ansible版本中将被删除。
3.6 修改Ansible执行策略
默认Ansible在远程执行任务是按批并行执行的,一批控制多少台主机由命令行的-f参数或ansible.cfg配
置中的--forks选项控制。例如,默认的并行进程数是5,如果有20台被控主机,那么只有在每5台全部执行
完一个任务才继续下一批的5台执行该任务,即使中间某台机器性能较好,完成速度较快,它也会空闲地等
待在那,直到所有20台主机都执行完该任务才会以同样的方式继续下一个任务。
在Ansible 2.0版本后,添加了一个策略控制选项strategy,默认值为"linear",即上面按批并行处理的方
式。我们还可以设置strategy的值为"free"。在free模式下,Ansible会尽可能快的切入到下一个主机。同样
是上面的例子,首先每5台并行执行一个任务,当其中某一台机器由于性能较好提前完成了该任务,它不会
等待其他4台完成,而是会跳出该任务让Ansible切入到下一台机器来执行该任务。也就是说,这种模式下,
一台主机完成一个任务后,另一台主机会立即执行任务,它是"前赴后继"的方式。所以这种策略的执行结果
给人感觉是无序的甚至是杂乱无章的,而且每次执行结果的Task显示顺序很可能不一样。利用Playbook,
这两种策略的设置的方式如下:
---
- hosts: all
strategy: free
tasks:
...
3.7 任务执行优化
默认情况下Playbook中的任务在执行时会一直保持连接,直到该任务在每个主机节点都执行完毕,下一
个任务才会开始执行。有时这是不必要的,比如有些操作运行时间比SSH超时时间还要长。解决该问题最简
单的方式是一起执行它们,然后轮询直到任务执行完毕,简单的意思就是,像下面的例子,执行任务后,
Ansible就不等它了,往下执行下一个任务,然后每隔5秒钟去看看它执行完成没,超时时间为45秒,async
参数值代表了这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。如果
async参数若未设置,则为同步执行。我们也可以对执行时间非常长(有可能遭遇超时)的操作使用异步模
式。为了异步启动一个任务,可以指定其最大超时时间以及轮询其状态的频率。如果没有为 poll 指定值,那么
默认的轮询频率是10秒钟。
---
- hosts: all
remote_user: root
tasks:
- name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
command: /bin/sleep 15
async: 45
poll: 5
在异步执行任务时,需要注意那些有依赖性的任务。对于那些对资源要求占有排它锁的任务,如yum,
不应该将Poll的间隔设置为0。如果设置为0,很可能会导致资源阻塞。总结来说,大概有以下一些场景需要使
用到Ansible的异步特性:
某个Task需要运行很长的时间,这个Task很可能会达到ssh连接的Timeout。
没有任务是需要等待它才能完成的,即没有任务依赖此任务是否完成的状态。
需要尽快返回当前shell的。
当然也有一些场景不适合使用异步特性:
这个任务是需要运行完后才能继续另外的任务的。
申请排它锁的任务。
3.8 设置Facts缓存
当我们用ansible-playbook执行Playbook的时候,我们会发现,默认第一个Task都是GATHERING
FACTS,这个过程就是Ansible收集每台主机的Facts信息,方便我们在Playbook中直接引用Facts里的信息。
当然如果我们的Playbook中不需要Facts信息,可以在Playbook中设置gather_facts: False来提高Playbook的
效率:
---
- hosts: 10.0.108.2
gather_facts: no
tasks:
...
也可以在ansible.cfg文件中添加如下配置来默认禁用Facts采集:
[defaults]
gathering = explicit
但是如果我们既想每次执行Playbook的时候都能收集Facts信息,又想加速这个收集过程,这时候可以
设置Facts的缓存。例如,在空闲的时候收集Facts,缓存下来,在需要的时候直接读取缓存进行引用,直到
缓存过期。目前Ansible支持使用Json文件,Redis、Memcached内存数据库来存储Facts信息。
Json文件缓存Fact信息
使用Json文件作为Fact缓存后端时,Ansible将会把采集的Fact写入Ansible中控机的上的文件中。如果
系统中已经存在这个文件,那么Ansible将使用这个文件中的数据,而不再连接到主机去采集Fact。下面我
们首先通过示例来了解如何使用Json文件存储Facts信息,在ansible.cfg文件中添加:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_fact_cache
Ansible的配置文件中可以修改gathering的值为smart、implicit或者explicit。
smart表示默认收集Facts,但Facts已有的情况下不会收集,即使用缓存Facts;
implicit表示默认收集Facts,要禁止收集,必须使用gather_facts: False;
explicit表示默认不收集,要显式收集,必须使用gather_facts: Ture;
在使用Facts缓存时(即设置为smart),Ansible支持两种Facts缓存:redis和jsonfile。这里设置Facts过期
时间为86400秒(会根据文件的最后修改时间来确定Facts信息是否过期),Json文件存放在/tmp/ansi-
ble_fact_ cache下,下面我们执行一下Playbook:
我们再执行Playbook的时候就没有Facts收集这个过程了。直接从Json文件中读取Facts缓存信息:
可以看到10台受控机的执行耗时仅1.8秒,效率是非常不错的。
Redis缓存Fact信息
由于目前Ansible Facts缓存还不支持远端,所以需要在 Ansible中控机上安装Redis服务,并安装Redis
Python模块。
如何安装在,这里不再赘述,有兴趣可以去下载安装包安装。Redis配置ansible.cfg文件如下所示:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
Memcache缓存Fact信息
Ansible Facts存储还支持Memcached 存储,配置方法也很简单,在安装完Memcached服务并运行后,
同时安装Python的Memcached依赖包,最后配置ansible.cfg即可:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = memcached
4 Ansible软件日常维护和使用
4.1 本章价值
通过本章节,您将学习到如何维护Ansible的Inventory,来管理不同业务的不同机器,以便后续灵活的
对它们进行自动化运维操作;同时您也将学习到如何使用Ansible的一些常用组件,包括如何通过AD-Hoc命
令行的方式使用Ansible的各种模块,完成一些基本的自动化运维工作;如何编写和使用Playbook,来完成
复杂环境下的自动化运维工作;如何利用Facts组件来采集被管客户端的设备信息,来实现配置管理系统(
CMDB)的自动采集能力等等。
4.2 Ansible Inventory维护
Inventory文件
在日常维护中,Ansible通过Inventory(可管理的主机集合),对远端服务器或者主机进行统一操作和
管理。在Ansible中,描述主机的默认方法是将他们列在一个文本文件中,这个文件称为Inventory文件,默
认的路径和文件为:/etc/ansible/hosts,可以通过ANSIBLE_HOSTS环境变量来指定,也可以在ansible.cfg
文件中通过inventory参数指定,或者在运行ansible和ansible-playbook的时候使用-i参数来临时指定。
下面举例说明,如何在inventory组件的/etc/ansible/hosts文件中定义主机和主机组:
1 X.X.X.100 ansible_ssh_pass='123456'
2 [groupname1]
3 X.X.X.10[1:9]
4 X.X.X.20[1:9]
5 [groupname1:vars]
6 ansible_ssh_pass='123456'
7 [groupname2:children]
8 groupname1
第一行定义了一个主机X.X.X.100,并使用inventory内置变量ansible_ssh_pass定义了该主机的登录密
码,如果建立了互信,则不需要这个参数;
第二、三、四行定义了一个名为groupname1的主机组,其中包含X.X.X.101-X.X.X.109,
X.X.X.201-X.X.X.209共计18台主机;
第五、六行为groupname1的主机组定义了一个共同的变量:ansible_ssh_pass,以定义该组内所有主
机的登录密码;
第七、八行定义了一个更大的组:groupname2,其下包含了groupname1组下的所有主机。
定义好之后,我们在ansible命令行和ansible-playbook中,可以非常灵活的使用,便于批量操作。例如
批量查看groupname1组下所有主机的当前时间:
ansible groupname1 -a date
Inventory内置参数
除了前面介绍的ansible_ssh_pass参数,Ansible Inventory内置了一些参数,这些参数在我们实际工作
中也会经常使用,我们可以直接在Inventory文件中定义它。
我们也可以在ansible.cfg文件中的[defaults]部分更改一些Inventory内置参数的默认值,可以支持更改
的有:
动态Inventory
在实际的应用中,会存在大量的主机列表信息,如果手动维护Ansible中的Inventory文件将会非常的繁
琐,所以支持动态Inventory将会让问题变得统一、清晰、简单许多。动态Inventory也就是Ansible所有的
Inventory文件里面的主机列表和变量信息都支持从外部拉取,例如我们常用的CMDB,我们可以通过定义的
脚本,将外部CMDB等其他运维系统中的主机信息同步至Ansible中。在实际的配置中仅需要更改ansible.cfg
文件中的inventory参数为一个可执行的脚本即可。
[defaults]
inventory = /etc/ansible/inventory.sh
脚本的内容不受任何编程语言限制,但该脚本必须支持以下规范的参数,脚本的执行结果也有一定的
要求:
--list或者-l,脚本运行该参数须显示所有主机和组的信息(Json格式)。
--host或者-H,脚本的该参数后需指定一个主机,运行结果也会返回该主机的所有信息(同样也必须
为Json格式)。
脚本调试好之后,ansible将利用inventory变量所指向的脚本,获取主机和组信息(或者通过-i参数指
定),来向主机执行命令。
Inventory分割
如果我们想要同时使用常规Inventory文件和动态Inventory脚本,或者按不同业务/系统分割成的多个
Inventory文件,我们可以把所有这些文件全部都放到同一个目录,并配置ansible.cfg文件的hostfile参数,让
Ansible使用hostfile参数所指定的目录作为Inventory即可,也可以在命令行中使用-i命令来指定特定的
Inventory文件。Ansible将会处理目录里所有的文件并将结果合并为一个完整的Inventory。
[defaults]
hostfile = /etc/ansible/inventory
4.3 Ansible Ad-Hoc命令使用
Ansible系统由控制主机对被管节点的操作方式可分为两类,即 Ad-Hoc和Playbook:
Ad-Hoc模式使用单个模块,支持批量执行单条命令。
Playbook模式是Ansible主要管理方式,也是Ansible功能强大的关键所在,Playbook通过多个Task集合
完成一类功能,如 Web 服务的安装部署、数据库服务器的批量备份等,可以简单地把 Playbook理解为通过
组合多条Ad-Hoc操作的配置文件。
下面将通过两个小节的内容,来说明如何使用Ad-Hoc和Playbook。其中Ad-Hoc将重点介绍命令参数
和几个常用的模块。
通常我们会以命令行的形式使用Ansible模块,或者将Ansible命令嵌入到脚本中去执行。Ansible自带了
很多模块,我们可以直接使用他们。当我们不知道如何使用这些模块时,可以ansible-doc命令获取帮助,
例如:使用“ansible-doc -l”命令可以显示所有自带的模块和相关简介,使用“ansible-doc 模块名”命令可以
显示该模块的参数及用法等内容。
Ansible Ad-Hoc命令参数
我们可以使用“ansible -h”命令来列出所有的命令参数,下面列举了常用的一些参数,部分参数如果不
指定将采用ansible.cfg中的设置值,或者采用原始默认值。
Ansible常用模块介绍
连通性测试
通常采用Ping模块来测试远程主机的运行状态:
ansible ip -m ping
执行命令
执行命令可以采用四种方式,第一种方式是利用Command模块在远程主机上执行命令,但Command
模块不支持管道命令,例如,查看某个主机的日期:
ansible ip -m command -a date -o
值得注意的是,Ansible默认的模块是Command,所以上面的命令可以简化为:
ansible ip -a date -o
第二种方式是利用Shell模块,切换到某个Shell执行远程主机上的Shell/Python脚本,或者执行命令,
Shell支持管道命令,功能较Command更强大灵活,例如:
ansible ip -m shell -a 'bash /root/test.sh' -o
ansible ip -m shell -a 'echo "123456"|passwd --stdin root'
第三种方式是利用Raw模块,Raw支持管道命令。Raw有很多地方和Shell类似,但是如果是使用老版本
Python(低于2.4),无法通过Ansible的其他模块执行命令,则需要先用到Raw模块远程安装Python-sim-
plejson后才能受管;又或者是受管端是路由设备,因为没有安装Python环境,那就更需要使用Raw模块去
管控了。例如:
ansible ip -m raw -a "cd /tmp;pwd"
第四种方式是利用Script模块,传输Ansible中控端上的Shell/Python脚本到远端主机上执行,即使远端
主机没有安装Python也可以执行,有点类似Raw模块。但Script只能执行脚本,不能调用其他指令,且不支
持管道命令,例如:
ansible ip -m script -a '/root/test.sh' -o
removes参数用来判断远端主机上是不是存在test.sh文件,如果存在,就执行管控机上的test.sh,不存
在就不执行:
ansible ip -m script -a 'removes=/root/test.sh /root/test.sh' -o
creates用来判断远端主机上是不是存在test.sh文件,如果存在,就不执行,不存在就执行管控机上的
test.sh文件:
ansible ip -m script -a 'creates=/root/test.sh /root/test.sh' -o
复制文件
常用的文件操作模块就是Copy模块,它主要用于将本地或远程机器上的文件拷贝到远程主机上。其主
要参数有以下几个:
复制本地文件的到远程主机:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh'
复制并修改文件的权限:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755'
复制并修改文件的属主:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755 owner=root'
复制文件前备份:
ansible ip -m copy -a 'src=test.sh backup=yes dest=/tmp'
服务管理
在Ansible Ad-Hoc中,Service模块可以帮助我们管理远程主机上的服务。例如,启动或停止远程主机
中的某个服务。但是该服务本身必须要能够通过操作系统的管理服务的组件所管理,例如Redhat6中默认通
过SysV进行服务管理,Redhat7中默认通过Systemd管理服务,如果该服务本身都不能被操作系统的服务管
理组件所管理,那么也不能被Service模块管理。该模块的几个常用参数如下:
启动服务:
ansible all -m service -a "name=sshd state=started"
停止服务:
ansible all -m service -a "name=sshd state=stopped"
开启服务自启动:
ansible all -m service -a "name=sshd enable=yes"
安装包管理
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
安装软件包:
ansible all -m yum -a 'name=nginx state=installed’
卸载软件包:
ansible all -m yum -a 'name=nginx state=removed'
临时启用local yum源安装最新版软件包:
ansible all -m yum -a 'name=nginx state=latest enablerepo=local'
用户管理
在Ansible Ad-Hoc中,可以通过User模块帮助我们管理远程主机上的用户,比如创建用户、修改用户、
删除用户、为用户创建密钥对等操作。该模块的几个常用参数如下:
增加用户、组和密码:
ansible ip -m group -a "name=testg”
ansible ip -m user -a "name=test group=testg password=123456 home=/home/test”
删除用户和用户主目录:
ansible ip -m user -a "name=test state=absent remove=yes"
4.4 Ansible Playbook使用
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
我们在使用Ansible时,绝大部分时间将花费在编写Playbook上,Playbook是一个Ansible术语,指的是
用于配置管理的脚本。Ansible的Playbook是使用YAML语法编写的。YAML是一种类似于Json的文件格式,
不过YAML更适合人来读写。我们在开始编写Playbook时,需要对YAML的语法有一定的了解,否则将经常
碰到语法错误。下面首先通过一个安装和配置ntpd服务的Playbook案例来介绍:
1 ---
2 - hosts: all
3 tasks:
4 - name: install ntpd Package
5 yum: name=ntp state=present
6 - name: copy ntp.conf
7 template: src=/tmp/ntp.conf.j2 dest=/etc/ntp.confowner=root group=root mode=0644
8 notify:
9 - restart ntpd service
10 handlers:
11 - name: restart ntpd service
12 service: name=ntpd state=restarted
第一行仅表示该文件为YAML格式文件,非必须。
第二行定义了该Playbook所针对的主机,all表示所有,也可以填写Inventory文件中的IP地址或者主机组
名称。
第三行表示下面开始定义Task任务。
第四、五行定义了一个具体Task任务(通过Yum安装ntpd服务),包含任务名称和执行动作,其中任
务名称为非必须,可以直接定义执行动作。
第六、七、八、九行定义了另一个具体Task任务(同步ntpd配置文件模板),并更改文件的属主、属
组和文件权限。notify和下面的handlers为配对使用,当ntpd配置文件模板同步至远端主机后,文件的MD5
值将发生变化,触发restart ntpd service这个handler。
第十、十一、十二行定义了上述handler的具体内容,包括名称和执行动作,也就是利用service模块来
重启ntpd服务。
编制好了Playbook,我们需要使用--syntax-check参数来对该脚本进行语法检查:
ansible-playbook ntpd.yaml --syntax-check
playbook: ntpd.yaml
语法检测过后,可以用--list-task参数来查看该Playbook中的所有Task:
ansible-playbook ntpd.yaml --list-task
playbook: ntpd.yaml
play #1 (X.X.X.2): X.X.X.2 TAGS: []
tasks:
install ntpd Package TAGS: []
copy ntp.conf TAGS: []
确认无误后,开始使用命令运行名为ntpd.yaml的Playbook:
ansible-playbook ntpd.yaml
后续如果我们的ntpd.conf.j2配置模板需要变更,并需要批量分发下去,我们可以指定copy ntp.conf这
个Task,只运行该Task:
ansible-playbook ntpd.yaml --start-at-task=’copy ntp.conf’
除了上述参数之外,ansible-playbook还有几个常用的参数:
--step同一时间只执行一个Task,每个Task执行前都会提示确认一遍。
--tags=TAGS当Play和Task的Tag为该参数指定的值时才执行,多个Tag以逗号分隔。
--skip-tags=SKIP_TAGS当Play和Task的Tag不匹配该参数指定的值时才执行。
根据前面的案例,我们对Playbook的大体写法和用法有了一个大致的认识,下面重点介绍几个Play-
book常用的使用要点:
Playbook的组成
一个Playbook包括一个或多个Play。一个Play由Host的无序集合与Task的有序列表组成。每一个Task
仅由一个模块构成。见下图所示:
Tasks List和Action
Play的主体部分是Task列表,Task列表中的各任务按次序逐个在Hosts中指定的主机上执行,即在所有
主机上完成第一个任务后再开始第二个任务。在运行Playbook时(从上到下执行),如果一个Host执行
Task失败,整个Task都会回滚,我们需要修正Playbook中的错误,然后重新执行即可。Task的目的是使用
指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等等,这意味着多次执行是安全的,因
为其结果一致。
另外,按照规范写法,每一个Task必须有一个名称Name,虽然这不是必须的,但这样在运行Playbook
时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个Task。如果没有定义Name,Action的值将
会用作输出信息中标记特定的Task,结果不好分辨。定义一个Task,常见的格式为“module: options”,例
如:“yum: name=httpd”。值得注意的是,Ansible的自带模块中,Command模块和Shell模块无需使用
key=value格式,直接编写要执行的命令即可。
Handlers
Handlers也是一些Task的列表,和一般的Task并没有什么区别。它是由通知者进行的Notify,如果没有
被Notify,则Handlers不会执行,如果被Notify了,则Handlers被执行。不管有多少个通知者进行了Notify,
等到Play中的所有Task都执行完成之后,Handlers也只会被执行一次。例如:
变量引用
我们可以在PlayBook中通过“vars: 变量名”的方式声明变量,并通过“{{变量名}}”的方式使用已声明的变
量。另外,我们还可以直接引用Ansible的变量,包括采集到的主机Fact中的变量,例如:通过ansi-
ble_all_ipv4_address来获取IPV4地址,或者通过ansible_distribution、ansible_distribution_version来获取操
作类型和版本信息。除此之外,还能引用已编辑好的Inventory文件中定义的主机变量,这样当安装完一些软
件,需要根据主机中定义的变量来做一些自动化配置时,将会非常好用。例如:
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
X.X.108.2 hostname="test"
上面的案例是通过vars的方式定义了package和service两个变量,并在下面的yum和service两个Task中
进行引用,第三个Task则是直接引用setup生成的Fact变量和来自Inventory文件中定义的主机变量host-
name,来实现将内容信息传递至远端主机的文件中,输出结果如下:
cat /tmp/test.txt
test:RedHat 7.2
条件判断
我们可以在PlayBook中通过“when: 变量==值”的方式声明一个条件判断,可以看出when的值是一个条
件表达式,如果条件判断成立,Task就执行,如果判断不成立,则task不执行。例如当我们需要根据变量、
Facts(setup)或此前任务的执行结果来作为某Task执行与否的前提时,则要用到条件判断,这时可以在
Playbook中使用when子句:在Task后添加when子句。另外,when子句支持jinjia2表达式或语法。
迭代
当我们有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变
量引用,并通过with_items语句指明迭代的元素列表即可。例如:
Templates
Jinja是基于Python的模板引擎。Template类是Jinja的另一个重要组件,可以看作一个编译过的模块文
件,用来生产目标文本,我们可以传递Python的变量给模板去替换模板中的标记。例如,我们在做Nginx安
装与配置时,有些监听端口、服务名称等配置可以通过变量的方式在Inventroy文件中为不同主机预定义好,
当我们定义好了一个模板,并将模板中的监听端口和服务名称设置为变量后,在运行Template这个Task时,
将会把不同主机的这些变量信息传递到模板中使用,实现配置的自动化。例如:
vi /tmp/httpd.conf.j2 #定义模板中的变量
Listen {{http_port}}
ServerName {{server_name}}
MaxClients {{access_num}}
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
[test]
X.X.X.2 http_port=X.X.X.2:80 access_num=50 server_name="test:80"
安装Nginx时,将把Inventory文件中主机定义好的变量与值传递到模板中,并拷贝至该远端主机:
Tags
在一个Playbook中,我们一般会定义很多个Task,如果我们只想执行其中的某一个Task或多个Task时
就可以使用Tags标签功能了,例如:
ansible-playbook test.yml --tags="nginx"
4.5 Ansible Facts使用
Facts组件是Ansible用于采集被管主机设备信息的一个功能,当Ansible采集Fact的时候,它会收集被管
主机的各种详细信息:CPU架构、操作系统、IP地址、内存信息、磁盘信息等,这些信息保存在被称作Fact
的变量中。Ansible使用一个名为Setup的特殊模块来实现Fact的收集,在Playbook中默认会调用这个模块进
行Fact收集,在命令行中可以通过“ansible ip -m setup”来进行手动收集,整个Facts信息被包装JSON格式
的数据结构中, Ansible Facts是最上层的值。例如:
Facts还支持通过filter参数来查看指定信息,例如下面只查看远端主机的操作系统和版本:
查看远端主机的CPU和内存大小:
查看远端主机的各文件系统大小和剩余容量:
在Playbook中,Facts组件默认会收集很多的主机的基础信息,可以通过前面的Fact缓存机制,将这些
信息缓存到本地目录或者内存数据库中,在做配置管理的时候进行引用,也可以用来将获取的主机基础信息
自动同步到CMDB中去,实现基础信息的自动采集功能。下面通过通过演示,说明如何通过ansible-cmdb
插件,实现远端主机CPU自动同步至外部CMDB系统中。
首先,我们需要安装ansible-cmdb插件,下载链接如下:
其次,开始安装ansible-cmdb插件:
gzip -dc ansible-cmdb-1.27.tar.gz|tar -xvf -
cd ansible-cmdb-1.27
python setup.py install
生成所有主机的Fact信息并用filter过滤出主机CPU值:
ansible all -m setup -t /tmp/factout
ansible all -m setup -a “filter=ansible_processor_count” -t /tmp/cpu
通过ansible-cmdb插件以csv或sql格式输出IP地址和CPU颗数值:
PATH=/usr/local/bin:$PATH
ansible-cmdb -t csv -c name,cpus /tmp/cpu >/tmp/cpu.csv
ansible-cmdb -t sql /tmp/cpu >/tmp/cpu.sql
以csv格式或者sql格式导入信息至外部CMDB系统中(根据支持方式灵活选用),这里以postgres数据
库为例,通过转csv格式为sql格式导入至外部CMDB系统:
cpuinfo=$(cat /tmp/cpu.csv)
for cpu_info in $cpuinfo
do
ip=$(echo "$cpu_info" |awk -F"," '{print $1}'|sed 's/"//g')
cpu=$(echo "$cpu_info" |awk -F"," '{print $2}'|sed 's/"//g')
echo "update \"VirtualMachine\" set \"VCPU\"='$cpu' where \"IP\"='$cpuip' and \"Status\"='A';"
>>/tmp/cpu_info.sql
done
su - postgres -c "export PGPASSWORD=postgres;/opt/PostgreSQL/9.3/bin/psql -d cmdbuild -f
/tmp/cpu_info.sql"
当然,以上仅仅是简单的示例,事实上,我们可以利用好Ansible Fact的功能,实现更加复杂的CMDB
自动化采集功能。
06
运维技术岗岗位学习教程
1 Ansible软件简介
1.1 本章价值
通过本章节,您将学习到Ansible的软件架构模式、管理方式和系统架构等内容,同时您将了解到Ansi-
ble的六大功能特性,和其他主流的开源自动化运维软件的对比,与优缺点分析等。
1.2 Ansible软件架构
Ansible是一个开源的基于OpenSSH的自动化运维管理软件。可以用它来配置系统、部署软件和编排更
高级的IT任务,比如持续部署或零停机更新。Ansible的主要目标是简单和易用,并且它还高度关注安全性和
可靠性。基于这样的目标,Ansible适用于开发人员、系统管理员、发布工程师、IT经理,以及介于两者之间
的所有人。Ansible适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。
Ansible软件架构模式通常由控制机和被管机组成,控制机是用来安装Ansible工具软件、执行维护指令
的服务器或工作站,也称之为Ansible服务端,它是Ansible维护的核心。被管机是运行业务服务的服务器,
也称为Ansible客户端,由控制机通过SSH来进行管理。
Ansible管理方式
Ansible是一个模型驱动的配置管理器,支持多节点发布、远程任务执行,默认使用SSH进行远程连接。
无需在被管节点上安装附加软件,可使用各种编程语言进行扩展。Ansible管理系统由控制主机和一组被管
节点组成,控制主机直接通过SSH控制被管节点,被管节点通过Ansible的资源清单来进行分组管理。
Ansible系统架构
Ansible集合了众多优秀运维工具(Puppet、Cfengine、Chef、Fune、Fabric)的优点,实现了批量系
统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作的,本身没有批量部署的能力。真
正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。Ansible的系统架构见下图,用户可
以通过Ansible编排引擎操作公有云/私有云或CMDB(配置管理数据库)中的主机。从图中可以看到,Ansi-
ble由以下各部分组成:
核心引擎:即Ansible。
核心模块(Core Modules):这些都是Ansible自带的模块,Ansible 模块资源分发到远程节点使其执行
特定任务或匹配一个特定的状态。Ansible遵循“Batteries Included“哲学,所以你可以有各种各样任务的核心
模块。这意味着模块是最新的,你不需要寻找一个在你平台上工作的实现。你可以认为模块库的工具箱里充
满了有用的系统管理工具,和Playbook一起构建自动化运维系统的基础源材料。
白定义模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加自定义模块。
插件(Plugins):完成模块功能的补充,借助于插件完成记录日志、邮件等功能。
剧本(Playbook):定义Ansible任务的配置文件,可以将多个任务定义在一个剧本中,由 Ansible自动
执行,剧本执行支持多个任务,可以由控制主机运行多个任务,同时对多台远程主机进行管理。Playbook是
Ansible的配置、部署和编排语言,可以描述一个你想要的远程系统执行策略,或一组步骤的一般过程。如
果Ansible模块作为你的工作室工具,PlayBook则是你的设计方案。在基本层面上,剧本可用于管理配置和
部署远程机器。在更高级的应用中,可以序列多层应用及滚动更新,并可以把动作委托给其他主机,与监控
服务器和负载平衡器交互。
连接插件(Connectior Plugins) : Ansible基于连接插件连接到各个主机上,负责和被管节点实现通信。
虽然Ansible是使用SSH连接到各被管节点,但它还支持其他的连接方法,所以需要有连接插件。
主机清单(Host Inventory):定义Ansible管理的主机策略,默认是在Ansible Hosts配置文件中定义被
管节点,同时也支持自定义动态主机清单和指定配置文件的位置。
1.3 Ansible软件特性
Ansible是基于一致性、安全性、高可靠性设计的轻量级自动化工具,具有功能强大、部署便捷、描述
清晰等特性。对于管理员、开发者、IT经理等都容易上手,学习曲线较低,能够快速理解、掌握 Ansible的
自动化体系,满足不同技术级别的用户需求。同时Ansible 是一款满足当代大规模、复杂环境的IT基础架构
自动化管理的工具。
Ansible相对与其他自动化解决方案,在核心能力上效率更高。也很好地解决了统一配置、统一部署、
流程编排等复杂的IT自动化管理问题。下面就介绍其功能特性以及与其他工具的对比。
Ansible功能特性
从功能上看,Ansible可以实现以下目标:
应用代码自动化部署。
系统管理配置自动化。
支持持续交付自动化。
支持云计算、大数据平台(如AWS、OpenStack、CloudStack、VMWare等)环境。
轻量级,无需在客户端安装Agent,更新时只需在控制机上进行一次更新即可。
批量任务执行可以写成脚本,不用分发到远程就可以执行。
使用Python编写,维护更简单,而Ruby语法过于复杂。
支持非root用户管理操作,支持sudo。
实现上述目标是很有挑战性的工作,需要满足健壮性、易于管理的架构,这在应用维度一直没能很好地
解决,因为管理工具不能对被管环境施加额外的影响,而Ansible很好地解决了这些问题。Ansible作为优秀
管理工具具备以下一些特点:
1.语法简单、易读
Ansible的配置管理脚本Playbook语法基于YAML,它是一种可读性高、用来表达数据序列的格式标准。
YAML参考了XML、C、Python、Perl以及电子邮件格式RFC2822等其他多种语言,可读性好、交互性强,
使用了实现语言的数据类型,有一个一致的信息模型,可以基于流方式来处理,具有表达能力强、扩展性好
等特点。可以把Playbook称为“可执行的文档”,就像README文件一样描述你需要部署软件的指令,由于这
些代码是可以直接执行的,这些指令永远不会过时。
2.不需要在被管节点安装客户端软件
Ansible运维管理系统的核心是通过 SSH来连接被管节点,可以使用Paramiko(一个Python库)或使用
原生的OpenSSH(带参数-c ssh)。当使用SSH客户端连接的时候,默认的OpenSSH连接是可以重用的。无
论哪种方式,SSH都是作为一种传输方式,不是作为一种执行的Shell。
Ansible模块是包含一些参数的Ansible小程序,通过SCP或SFTP传送到远端被管机器的临时目录中进行
执行,然后再删除。这些模块通过标准的输出方式返回JSON格式的数据,这些返回的数据通过控制主机上
的Ansible程序进行处理。这种方式能管理非常多远程活动,并且只需要很小的交互流量。模块按照“幕等资
源”的方式进行管理,也就是发起多次执行也不会给服务带来负面响应。它不是简单的命令或脚本,例如一
个模块可以确定应该安装某个特定版本的软件包,但如果这个系统已经有合适的工作状态,就不会再执行任
何命令。这种方式有如下优点:
提高网络安全:由于不需要在远端被管节点上运行Agent,因此 Ansible遭受攻击的机会很少。只需要运
行OpenSSH一个后台进程,OpenSSH在全球范围内是最严格审查的程序之一。Ansible知道做好加密是一项
极其艰难的事情,因此没有考虑使用自己的后台进程和认证方式,而是依赖可用的最安全的远程管理方式。
OpenSSH极其广泛地在各种系统中使用,属于非常轻量级。一旦Open SSH出现安全问题,将会非常快速地
推出补丁修复。
可以使用非root用户访问(可用sudo) : Ansible Playbook能够用任何用户账号登录远程系统,可以用初
始连接的用户来运行程序,也可以使用sudo切换到其他用户(包括root)。如果需要,可以直接用root登
录,sudo可以需要口令,也可以不需要口令,当管理的一些系统根本不能使用root登录的时候,或者不允
root登录但可以通过sudo切换到root的,这种方式是非常合适的。
限制传输潜在敏感数据:Ansible总是尽量把最少的数据传输到被管节点,由于控制服务器是逻辑控制
中心,只有远端被管节点必要的变量才送给它。例如,有个全局变量叫foo,只有在远端被管节点中明确在
资源或模板中使用它,否则它不会发送到该远端节点。这种Ansible的推送方式,只给远端节点需要看到的
最少数据。类似地,Ansible没有包含客户文件服务器的实现,只通过SFTP、SCP、Rsync(基于SSH)传
输文件,并且只有Playbook需要的文件才传输。结果是被管节点请求的文件或模板可以提供,但敏感数据不
会提供给。也就是不能给一台远程主机查看将要提供给其他被管节点的数据。这使得Ansible适用于带有敏
感数据的环境,包括社会科学工作、健康医疗、政府政务等应用。
(Credential Segregation凭证隔离): Ansible适用于不同用户有不同安全级别的环境。可以定义管理主
机的通用变量,然后使用自己的凭证访问远端节点。例如,允许研发工程师管理开发的服务器,QA工程师
管理QA的服务器,系统管理员管理生产环境服务器,不存在研发工程师把代码推送到生产环境的风险。
去中心化:由于Ansible Playbook需要用户的凭证来执行,不存在中心点,只是通过访问配置内容、管
理软件链条,不需要访问SSH密钥,就可以接管建立“僵死网络”,避免使它成为攻击的目标。用户可以加
密自己的密钥,不需与任何人使用相同密码。在可选的管理形式中,访问授权的软件资源都有可能导致部
署系统自动化。要使用Ansible,用户需要两个条件:能够访问到资源库,具有管理远端节点的凭证。当使
用锁定的密钥(甚至是密码)时,不存在暴露安全漏洞中心被攻击点,也不允许从远端硬件来访问管理服
务器。
没有“管理的管理程序”的问题:许多配置管理解决方案的主要问题之一是“管理的管理”,为了开始管
理服务器必须先在远端节点上安装软件。当更新管理软件的时候,通常各种Agent需要先更新(许多系统是
无法自己自动更新的)。有时会产生管理服务器与Agent软件版本兼容性问题,或Agent与运行语言版本问
题,Ansible通过基于SSH传输模块避免了这类问题。SSH二进制代码已经是OS的一部分了,并且是每个主
流操作系统的核心。不需要任何Agent,也就不存在Agent以任何方式崩溃的问题,因此服务器存在的安全
风险是非常小的。
管理服务器的可扩展性:由于Ansible使用推送方式来管理远端节点(当然,也很容易配置成远端节点
查询更新的方式),因此Ansible对于“羊群效应”的管理问题是有免疫能力的。在其他的一些解决方案中,
管理Agent周期性检查会对管理服务造成破坏,经常会超过管理服务器的运行负荷,导致需要对管理服务器
进行横向或纵向扩展。频繁管理服务器需要为远端节点消耗昂贵的计算资源。为了解决这个问题,Ansible
通过推送的方式,通过配置每次推送节点数量来做限制。均衡了远程节点需要的管理服务器的负载能力,可
以让计算系统负载更加均衡,即使个人笔记本电脑也可以作为Ansible系统的控制服务器。
资源的利用:在Ansible不管理远端节点时,这些远端节点什么也不做,也就是没有后台进程在消耗
CPU、内存。曾经报道过,某些应用服务器在唤醒配置窗口时会产生明显的降低性能,某些 Agent可能会占
用超过400MB的内存。在虚拟化环境中,这些资源的消耗可能会快速叠加,就会增加对硬件的支出。Ansi-
ble能最大限度让你的关键性能负荷使用所有的计算资源,你也可以选用间隔方式运行管理程序,也不存在
由于内存泄漏或Agent软件崩溃导致无法管理远端节点的问题。
防火墙的友好性和确定性:不像某些基于消息总线的系统,Ansible不需要长时间在控制节点与被管主机
之间建立连接。在生产环境,这种长连接可能受限于防火墙,防火墙一般不喜欢长连接,Ansible很好地规避
了这个问题。当管理服务与应用之间的连接被断开又没法重置的时候,就只能等到重启Agent端服务了,
Ansible没有这个问题。没有严格意义上的无代理系统,Ansible也避免在这些架构中的其他问题,获得确定
性的响应。并不是只有出现响应节点才管理,对于你要管理但无法达到的就静默了。如果一个节点宕机,运
行Ansible时你就会知道,将会返回一个失效信息,这个你可能忽略或修复。这对于你给所有节点或部分子
集部署软件更新,是很重要的信息,知道哪些节点无法连接是非常重要的。
3.基于推送(Push)方式
有些运维管理工具(如Chef、Puppet、Saltstack等)是使用代理模式的,它们默认基于拉(Pull)方
式。被管节点上安装代理后,代理服务将周期性检查中心控制主机的服务,并从控制主机上取来配置信息。
被管节点的变更过程大致如下:
修改配置管理脚本。
把修改好的管理配置脚本推送到中心控制主机上。
被管节点的代理服务周期性触发检查。
被管节点连接配置管理的控制主机。
被管节点下载新的配置管理脚本。
被管节点在本地执行配置管理脚本,被管节点状态相应地变化。
而Ansible默认基于推送(Push)方式,管理过程如下:
增加或修改Playbook。
执行新的Playbook。
控制节点的Ansible连接被管节点并执行修改被管节点状态的模块。
一旦你执行ansible-playbook命令,Ansible就会连接到远程的被管节点并按照脚本要求执行。基于推送
方式有很大的优势,你能控制什么时候让远程被管节点发生变更,不需要等到被管节点上周期性的时间。拉
方式的支持者声称拉方式具有管理服务器规模数量的优势,新被管节点随时可以在线添加。但是Ansible已经
在管理超过上万台节点规模的系统,很方便地动态增减或删除被管节点。当然,如果你一定要使用拉方式,
Ansible官方也已经支持这种拉方式,可以使用ansible-pull这个工具。
4.方便管理小规模场景
Ansible能够管理成千上万台主机,但如何管理缩小规模的场景呢?其实,用Ansible也很容易配置小规
模集群甚至单台主机,你只要简单编写一个Playbook即可。
5.大量内置模块
使用Ansible能够在被管节点上执行任何Shell命令,但是 Ansible真正的威力在于内置大量的模块。使用这
些模块可以完成如软件包安装、重启服务、拷贝配置文件等操作。Ansible模块是声明式的(Declarative),
你只需使用这些模块描述被管节点期望达到的状态。例如,你可以用user模块对用户授权,确保系统有一个
deploy用户,并且属于web组,代码如下:user: name=deploy group=web
Ansible内置模块都是等幕性的(Idempotent)。这就是如果系统中没有用户deploy, Ansible将会创建一
个deploy账号;如果这个账号已经存在,则Ansible什么也不做。等幕性对于自动化维护是非常重要的特性,
这样在被管节点上多次执行AnsiblePlaybook 也能达到同样效果。相对于直接执行操作系统脚本的方式是巨
大的改进,操作系统脚本再执行一次可能就会产生不同的、非预期的结果。
6.非常轻量级的抽象层
有些配置管理工具通过一个抽象层,可以把相同的脚本在不同的操作系统上管理。例如,安装软件包有
yum、apt工具,对于配置管理工具就可能抽象成package。Ansible不同于这种方式,你需要使用apt模块来
安装基于apt软件管理的系统,用yum模块来安装基于 yum软件管理的系统。这听起来也许不太方便,在实
践中我们发现这使得Ansible更方便使用。Ansible不需要再学新知识来屏蔽不同操作系统的差异性、新的抽
象环境。这相对减少了Ansible要求的知识领域。这样,你不需要了解太多就可以编写Playbook了。如果你
确实需要,你也可以在Ansible Playbook中对不同被管节点的操作系统编写不同的动作脚本。但不太建议这
么做,建议编写针对特定操作系统的Playbook,如CentOS、Ubuntu。
1.4 Ansible与其他运维管理工具的对比
当前几款与Ansible功能类似的主流配置管理软件有Chef、Puppet、SaltStack等,这里只对各个软件的
技术特性做个简单对比,其中不针对各个软件的性能作比较。具体内容见下表:
与其他的自动化工具相比较,Ansible不需要安装管理客户端就能轻松地管理、配置你的基础架构。它
们各自的优缺点见下表所示:
这些自动化管理软件都具备强大的功能、灵活的系统管理和状态配置,都提供丰富的模板及API,对云
计算平台、大数据都有很好的支持。Puppet、Chef、SaltStack设置比较复杂,有代理和服务,有远程被管
节点需要长期运行管理进程,而且很多术语和概念都是自己一套。Ansible相对于其他产品要简单得多,本
质上混合了声明式和命令式。不仅适用于大规模的IT环境,而且对于一些规模较小的环境(20-50台机器)
Ansible也是很实用的。
2 Ansible软件部署与配置
2.1 本章价值
通过本章节,您将学习到如何通过安装包的方式安装Ansible软件(YUM源配置,依赖模块及安装包安
装),配置Ansible相关参数,建立Ansible服务端与客户端互信,进行必要的Ansible服务端与客户端连通性
测试,极快速地搭建一整套基于Ansible的自动化运维环境。另外,对于客户端Python版本不符合要求的,
本章节也将介绍如何快速批量完成安装。
2.2 Ansible软件安装
Ansible软件安装的方式较多,非常灵活,可以满足各种环境的部署需求。一般可以直接用源码进行安
装,包括从GitHub源码库安装方式、TAR包安装、制作RPM包安装等。也可用操作系统软件包管理工具进
行安装,包括YUM安装(适合Fedora、RHEL、CentOS)、APT安装(适合Ubuntu)、Homebrew安装(适
合Mac OS X)、PIP安装等。其中大部分安装方式需要服务端连通公网,下面不一一介绍,仅详细介绍如
何在生产环境,无法连接外部互联网的条件下,通过TAR包的安装方式,快速搭建Ansible整套环境,包含
一套Ansible服务端和千余个生产环境Ansible客户端环境。整个搭建耗时约1-2天。下面演示的服务端操作
系统版本为RHEL6.6x86_64,该操作系统自带Python2.6.6(要求Version>=2.6),所有安装包的下载地址
为:http://www.talkwithtrend.com/Document/detail/tid/404677
1.配置YUM源
如果有专门的YUM服务器,可以直接配置如下:
cat /etc/yum.repos.d/rhel-source.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
如果没有专门的YUM服务器,可以先将RHEL6.6的ISO文件传至服务端,并用以下命令挂载:
mount -o loop -o ro /tmp/rhel6.6_x86_64.iso /mnt
再配置本地YUM源:
cat /etc/yum.repos.d/rhel-local.repo
[rhel]
name=Red Hat Enterprise Linux - rhel
baseurl=http://yum_server_ip/repo/rhel/6.6/x86_64/
enabled=1
gpgcheck=0
2.ansible依赖模块及安装包的安装
安装setuptools-7.0
tar -xvf setuptools-7.0.tar
cd setuptools-7.0
python setup.py instal
安装pycrypto-2.6.1
gzip -dc pycrypto-2.6.1.tar.gz|tar -xvf -
cd pycrypto-2.6.1
python setup.py install
安装包错解决:
报错1:
running install
running build
running build_py
running build_ext
running build_configure
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ansible/pycrypto-2.6.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
解决办法:yum install gcc
报错2:
解决办法:yum install python-devel
最后pycrypto安装成功。
安装PyYAML模块
安装yaml-0.1.5:
tar -xvf yaml-0.1.5.tar
cd yaml-0.1.5
./configure --prefix=/usr/local
make --jobs=`grep processor /proc/cpuinfo|wc -l`
make install
安装PyYAML-3.11:
gzip -dc PyYAML-3.11.tar.gz|tar -xvf -
cd PyYAML-3.11
python setup.py install
安装Jinja2模块
安装MarkupSafe-0.9.3:
tar -xvf MarkupSafe-0.9.3.tar
cd MarkupSafe-0.9.3
python setup.py install
安装Jinja2-2.7.3
gzip -dc Jinja2-2.7.3.tar.gz|tar -xvf -
cd Jinja2-2.7.3
python setup.py install
安装Paramiko模块
安装ecdsa-0.11:
gzip -dc ecdsa-0.11.tar.gz|tar -xvf -
cd ecdsa-0.11
python setup.py installs
安装paramiko-1.15.1:
gzip -dc paramiko-1.15.1.tar.gz|tar -xvf -
cd paramiko-1.15.1
python setup.py install
安装ansible-stable-2.3
unzip ansible-stable-2.3.zip
cd ansible-stable-2.3
python setup.py install
至此,Ansible软件在服务端的安装工作全部完成。
2.3 Ansible软件配置
1.配置Ansible变量环境
Ansible配置文件是以ini格式存储配置数据的,在Ansible中,几乎所有的配置项都可以通过Ansible的
Playbook或者环境变量来重新赋值,在运行Ansible命令时,命令将会按照预先设定的顺序查找配置文件,
如下所示:
ANSIBLE_CONFIG:首先,Ansible命令会检查该环境变量,及这个环境变量所指向的配置文件。
./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件。
~/.ansible.cfg:再次,将会检查当前用户home目录下的ansible.cfg配置文件。
/etc/ansible/ansible.cfg:最后,将会检查在用软件包管理工具安装Ansible时自动产生的配置文件。
在这里我们在/etc/profile中,增加一行:
export ANSIBLE_CONFIG=/etc/ansible/ansible.cfg
在用户登录时,都将设置该环境变量。
2.配置Ansible配置文件
由于是TAR包安装,Ansible的目录及相关文件都需要自己创建:
mkdir /etc/ansible
cd /etc/ansible
touch ansible.cfg hosts
修改/etc/ansible/ansible.cfg的内容:
cat /etc/ansible/ansible.cfg
#defaults这一行是需要的
[defaults]
#inventory代表所管理的主机清单的文件位置
inventory = /etc/ansible/hosts
#library参数就是指向存放ansible模块的目录(ansible基于模块工作,本身没有批量部署的能力,真正
具有批量部署的ansible所运行的模块)
library = /usr/share/ansible/my_modules
#设置默认情况下ansible最多能有多少个进程同时工作
forks = 50
#设置默认执行命令的用户,可以在playbook中重新指定该参数
sudo_user = ansible
#指定连接被管节点的ssh端口,可以在hosts文件中,单独指定被管主机的ssh端口
remote_port = 22
#设置模块的语言
module_lang = C
#设置ansible服务端连接客户端的私有ssh key文件位置
private_key_file = /root/.ssh/id_rsa
#设置是否检查ssh主机的密钥
host_key_checking = False
#设置ssh连接的超时时间,单位秒
timeout = 60
#设置把ansible系统的输出记录到日志文件中
log_path = /tmp/ansible.log
2.4 Ansible客户端互信配置
按照以下步骤建立Ansible服务端与客户端间的互信关系,可以是root用户和root用户,也可以是非root
用户和非root用户间。
在Ansible服务端生成ssh public和private key:
ssh-keygen
将ssh public key下发到被管节点的.ssh目录:
ssh-copy-id -i /root/.ssh/id_rsa.pub client_ip
为了提高效率,可以将所有需要添加互信的client的ip地址编入文件/tmp/clienthosts.txt,并批量
下发到被管节点。
a=`cat /tmp/clienthosts.txt`
for i in $a
do
ssh-copy-id -i /root/.ssh/id_rsa.pub $i
done
然后每个建立互信过程时,输入“yes”和client密码,这样下次服务端就可以直接通过ssh连接客户
端了。
2.5 Ansible客户端Python与Simplejson环境安装
1.Ansible客户端环境的需求
被管理的服务器(Ansible客户端)需要安装python2.4以上的版本,如果python版本低于2.5,但不想安
装更高版本的python,对于Linux操作系统而言,可以安装python-simplejson模块来解决。
2.AIX操作系统python的批量安装
为了加快Ansible客户端环境的部署效率,可以通过以下批量python环境的安装步骤进行:
将以下AIX python的安装文件传至Ansible服务端的/tmp目录,版本满足要求即可:
gdbm-1.8.3-2.aix5.1.ppc.rpm
readline-4.3-2.aix5.1.ppc.rpm
expat-2.0.1-2.aix5.3.ppc.rpm
python-2.6.2-2.aix6.1.ppc.rpm
编辑文件/tmp/clienthosts_aix.txt将所有AIX的IP地址输入至该文件,并运行命令:
b=`cat /tmp/clienthosts_aix.txt`
for i in $b
do
scp /tmp/gdbm-1.8.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/readline-4.3-2.aix5.1.ppc.rpm $i:/tmp
scp /tmp/expat-2.0.1-2.aix5.3.ppc.rpm $i:/tmp
scp /tmp/python-2.6.2-2.aix6.1.ppc.rpm $i:/tmp
done
检查AIX客户端是否已经安装了python
for i in $b
do
ssh $i which python
done
如果安装了python,版本也大于等于2.6,可以重新编辑/tmp/clienthosts_aix.txt将该ip地址去掉。
未安装python的AIX客户端开始安装:
c=`cat /tmp/clienthosts_aix.txt`
for i in $c
do
ansible $i -m raw -a "cd /tmp;rpm -ivh gdbm-1.8.3-2.aix5.1.ppc.rpm;rpm -ivh readline-4.3-2.aix
5.1.ppc.rpm;rpm -ivh expat-2.0.1-2.aix5.3.ppc.rpm;rpm -ivh python-2.6.2-2.aix6.1.ppc.rpm"
done
由于Ansible服务端需要和安装了python的客户端才能通信,但是在客户端没有安装python前,可以通
过Ansible的raw模块直接通信,并安装python,用这种方式实现批量安装的目的。
3.Linux批量安装simplejson
Linux操作系统基本都自带python环境,所以只需要关注python版本即可,对于Linux python version<2.5
的操作系统环境,可以通过安装simplejson解决。
单机安装simplejson-3.6.5:
gzip -dc simplejson-3.6.5.tar.gz|tar -xvf -
cd simplejson-3.6.5
python setup.py install
批量安装simplejson-3.6.5:
将simplejson-3.6.5.tar.gz传至Ansible服务端的/tmp目录
拷贝simplejson-3.6.5.tar.gz至需要安装的客户端
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
scp /tmp/simplejson-3.6.5.tar.gz $i:/tmp
done
开始批量安装simplejson
d=`cat /tmp/clienthosts_linux_lowpython.txt`
for i in $d
do
ansible $i -m raw -a "gzip -dc simplejson-3.6.5.tar.gz|tar -xvf –;cd simplejson-3.6.5; python
setup.py install"
done
批量安装都是用类似的方法,这里也不再一一举例。
2.6 Ansible服务端与客户端连通性测试
1.查看ansible版本
"failed": true,
"module_stderr":"Shared connection to X.X.X.X closed.\r\n",
"module_stdout": "/bin/sh: /usr/bin/python: not found.\r\n"
"msg": "MODULE FAILURE",
"rc": 0
}
如果遇到这些报错,这里只需要按照上面所介绍的批量安装方式安装即可。
3 Ansible软件配置优化
3.1 本章价值
鉴于Ansible服务端使用了默认的SSH无代理方式与客户端通信,效率远低于有代理的通讯方式,然而
通过本章节,您将学习到如何通过配置优化,来加速Ansible的执行速度,以提高自动化运维的工作效率,
做到等同于有代理通讯方式的效率:包括如何开启SSH长连接,避免SSH短连接的通信开销;开启Pipelin-
ing,利用SSH会话来缩短PUT脚本至远端客户端执行的流程;开启Accelerate模式,利用远端客户端上运行
的守护进程,优化Ansible的执行流程;在Playbook中修改Ansible的执行策略,减少多主机批量执行过程的
等待;在Playbook中使用异步特性,减少执行任务的同步等待;设置Facts缓存,通过提前将Facts信息缓存
于本地JSON文件、Redis或Memcached内存数据库中,来提高PlayBook的执行效率。
3.2 Ansible执行速度过慢问题
在测试连通性的过程中,利用前面的默认配置,发现有一个问题非常困扰,就是通过Ansible服务端向
客户端执行命令非常缓慢,主要体现在创建SSH的通道很慢,虽然Ansible在同一个task里面是并行的控制
多台受管端,但是每一个task都需要和受控端创建SSH通道,非常影响效率。由下面也能看出,一个简单的
PING命令都要耗时13秒以上。
time ansible test -m ping
X.X.X.X | SUCCESS => {
"changed": false,
"ping": "pong"
}
real 0m13.030s
user 0m1.147s
sys 0m0.263s
这种执行效率显然是无法接收的,那么接下来如何通过配置优化来提升Ansible的执行效率是势在
必行。
3.3 开启SSH长连接
我们知道Ansible模式是使用SSH和远端主机进行通信,所以Ansible对于SSH的依赖性非常强,下面我
们第一步就从SSH入手来优化Ansible。OpenSSH在5.6版本以后支持了Multiplexing(多路复用)功能,它支
持同一主机的多个SSH会话共享单一TCP连接进行通讯,一旦第一个连接建立,后续连接就不再需要凭证,
从而消除了每次连接同一机器都需要键入密码的麻烦并且大幅度节省了服务器端的资源,这种功能也称作长
连接机制。
如果Ansible中控机的SSH -V版本高于5.6时,我们可以直接在ansible.cfg文件中设置SSH长连接即
可。设置参数如下:
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=5d
Contro1Persist=5d这个参数是设置整个长连接的保持时间,默认值为60秒,这里设置为5天,如果开
启后,通过SSH连接过的设备都会在用户当前目录的~/ansible/cp/目录下生成一个socket文件,每个会话一
个文件,以便相同连接复用,也可以通过netstat命令查看,会发现有一个ESTABLISHED状态的连接一直与
远端设备进行着TCP连接。如果长连接时间超过Contro1Persist的设定值,连接将被断开,socket文件也将
被清理。另外,如果不仅仅需要Ansible开启SSH长连接,SSH命令也保持长连接的话,可以修改Ansible中
控端的SSH CLIENT的全局性配置文件:/etc/ssh/ssh_config,或者修改当前用户的~/.ssh/config文件,仅
使本用户生效:
ServerAliveInterval 30
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 5d
其中ServerAliveInterval表示client每隔30秒发送一次请求给server,然后server响应,从而保持连接;
ServerAliveCountMax表示client发出请求后,服务器端没有响应的次数达到3,就自动断开连接;ControlPath
表示socket的存放和复用路径。
如果我们的Ansible中控机SSH-V版本低于5.6时,则需要升级到5.6版本后才能启用SSH Multiplex-
ing特性。
通过SSH-V命令查看了下当前演示环境的OpenSSH的版本为:OpenSSH_5.3p1,这次需要将openssh
版本升级到OpenSSH_6.7p1,安装包的下载地址为:
http://www.linuxfromscratch.org/blfs/view/7.7/postlfs/openssh.html
升级过程如下:
查看是否缺少依赖包:
rpm -qa|egrep “gcc|make|perl|pam|pam-devel”
缺少了依赖包,可以通过YUM源直接安装这些缺少的包:
yum –y install gcc* make perl pam pam-devel
上传安装包:openssh-6.7p1.tar.gz
备份ssh:
mv /etc/ssh /etc/ssh.bak
编译安装新版本OpenSSH
gzip -dc openssh-6.7p1.tar.gz|tar -xvf –
cd openssh-6.7p1
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-zlib --with-md5-passwords
make
卸载旧版本OpenSSH
rpm -a|grep openssh
rpm -e `rpm –qa|grep openssh` --nodeps
安装新版本OpenSSH
make install
配置OpenSSH,主要是保证ssh-copy-id等命令能够正常使用
cd openssh-6.7p1
install -v -m755 contrib/ssh-copy-id /usr/bin
install -v -m644 contrib/ssh-copy-id.1 /usr/share/man/man1
install -v -m755 -d /usr/share/doc/openssh-6.7p1
install -v -m644 INSTALL LICENCE OVERVIEW README* /usr/share/doc/openssh-6.7p1
查看是否升级到了新版本
ssh –V
OpenSSH_6.7p1, OpenSSL 1.0.1e-fips 11 Feb 2013
复制启动脚本到/etc/init.d
cp /root/openssh-6.7p1/contrib/redHat/sshd.init /etc/init.d/sshd
将sshd加入开机自启动
chkconfig --add sshd
重新启动sshd
service sshd restart
执行速度验证
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:17 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m4.228s
user 0m2.591s
sys 0m0.327s
通过OpenSSH的版本升级,我们发现速度优化较为明显,执行速度为4秒左右。我们当然不然满足于
此,看看按照前面介绍的方式,开启Multiplexing功能特性后的Ansible执行速度又如何:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
15:37:31 up 881 days, 17:12, 1 user, load average: 0.00, 0.00, 0.00
real 0m3.075s
user 0m2.532s
sys 0m0.310s
执行速度又降低了1秒,看来复用了长连接,减少SSH的TCP通信开销还是有效果的。
3.4 开启Pipelining
Pipelining也是OpenSSH的一个特性,在Ansible的整个执行流程中,包含三个步骤:
首先,基于调用的模块生成一个Python脚本
其次,再将Python脚本复制到主机上
最后,在远端服务器上执行这个Python脚本
我们可以看到,其中有一个流程就是把生成好的本地Python脚本PUT到远端服务器执行,如果开启了
Pipelining,Ansible执行Python脚本的时候并不会复制它,而是通过管道传递给SSH会话,Ansible使用的
SSH会话将减少到一个,这样可以大大提高整个执行效率。尤其是在在部署大规模服务器或引用模块非常多
时,开启Pipelining特性会给Ansible带来更加显著的性能提升。下面我们通过一个示例展示整个过程。首先
在ansible.cfg配置文件中设置Pipelining。
[ssh_connection]
pipelining = True
再来看开启了Pipelining之后整个Ansible的执行流程有什么变化:
开启Pipelining之前的流程如下:
开启Pipelining之后的流程如下:
我们可以看到开启了Pipelining之后整个流程少了一个PUT脚本和SFTP去远端服务器的流程,且大量减
少了SSH连接次数,第一步就是直接调用ssh执行脚本。那么经过优化后的耗时又如何呢:
time ansible X.X.X.X -a uptime
X.X.X.X | SUCCESS | rc=0 >>
ansible --version
ansible 2.3.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) [GCC 4.4.7 20120313 (Red Hat4.4.7-4)]
2.测试ansible服务端与客户端连通性
Ansible all -m ping
这时由于并非所有客户端都具备相应的条件,要么python未安装、要么python版本不符合要求,要么没
有安装ssh等,会报如下错误:
客户端python版本不符合要求:
X.X.X.X | FAILED! => {
"changed": false,
"failed": true,
"msg": "Error: ansible requires the stdlib json or simplejson module, neither was found!"
}
客户端未安装ssh:
X.X.X.X | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host x.x.x.x port 22: Connection
refused\r\n",
"unreachable": true
}
客户端未安装python:
X.X.X.X | FAILED! => {
"changed": false,
2.与客户端通信可以基于 SSH 或
在被管节点安装代理
3.WEB 界面 可 以 看到运行的工
作、Minion 状态、事件日志、可
以在客户端执行命令
4.扩展能力极强
2.缺乏生成深度报
告的能力
$150,随着数量增加
将有优惠折扣
Ansible 1.模块可以用任何语言开发
2.被管节点不需要安装代理
3.有 WEB 管理界面,可以配置用
户 、 组 、 资 源 清 单 和 执 行
Playbook
4.安装、运行极其简单
1. 对 被 管 节 点 是
Windows 的 管 理 有
待加强
2.WEB 管 理 界面是
内置 Ansible 的一
部分
3.需要导入资源清
单
1.开源版本是免费的
2.Ansible Tower 小
于 10 台时被管节点
免费
3.超过 10 台之后每
年 每 台 需 要 支 付
$100-$250 的支持服
务费用
15:38:26 up 881 days, 17:13, 0 users, load average: 0.00,0.00, 0.00
real 0m1.741s
user 0m1.429s
sys 0m0.176s
耗时又降低了1.3秒。
但是我们要注意,如果在Ansible中使用sudo命令的话,例如:ssh user@host sudo cmd,需要在被控
节点的/etc/sudoers中禁用"requiretty"。这是因为ssh远程执行命令时,它的环境是非登录式非交互式
shell,默认不会分配tty,没有tty,ssh的sudo就无法关闭密码回显(业可以在Ansible命令行中使用"-tt"参
数来强制SSH分配tty)。所以出于安全考虑,/etc/sudoers中默认是开启requiretty的,它要求只有拥有tty
的用户才能使用sudo,也就是说ssh连接过去不允许执行sudo。所以我们需要编辑sudo配置文件,通过注
释该选项来禁用它。如果我们在Playbook中不适用sudo越权功能,则不需要在被控节点的sudo配置文件中
禁用该选项。
3.5 开启Accelerate模式
除了OpenSSH上述两个功能之外,Ansible还有一个Accelerate模式,这和前面SSH Multiplexing功能有
点类似,因为都依赖Ansible中控机跟远端机器有一个长连接。但是Accelerate是使用Python程序在远端机器
上运行一个守护进程,然后Ansible会通过这个守护进程监听的端口进行通信。开启Accelerate模式很简单,
只要在Playbook中配置accelerate:true即可开启。但是需要注意,如果开启Accelerate模式,则需要在
Ansible中控机与远端机器都安装python-keyczar软件包,软件包的下载地址如下:
http://rpm.pbone.net/index.php3/stat/4/idpl/49957349/dir/redhat_el_6/com/python-keyczar-0.71c-
1.el6.noarch.rpm.html
安装python-keyczar软件包,中控机和远端都需要安装。远程批量安装可以参考采用之前所介绍的
方式实施。
yum install python-pyasn1
rpm -ivh python-keyczar-0.71c-1.el6.noarch.rpm
定义ansible.cfg文件中Accelerate参数,例如远端机器的监昕端口以及timeout设置。当然这些参数
也可以在写playbook的时候再定义:
[accelerate]
accelerate_port = 5099
accelerate_timeout= 30
accelerate_connect_timeout= 5.0
在Playbook中定义Accelerate,例如:
---
- hosts: all
accelerate: true
accelerate_port: 5099
然而,RedHat官方目前不赞成使用Accelerate模式。因为在启用ControlPersist和Pipelining管道的情况
下,Ansible的执行效率比较高。Accelerate功能在后面的Ansible版本中将被删除。
3.6 修改Ansible执行策略
默认Ansible在远程执行任务是按批并行执行的,一批控制多少台主机由命令行的-f参数或ansible.cfg配
置中的--forks选项控制。例如,默认的并行进程数是5,如果有20台被控主机,那么只有在每5台全部执行
完一个任务才继续下一批的5台执行该任务,即使中间某台机器性能较好,完成速度较快,它也会空闲地等
待在那,直到所有20台主机都执行完该任务才会以同样的方式继续下一个任务。
在Ansible 2.0版本后,添加了一个策略控制选项strategy,默认值为"linear",即上面按批并行处理的方
式。我们还可以设置strategy的值为"free"。在free模式下,Ansible会尽可能快的切入到下一个主机。同样
是上面的例子,首先每5台并行执行一个任务,当其中某一台机器由于性能较好提前完成了该任务,它不会
等待其他4台完成,而是会跳出该任务让Ansible切入到下一台机器来执行该任务。也就是说,这种模式下,
一台主机完成一个任务后,另一台主机会立即执行任务,它是"前赴后继"的方式。所以这种策略的执行结果
给人感觉是无序的甚至是杂乱无章的,而且每次执行结果的Task显示顺序很可能不一样。利用Playbook,
这两种策略的设置的方式如下:
---
- hosts: all
strategy: free
tasks:
...
3.7 任务执行优化
默认情况下Playbook中的任务在执行时会一直保持连接,直到该任务在每个主机节点都执行完毕,下一
个任务才会开始执行。有时这是不必要的,比如有些操作运行时间比SSH超时时间还要长。解决该问题最简
单的方式是一起执行它们,然后轮询直到任务执行完毕,简单的意思就是,像下面的例子,执行任务后,
Ansible就不等它了,往下执行下一个任务,然后每隔5秒钟去看看它执行完成没,超时时间为45秒,async
参数值代表了这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。如果
async参数若未设置,则为同步执行。我们也可以对执行时间非常长(有可能遭遇超时)的操作使用异步模
式。为了异步启动一个任务,可以指定其最大超时时间以及轮询其状态的频率。如果没有为 poll 指定值,那么
默认的轮询频率是10秒钟。
---
- hosts: all
remote_user: root
tasks:
- name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
command: /bin/sleep 15
async: 45
poll: 5
在异步执行任务时,需要注意那些有依赖性的任务。对于那些对资源要求占有排它锁的任务,如yum,
不应该将Poll的间隔设置为0。如果设置为0,很可能会导致资源阻塞。总结来说,大概有以下一些场景需要使
用到Ansible的异步特性:
某个Task需要运行很长的时间,这个Task很可能会达到ssh连接的Timeout。
没有任务是需要等待它才能完成的,即没有任务依赖此任务是否完成的状态。
需要尽快返回当前shell的。
当然也有一些场景不适合使用异步特性:
这个任务是需要运行完后才能继续另外的任务的。
申请排它锁的任务。
3.8 设置Facts缓存
当我们用ansible-playbook执行Playbook的时候,我们会发现,默认第一个Task都是GATHERING
FACTS,这个过程就是Ansible收集每台主机的Facts信息,方便我们在Playbook中直接引用Facts里的信息。
当然如果我们的Playbook中不需要Facts信息,可以在Playbook中设置gather_facts: False来提高Playbook的
效率:
---
- hosts: 10.0.108.2
gather_facts: no
tasks:
...
也可以在ansible.cfg文件中添加如下配置来默认禁用Facts采集:
[defaults]
gathering = explicit
但是如果我们既想每次执行Playbook的时候都能收集Facts信息,又想加速这个收集过程,这时候可以
设置Facts的缓存。例如,在空闲的时候收集Facts,缓存下来,在需要的时候直接读取缓存进行引用,直到
缓存过期。目前Ansible支持使用Json文件,Redis、Memcached内存数据库来存储Facts信息。
Json文件缓存Fact信息
使用Json文件作为Fact缓存后端时,Ansible将会把采集的Fact写入Ansible中控机的上的文件中。如果
系统中已经存在这个文件,那么Ansible将使用这个文件中的数据,而不再连接到主机去采集Fact。下面我
们首先通过示例来了解如何使用Json文件存储Facts信息,在ansible.cfg文件中添加:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_fact_cache
Ansible的配置文件中可以修改gathering的值为smart、implicit或者explicit。
smart表示默认收集Facts,但Facts已有的情况下不会收集,即使用缓存Facts;
implicit表示默认收集Facts,要禁止收集,必须使用gather_facts: False;
explicit表示默认不收集,要显式收集,必须使用gather_facts: Ture;
在使用Facts缓存时(即设置为smart),Ansible支持两种Facts缓存:redis和jsonfile。这里设置Facts过期
时间为86400秒(会根据文件的最后修改时间来确定Facts信息是否过期),Json文件存放在/tmp/ansi-
ble_fact_ cache下,下面我们执行一下Playbook:
我们再执行Playbook的时候就没有Facts收集这个过程了。直接从Json文件中读取Facts缓存信息:
可以看到10台受控机的执行耗时仅1.8秒,效率是非常不错的。
Redis缓存Fact信息
由于目前Ansible Facts缓存还不支持远端,所以需要在 Ansible中控机上安装Redis服务,并安装Redis
Python模块。
如何安装在,这里不再赘述,有兴趣可以去下载安装包安装。Redis配置ansible.cfg文件如下所示:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
Memcache缓存Fact信息
Ansible Facts存储还支持Memcached 存储,配置方法也很简单,在安装完Memcached服务并运行后,
同时安装Python的Memcached依赖包,最后配置ansible.cfg即可:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = memcached
4 Ansible软件日常维护和使用
4.1 本章价值
通过本章节,您将学习到如何维护Ansible的Inventory,来管理不同业务的不同机器,以便后续灵活的
对它们进行自动化运维操作;同时您也将学习到如何使用Ansible的一些常用组件,包括如何通过AD-Hoc命
令行的方式使用Ansible的各种模块,完成一些基本的自动化运维工作;如何编写和使用Playbook,来完成
复杂环境下的自动化运维工作;如何利用Facts组件来采集被管客户端的设备信息,来实现配置管理系统(
CMDB)的自动采集能力等等。
4.2 Ansible Inventory维护
Inventory文件
在日常维护中,Ansible通过Inventory(可管理的主机集合),对远端服务器或者主机进行统一操作和
管理。在Ansible中,描述主机的默认方法是将他们列在一个文本文件中,这个文件称为Inventory文件,默
认的路径和文件为:/etc/ansible/hosts,可以通过ANSIBLE_HOSTS环境变量来指定,也可以在ansible.cfg
文件中通过inventory参数指定,或者在运行ansible和ansible-playbook的时候使用-i参数来临时指定。
下面举例说明,如何在inventory组件的/etc/ansible/hosts文件中定义主机和主机组:
1 X.X.X.100 ansible_ssh_pass='123456'
2 [groupname1]
3 X.X.X.10[1:9]
4 X.X.X.20[1:9]
5 [groupname1:vars]
6 ansible_ssh_pass='123456'
7 [groupname2:children]
8 groupname1
第一行定义了一个主机X.X.X.100,并使用inventory内置变量ansible_ssh_pass定义了该主机的登录密
码,如果建立了互信,则不需要这个参数;
第二、三、四行定义了一个名为groupname1的主机组,其中包含X.X.X.101-X.X.X.109,
X.X.X.201-X.X.X.209共计18台主机;
第五、六行为groupname1的主机组定义了一个共同的变量:ansible_ssh_pass,以定义该组内所有主
机的登录密码;
第七、八行定义了一个更大的组:groupname2,其下包含了groupname1组下的所有主机。
定义好之后,我们在ansible命令行和ansible-playbook中,可以非常灵活的使用,便于批量操作。例如
批量查看groupname1组下所有主机的当前时间:
ansible groupname1 -a date
Inventory内置参数
除了前面介绍的ansible_ssh_pass参数,Ansible Inventory内置了一些参数,这些参数在我们实际工作
中也会经常使用,我们可以直接在Inventory文件中定义它。
我们也可以在ansible.cfg文件中的[defaults]部分更改一些Inventory内置参数的默认值,可以支持更改
的有:
动态Inventory
在实际的应用中,会存在大量的主机列表信息,如果手动维护Ansible中的Inventory文件将会非常的繁
琐,所以支持动态Inventory将会让问题变得统一、清晰、简单许多。动态Inventory也就是Ansible所有的
Inventory文件里面的主机列表和变量信息都支持从外部拉取,例如我们常用的CMDB,我们可以通过定义的
脚本,将外部CMDB等其他运维系统中的主机信息同步至Ansible中。在实际的配置中仅需要更改ansible.cfg
文件中的inventory参数为一个可执行的脚本即可。
[defaults]
inventory = /etc/ansible/inventory.sh
脚本的内容不受任何编程语言限制,但该脚本必须支持以下规范的参数,脚本的执行结果也有一定的
要求:
--list或者-l,脚本运行该参数须显示所有主机和组的信息(Json格式)。
--host或者-H,脚本的该参数后需指定一个主机,运行结果也会返回该主机的所有信息(同样也必须
为Json格式)。
脚本调试好之后,ansible将利用inventory变量所指向的脚本,获取主机和组信息(或者通过-i参数指
定),来向主机执行命令。
Inventory分割
如果我们想要同时使用常规Inventory文件和动态Inventory脚本,或者按不同业务/系统分割成的多个
Inventory文件,我们可以把所有这些文件全部都放到同一个目录,并配置ansible.cfg文件的hostfile参数,让
Ansible使用hostfile参数所指定的目录作为Inventory即可,也可以在命令行中使用-i命令来指定特定的
Inventory文件。Ansible将会处理目录里所有的文件并将结果合并为一个完整的Inventory。
[defaults]
hostfile = /etc/ansible/inventory
4.3 Ansible Ad-Hoc命令使用
Ansible系统由控制主机对被管节点的操作方式可分为两类,即 Ad-Hoc和Playbook:
Ad-Hoc模式使用单个模块,支持批量执行单条命令。
Playbook模式是Ansible主要管理方式,也是Ansible功能强大的关键所在,Playbook通过多个Task集合
完成一类功能,如 Web 服务的安装部署、数据库服务器的批量备份等,可以简单地把 Playbook理解为通过
组合多条Ad-Hoc操作的配置文件。
下面将通过两个小节的内容,来说明如何使用Ad-Hoc和Playbook。其中Ad-Hoc将重点介绍命令参数
和几个常用的模块。
通常我们会以命令行的形式使用Ansible模块,或者将Ansible命令嵌入到脚本中去执行。Ansible自带了
很多模块,我们可以直接使用他们。当我们不知道如何使用这些模块时,可以ansible-doc命令获取帮助,
例如:使用“ansible-doc -l”命令可以显示所有自带的模块和相关简介,使用“ansible-doc 模块名”命令可以
显示该模块的参数及用法等内容。
Ansible Ad-Hoc命令参数
我们可以使用“ansible -h”命令来列出所有的命令参数,下面列举了常用的一些参数,部分参数如果不
指定将采用ansible.cfg中的设置值,或者采用原始默认值。
Ansible常用模块介绍
连通性测试
通常采用Ping模块来测试远程主机的运行状态:
ansible ip -m ping
执行命令
执行命令可以采用四种方式,第一种方式是利用Command模块在远程主机上执行命令,但Command
模块不支持管道命令,例如,查看某个主机的日期:
ansible ip -m command -a date -o
值得注意的是,Ansible默认的模块是Command,所以上面的命令可以简化为:
ansible ip -a date -o
第二种方式是利用Shell模块,切换到某个Shell执行远程主机上的Shell/Python脚本,或者执行命令,
Shell支持管道命令,功能较Command更强大灵活,例如:
ansible ip -m shell -a 'bash /root/test.sh' -o
ansible ip -m shell -a 'echo "123456"|passwd --stdin root'
第三种方式是利用Raw模块,Raw支持管道命令。Raw有很多地方和Shell类似,但是如果是使用老版本
Python(低于2.4),无法通过Ansible的其他模块执行命令,则需要先用到Raw模块远程安装Python-sim-
plejson后才能受管;又或者是受管端是路由设备,因为没有安装Python环境,那就更需要使用Raw模块去
管控了。例如:
ansible ip -m raw -a "cd /tmp;pwd"
第四种方式是利用Script模块,传输Ansible中控端上的Shell/Python脚本到远端主机上执行,即使远端
主机没有安装Python也可以执行,有点类似Raw模块。但Script只能执行脚本,不能调用其他指令,且不支
持管道命令,例如:
ansible ip -m script -a '/root/test.sh' -o
removes参数用来判断远端主机上是不是存在test.sh文件,如果存在,就执行管控机上的test.sh,不存
在就不执行:
ansible ip -m script -a 'removes=/root/test.sh /root/test.sh' -o
creates用来判断远端主机上是不是存在test.sh文件,如果存在,就不执行,不存在就执行管控机上的
test.sh文件:
ansible ip -m script -a 'creates=/root/test.sh /root/test.sh' -o
复制文件
常用的文件操作模块就是Copy模块,它主要用于将本地或远程机器上的文件拷贝到远程主机上。其主
要参数有以下几个:
复制本地文件的到远程主机:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh'
复制并修改文件的权限:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755'
复制并修改文件的属主:
ansible ip -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=755 owner=root'
复制文件前备份:
ansible ip -m copy -a 'src=test.sh backup=yes dest=/tmp'
服务管理
在Ansible Ad-Hoc中,Service模块可以帮助我们管理远程主机上的服务。例如,启动或停止远程主机
中的某个服务。但是该服务本身必须要能够通过操作系统的管理服务的组件所管理,例如Redhat6中默认通
过SysV进行服务管理,Redhat7中默认通过Systemd管理服务,如果该服务本身都不能被操作系统的服务管
理组件所管理,那么也不能被Service模块管理。该模块的几个常用参数如下:
启动服务:
ansible all -m service -a "name=sshd state=started"
停止服务:
ansible all -m service -a "name=sshd state=stopped"
开启服务自启动:
ansible all -m service -a "name=sshd enable=yes"
安装包管理
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
安装软件包:
ansible all -m yum -a 'name=nginx state=installed’
卸载软件包:
ansible all -m yum -a 'name=nginx state=removed'
临时启用local yum源安装最新版软件包:
ansible all -m yum -a 'name=nginx state=latest enablerepo=local'
用户管理
在Ansible Ad-Hoc中,可以通过User模块帮助我们管理远程主机上的用户,比如创建用户、修改用户、
删除用户、为用户创建密钥对等操作。该模块的几个常用参数如下:
增加用户、组和密码:
ansible ip -m group -a "name=testg”
ansible ip -m user -a "name=test group=testg password=123456 home=/home/test”
删除用户和用户主目录:
ansible ip -m user -a "name=test state=absent remove=yes"
4.4 Ansible Playbook使用
在Ansible Ad-Hoc中,可以通过Yum模块实现在远程主机上通过Yum源管理软件包,包括安装、升级、
降级、删除和列出软件包等。该模块的几个常用参数如下:
我们在使用Ansible时,绝大部分时间将花费在编写Playbook上,Playbook是一个Ansible术语,指的是
用于配置管理的脚本。Ansible的Playbook是使用YAML语法编写的。YAML是一种类似于Json的文件格式,
不过YAML更适合人来读写。我们在开始编写Playbook时,需要对YAML的语法有一定的了解,否则将经常
碰到语法错误。下面首先通过一个安装和配置ntpd服务的Playbook案例来介绍:
1 ---
2 - hosts: all
3 tasks:
4 - name: install ntpd Package
5 yum: name=ntp state=present
6 - name: copy ntp.conf
7 template: src=/tmp/ntp.conf.j2 dest=/etc/ntp.confowner=root group=root mode=0644
8 notify:
9 - restart ntpd service
10 handlers:
11 - name: restart ntpd service
12 service: name=ntpd state=restarted
第一行仅表示该文件为YAML格式文件,非必须。
第二行定义了该Playbook所针对的主机,all表示所有,也可以填写Inventory文件中的IP地址或者主机组
名称。
第三行表示下面开始定义Task任务。
第四、五行定义了一个具体Task任务(通过Yum安装ntpd服务),包含任务名称和执行动作,其中任
务名称为非必须,可以直接定义执行动作。
第六、七、八、九行定义了另一个具体Task任务(同步ntpd配置文件模板),并更改文件的属主、属
组和文件权限。notify和下面的handlers为配对使用,当ntpd配置文件模板同步至远端主机后,文件的MD5
值将发生变化,触发restart ntpd service这个handler。
第十、十一、十二行定义了上述handler的具体内容,包括名称和执行动作,也就是利用service模块来
重启ntpd服务。
编制好了Playbook,我们需要使用--syntax-check参数来对该脚本进行语法检查:
ansible-playbook ntpd.yaml --syntax-check
playbook: ntpd.yaml
语法检测过后,可以用--list-task参数来查看该Playbook中的所有Task:
ansible-playbook ntpd.yaml --list-task
playbook: ntpd.yaml
play #1 (X.X.X.2): X.X.X.2 TAGS: []
tasks:
install ntpd Package TAGS: []
copy ntp.conf TAGS: []
确认无误后,开始使用命令运行名为ntpd.yaml的Playbook:
ansible-playbook ntpd.yaml
后续如果我们的ntpd.conf.j2配置模板需要变更,并需要批量分发下去,我们可以指定copy ntp.conf这
个Task,只运行该Task:
ansible-playbook ntpd.yaml --start-at-task=’copy ntp.conf’
除了上述参数之外,ansible-playbook还有几个常用的参数:
--step同一时间只执行一个Task,每个Task执行前都会提示确认一遍。
--tags=TAGS当Play和Task的Tag为该参数指定的值时才执行,多个Tag以逗号分隔。
--skip-tags=SKIP_TAGS当Play和Task的Tag不匹配该参数指定的值时才执行。
根据前面的案例,我们对Playbook的大体写法和用法有了一个大致的认识,下面重点介绍几个Play-
book常用的使用要点:
Playbook的组成
一个Playbook包括一个或多个Play。一个Play由Host的无序集合与Task的有序列表组成。每一个Task
仅由一个模块构成。见下图所示:
Tasks List和Action
Play的主体部分是Task列表,Task列表中的各任务按次序逐个在Hosts中指定的主机上执行,即在所有
主机上完成第一个任务后再开始第二个任务。在运行Playbook时(从上到下执行),如果一个Host执行
Task失败,整个Task都会回滚,我们需要修正Playbook中的错误,然后重新执行即可。Task的目的是使用
指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等等,这意味着多次执行是安全的,因
为其结果一致。
另外,按照规范写法,每一个Task必须有一个名称Name,虽然这不是必须的,但这样在运行Playbook
时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个Task。如果没有定义Name,Action的值将
会用作输出信息中标记特定的Task,结果不好分辨。定义一个Task,常见的格式为“module: options”,例
如:“yum: name=httpd”。值得注意的是,Ansible的自带模块中,Command模块和Shell模块无需使用
key=value格式,直接编写要执行的命令即可。
Handlers
Handlers也是一些Task的列表,和一般的Task并没有什么区别。它是由通知者进行的Notify,如果没有
被Notify,则Handlers不会执行,如果被Notify了,则Handlers被执行。不管有多少个通知者进行了Notify,
等到Play中的所有Task都执行完成之后,Handlers也只会被执行一次。例如:
变量引用
我们可以在PlayBook中通过“vars: 变量名”的方式声明变量,并通过“{{变量名}}”的方式使用已声明的变
量。另外,我们还可以直接引用Ansible的变量,包括采集到的主机Fact中的变量,例如:通过ansi-
ble_all_ipv4_address来获取IPV4地址,或者通过ansible_distribution、ansible_distribution_version来获取操
作类型和版本信息。除此之外,还能引用已编辑好的Inventory文件中定义的主机变量,这样当安装完一些软
件,需要根据主机中定义的变量来做一些自动化配置时,将会非常好用。例如:
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
X.X.108.2 hostname="test"
上面的案例是通过vars的方式定义了package和service两个变量,并在下面的yum和service两个Task中
进行引用,第三个Task则是直接引用setup生成的Fact变量和来自Inventory文件中定义的主机变量host-
name,来实现将内容信息传递至远端主机的文件中,输出结果如下:
cat /tmp/test.txt
test:RedHat 7.2
条件判断
我们可以在PlayBook中通过“when: 变量==值”的方式声明一个条件判断,可以看出when的值是一个条
件表达式,如果条件判断成立,Task就执行,如果判断不成立,则task不执行。例如当我们需要根据变量、
Facts(setup)或此前任务的执行结果来作为某Task执行与否的前提时,则要用到条件判断,这时可以在
Playbook中使用when子句:在Task后添加when子句。另外,when子句支持jinjia2表达式或语法。
迭代
当我们有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变
量引用,并通过with_items语句指明迭代的元素列表即可。例如:
Templates
Jinja是基于Python的模板引擎。Template类是Jinja的另一个重要组件,可以看作一个编译过的模块文
件,用来生产目标文本,我们可以传递Python的变量给模板去替换模板中的标记。例如,我们在做Nginx安
装与配置时,有些监听端口、服务名称等配置可以通过变量的方式在Inventroy文件中为不同主机预定义好,
当我们定义好了一个模板,并将模板中的监听端口和服务名称设置为变量后,在运行Template这个Task时,
将会把不同主机的这些变量信息传递到模板中使用,实现配置的自动化。例如:
vi /tmp/httpd.conf.j2 #定义模板中的变量
Listen {{http_port}}
ServerName {{server_name}}
MaxClients {{access_num}}
vi /etc/ansible/hosts #定义Inventory文件中的变量与值
[test]
X.X.X.2 http_port=X.X.X.2:80 access_num=50 server_name="test:80"
安装Nginx时,将把Inventory文件中主机定义好的变量与值传递到模板中,并拷贝至该远端主机:
Tags
在一个Playbook中,我们一般会定义很多个Task,如果我们只想执行其中的某一个Task或多个Task时
就可以使用Tags标签功能了,例如:
ansible-playbook test.yml --tags="nginx"
4.5 Ansible Facts使用
Facts组件是Ansible用于采集被管主机设备信息的一个功能,当Ansible采集Fact的时候,它会收集被管
主机的各种详细信息:CPU架构、操作系统、IP地址、内存信息、磁盘信息等,这些信息保存在被称作Fact
的变量中。Ansible使用一个名为Setup的特殊模块来实现Fact的收集,在Playbook中默认会调用这个模块进
行Fact收集,在命令行中可以通过“ansible ip -m setup”来进行手动收集,整个Facts信息被包装JSON格式
的数据结构中, Ansible Facts是最上层的值。例如:
Facts还支持通过filter参数来查看指定信息,例如下面只查看远端主机的操作系统和版本:
查看远端主机的CPU和内存大小:
查看远端主机的各文件系统大小和剩余容量:
在Playbook中,Facts组件默认会收集很多的主机的基础信息,可以通过前面的Fact缓存机制,将这些
信息缓存到本地目录或者内存数据库中,在做配置管理的时候进行引用,也可以用来将获取的主机基础信息
自动同步到CMDB中去,实现基础信息的自动采集功能。下面通过通过演示,说明如何通过ansible-cmdb
插件,实现远端主机CPU自动同步至外部CMDB系统中。
首先,我们需要安装ansible-cmdb插件,下载链接如下:
其次,开始安装ansible-cmdb插件:
gzip -dc ansible-cmdb-1.27.tar.gz|tar -xvf -
cd ansible-cmdb-1.27
python setup.py install
生成所有主机的Fact信息并用filter过滤出主机CPU值:
ansible all -m setup -t /tmp/factout
ansible all -m setup -a “filter=ansible_processor_count” -t /tmp/cpu
通过ansible-cmdb插件以csv或sql格式输出IP地址和CPU颗数值:
PATH=/usr/local/bin:$PATH
ansible-cmdb -t csv -c name,cpus /tmp/cpu >/tmp/cpu.csv
ansible-cmdb -t sql /tmp/cpu >/tmp/cpu.sql
以csv格式或者sql格式导入信息至外部CMDB系统中(根据支持方式灵活选用),这里以postgres数据
库为例,通过转csv格式为sql格式导入至外部CMDB系统:
cpuinfo=$(cat /tmp/cpu.csv)
for cpu_info in $cpuinfo
do
ip=$(echo "$cpu_info" |awk -F"," '{print $1}'|sed 's/"//g')
cpu=$(echo "$cpu_info" |awk -F"," '{print $2}'|sed 's/"//g')
echo "update \"VirtualMachine\" set \"VCPU\"='$cpu' where \"IP\"='$cpuip' and \"Status\"='A';"
>>/tmp/cpu_info.sql
done
su - postgres -c "export PGPASSWORD=postgres;/opt/PostgreSQL/9.3/bin/psql -d cmdbuild -f
/tmp/cpu_info.sql"
当然,以上仅仅是简单的示例,事实上,我们可以利用好Ansible Fact的功能,实现更加复杂的CMDB
自动化采集功能。
07
运维技术岗岗位学习教程
剩余45页未读,继续阅读
2023-12-15 上传
2023-07-22 上传
2023-09-06 上传
2023-06-03 上传
2023-08-16 上传
2024-03-14 上传
AlbertEdison
- 粉丝: 6w+
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C语言快速排序算法的实现与应用
- KityFormula 编辑器压缩包功能解析
- 离线搭建Kubernetes 1.17.0集群教程与资源包分享
- Java毕业设计教学平台完整教程与源码
- 综合数据集汇总:浏览记录与市场研究分析
- STM32智能家居控制系统:创新设计与无线通讯
- 深入浅出C++20标准:四大新特性解析
- Real-ESRGAN: 开源项目提升图像超分辨率技术
- 植物大战僵尸杂交版v2.0.88:新元素新挑战
- 掌握数据分析核心模型,预测未来不是梦
- Android平台蓝牙HC-06/08模块数据交互技巧
- Python源码分享:计算100至200之间的所有素数
- 免费视频修复利器:Digital Video Repair
- Chrome浏览器新版本Adblock Plus插件发布
- GifSplitter:Linux下GIF转BMP的核心工具
- Vue.js开发教程:全面学习资源指南
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功