当前位置: 首页 > 科技观察

使用Ansible的第一天

时间:2023-03-21 20:04:53 科技观察

一位系统管理员分享有关如何使用Ansible在网络中配置机器并使它们正常工作的信息和建议。无论是第一次还是第五十次,启动并运行新的物理或虚拟计算机都是耗时且需要大量工作的。多年来,我使用了我创建的一系列脚本和RPM来安装所需的包并为我最喜欢的工具配置各种选项。这种方法效果很好,简化了我的工作,还减少了在键盘上键入命令所花费的时间。我一直在寻找更好的工作方式。在过去的几年里,我一直在听说和阅读有关Ansible的信息,它是一种用于自动配置和管理系统的强大工具。Ansible允许系统管理员在一个或多个playbook中为每个主机指定特定状态,然后执行使主机进入该状态所需的各种任务。这包括安装或删除各种资源,例如RPM或Apt包、配置和其他文件、用户、组等。由于一些琐事,我推迟了很长时间学习如何使用它。直到最近,我遇到了一个我认为Ansible可以轻松解决的问题。这篇文章不会告诉你如何开始使用Ansible,它只是记录我遇到的问题和我在一些隐藏的地方找到的信息。我在各种在线讨论和问答组中发现的关于Ansible的大部分信息都是错误的。错误的范围从明显的旧信息(没有日期或来源的指示)到一些完全错误的信息。本文描述的内容有效,尽管可能有其他方法可以完成同样的事情,但我使用的是Ansible2.9.13和Python3.8.5。我的问题我所有最好的学习经历都是从我需要解决的问题开始的,这次也不例外。我一直在做一个小项目来修改MidnightCommander文件管理器的配置文件,并将它们推送到我网络上的各种系统以进行测试。即使我有一个自动执行此操作的脚本,它仍然需要循环遍历命令行以提供我要将新代码推送到的系统的名称。我对配置文件做了很多更改,这使我不得不经常推送新的配置文件。然而,就在我认为我的新配置刚刚好时,我发现了一个问题,所以我需要在修复后再次推送。这种环境使得很难跟踪哪些系统有新文件,哪些系统没有。我也有一些主机需要区别对待。我对Ansible的一点了解表明它可能能够完成我的全部或大部分工作。我一开始读了很多关于Ansible的好文章和书籍,但从来没有读过“我必须马上得到它!”的感觉。情况。而现在——好吧,现在!在重新阅读文档时,我发现他们主要在谈论如何从GitHub安装和使用Ansible,这非常酷。但我真的只是想尽快开始,所以我使用DNF和Fedora存储库中的版本将它安装在我的Fedora工作站上,非常简单。但后来我开始寻找文件位置并试图弄清楚哪些配置文件需要修改,在哪里保存我的剧本,甚至剧本是如何编写的以及它的作用,我有一大堆(到目前为止)悬而未决的问题。因此,无需进一步描述我的困难,以下是我的发现以及促使我继续前进的原因。配置Ansible的配置文件保存在/etc/ansible中,这是有道理的,因为/etc/是系统程序应该保存其配置文件的地方。我需要使用的两个文件是ansible.cfg和hosts。ansible.cfg在做了一些我从文档和网上找到的实践练习后,我遇到了一些关于弃用一些旧的Python文件的警告消息。所以我在ansible.cfg中将deprecation_warnings设置为false这样那些愤怒的红色警告消息就不会出现了:deprecation_warnings=False这些警告很重要所以我稍后会重新访问它们并弄清楚我需要做什么什么。但现在,它们不再使屏幕混乱,也不再用实际需要注意的错误来混淆我。主机文件不同于/etc/hosts文件。主机文件也称为清单文件,它列出了网络上的主机。该文件允许将主机分组到相关的集合中,例如“服务器”、“工作站”以及您想要的任何内容。这个文件里面有帮助,还有很多例子,这里就不赘述了。但是,有些事情您必须知道。主机也可以列在组之外,但组对于识别具有一个或多个特征的主机很有用。组使用INI格式,因此服务器组如下所示:[servers]server1server2...此文件中必须有一个主机名,以便Ansible对其进行操作。即使某些子命令允许指定主机名,除非主机名在主机文件中,否则该命令将失败。一台主机也可以放在多个组中。因此,server1除了是[servers]组之外,也可能是[webservers]组的成员,也可能是[ubuntu]组的成员,以区别于Fedora服务器。Ansible很聪明。如果all参数用作主机名,Ansible会扫描主机文件并在它列出的所有主机上执行定义的任务。Ansible只会尝试在每个主机上工作一次,无论它出现在多少个组中。这也意味着不需要定义all组,因为Ansible可以确定文件中的所有主机名并创建自己的唯一列表主机名。另一件需要注意的事情是单个主机的多个条目。我在我的DNS文件中使用CNAME记录来创建指向某些主机的A记录的别名,这样我就可以将主机称为host1或h1或myhost。如果您在hosts文件中为同一主机指定多个主机名,Ansible将尝试在所有主机上执行其任务,它无法知道它们指向同一主机。好消息是这不会影响整体结果;它只需要一点时间,因为Ansible将在辅助主机名上运行,并且它将确保所有内容都已执行。Ansiblefacts我读过的关于Ansible的大部分资料都在谈论Ansiblefacts,它们是与远程系统相关的数据,包括操作系统、IP地址、文件系统等。这些信息可以通过其他方式获取,比如lshw、dmidecode或/proc文件系统等。但是Ansible会生成一个包含这些信息的JSON文件。每次Ansible运行时,它都会生成这些事实。在这个数据流中,有大量的键值对形式的信息:<"variable-name":"value">。所有这些变量都在Ansible剧本中可用,理解大量可用信息的最佳方法是实际显示它:#ansible-msetup|明白了吗?你想知道的关于主机硬件和Linux发行版的一切都在这里,而且都可以在剧本中找到。我还没有达到需要使用这些变量的地步,但我相信在接下来的几天里我会的。模块上方的ansible命令使用-m选项指定设置模块。Ansible已经内置了许多模块,因此您无需为这些模块使用-m。还有许多可以安装的下载模块,但内置模块可以满足我当前项目所需的一切。剧本剧本几乎可以放在任何地方。因为我需要以root身份运行,所以我把它放在/root/ansible下。当我运行Ansible时,只要这个目录是当前工作目录(PWD),它就可以找到我的剧本。Ansible还可以选择在运行时指定不同的剧本和位置。剧本可以包含评论,但我见过的很少有文章或书籍提到这一点。但作为一个相信记录一切的系统管理员,我发现使用注释很有帮助。这不是关于在笔记中做与任务名称相同的事情,而是确定任务组的目的并确保我记录为什么我以某种方式或顺序做它们。当我可能忘记了最初的想法时,这可以帮助我稍后调试问题。剧本只是定义主机所需状态的任务集合。在剧本的开头指定主机名或清单组,并定义Ansible将在其上运行剧本的主机。下面是我的一个剧本示例:###################################################################################这个Ansibleplaybook更新了Midnightcommander配置文件。###################################################################################-名称:更新午夜指挥官配置文件主机:所有任务:-名称:确保午夜指挥官是最新版本dnf:name:mcstate:present-name:create~/.config/mcdirectoryforrootfile:path:/root/.config/mcstate:directorymode:0755owner:rootgroup:root-name:为dboth文件创建~/.config/mc目录:路径:/home/dboth/.config/mc状态:目录模式:0755所有者:dboth组:dboth-名称:copylatestpersonalskincopy:src:/root/ansible/UpdateMC/files/MidnightCommander/DavidsGoTar.inidest:/usr/share/mc/skins/DavidsGoTar.inimode:0644owner:rootgroup:root-name:copylatestmcinifile复制:src:/root/ansible/更新MC/files/MidnightCommander/inidest:/root/.config/mc/inimode:0644owner:rootgroup:root-name:copylatestmcpanels.ini文件copy:src:/root/ansible/UpdateMC/files/MidnightCommander/panels.inidest:/root/.config/mc/panels.inimode:0644owner:rootgroup:root该脚本以它自己的名称和它将运行的主机开始,在本例中是所有主机在我的主机文件中,任务部分列出了使主机进入所需状态的特定任务。该剧本首先使用DNF更新MidnightCommander(如果不是最新版本)。下一个任务确保创建所需的目录(如果它们不存在),其余任务将文件复制到适当的位置。这些文件和复制任务还可以为目录和文件设置所有权和文件模式。脚本细节超出了本文的范围,但我对这个问题使用了一点蛮力。还有其他方法可以确定哪些用户需要更新文件,而不是对每个用户每个文件使用一个任务。我的下一个目标是简化这个脚本并使用一些更高级的技术。运行剧本很简单,只需使用ansible-playbook命令即可。.yml扩展名代表YAML,我见过它的几种不同含义,但我认为它是“另一种标记语言”,尽管有些人声称YAML不是这种语言。此命令将运行playbook,这将更新MidnightCommander文件:#ansible-playbook-f10UpdateMC.yml-f选项指定Ansible使用10个线程来执行操作。这可以大大加快整个任务的完成速度,尤其是在多台主机上工作时。输出剧本运行时,会列出每个任务和执行结果。ok表示任务管理的机器状态已经完成,因为任务中定义的状态已经为真,所以Ansible不需要做任何事情。changed表示Ansible已经执行了指定的任务。在这种情况下,任务中定义的机器状态不为真,因此执行指定的操作使其为真。在彩色终端上,任务行以彩色显示。我的终端配色方案是“amber-on-black”,TASK行是琥珀色,changed是棕色,ok是绿色,errors是红色。下面的输出是我最终用来在新主机上执行安装后配置的剧本:PLAY[安装后更新、软件包安装和配置]TASK[GatheringFacts]ok:[testvm2]TASK[确保我们有连接]好的:[testvm2]TASK[安装所有当前更新]更改:[testvm2]TASK[安装一些命令行工具]更改:[testvm2]TASK[将最新的个人MidnightCommander皮肤复制到/usr/share]更改:[testvm2]TASK[为root创建~/.config/mc目录]更改:[testvm2]TASK[将最新的MidnightCommander配置文件复制到/root/.config/mc]更改:[testvm2]=>(item=/root/ansible/PostInstallMain/files/MidnightCommander/DavidsGoTar.ini)已更改:[testvm2]=>(item=/root/ansible/PostInstallMain/files/MidnightCommander/ini)已更改:[testvm2]=>(item=/root/ansible/PostInstallMain/files/MidnightCommander/panels.ini)TASK[create~/.config/mcdirectoryin/etc/skel]changed:[testvm2]cowsay如果你有奶牛ay程序安装在你的电脑上,你会发现TASK对话泡泡中出现牛的名字:__________________________________<任务[确保我们有连接]>------------------------------------\^__^\(oo)\\_______(__)\)\/\||----w|||||如果你没有这个有趣的程序,你可以使用你的发行版的包管理器来安装Cowsay程序如果你有这个程序但不想要它,可以通过在/etc/ansible/ansible中设置nocows=1来禁用它.cfg文件。我喜欢这头牛,它很有趣,但它占据了我屏幕的一部分。因此,当它开始妨碍我时,我将其禁用。目录与我的MidnightCommander任务一样,经常需要安装和维护各种类型的文件。有多少系统管理员就有多少创建用于存储playbook的目录树的“最佳实践”,至少有多少作者写关于Ansible的书籍和文章。我选择了一个对我有意义的简单结构:/root/ansible└──UpdateMC├──files│└──MidnightCommander│├──DavidsGoTar.ini│├──ini│└──panels.ini└──UpdateMC.yml你可以使用任何结构。但是请注意,其他系统管理员可能需要使用您设置的脚本,因此目录应该具有一定的逻辑级别。在我使用RPM和Bash脚本执行安装任务后,我的文件存储库有点分散,完全没有逻辑结构。当我为许多管理任务创建剧本时,我引入了一个更符合逻辑的结构来管理我的目录。多次运行剧本根据需要或期望多次运行剧本是安全的。只有当主机状态与任务中指定的状态不匹配时,才会执行每个任务。这使得从以前的剧本运行中遇到的错误中恢复变得容易。因为当playbook遇到错误时,它会停止运行。在测试我的第一个脚本时,我犯了很多错误并修正了它们。假设我的修复是正确的,每次运行剧本时,它都会跳过状态已经符合指定状态的任务,并执行不符合指定状态的任务。当我的修复工作时,先前失败的任务成功完成,并执行此任务之后的任务——直到遇到另一个错误。这使得测试变得容易。我可以添加新任务,当我运行playbook时,只会执行新任务,因为它们是唯一与测试主机的所需状态不匹配的任务。一些思考有些任务不适合Ansible,因为有更好的方法来实现特定的计算机状态。我想到的场景是将VM返回到初始状态,以便可以多次使用它来执行从已知状态开始的测试。将VM置于特定状态然后为此时的计算机状态拍摄快照要容易得多。恢复到这个快照通常比Ansible将主机恢复到以前的状态更容易和更快。在研究文章或测试新代码时,我每天都会这样做几次。完成更新MidnightCommander的playbook后,我创建了一个新的playbook来在新安装的Fedora主机上执行安装任务。我取得了不错的进步,脚本比我的第一个脚本更复杂,但没有那么粗糙。在我使用Ansible的第一天,我创建了一个playbook来解??决这个问题,我也开始编写第二个playbook来解??决安装后配置这个大问题,在这个过程中我学到了很多东西。虽然我真的很喜欢使用Bash脚本来管理任务,但我发现Ansible可以做我想做的一切,并将系统保持在我需要的状态。仅仅一天时间,我就成为了Ansible的粉丝。