本章首先介绍 Ansible 服务的背景、相关术语以及主机清单的配置,期间会和大家深入学习 ping、yum、firewalld、service、template、setup、lvol、lvg、copy、file、debug 等十余个常用的 Ansible 模块。然后动手实操的方式介绍从系统中加载角色、从外部环境获取角色或自行创建角色,此外通过编写的 playbook(剧本)文件,以实操的方式创建逻辑卷设备,依据主机改写文件、管理文件属性等;最后以使用 Ansible 的 vault 对变量以及剧本文件进行加密来收尾。
16.1 Ansible 介绍与安装
Ansible 目前是运维自动化工具中最容易上手的一款优秀软件,能够用来管理各种资源;可以对服务器进行初始化配置、安全基线配置,以及更新和打补丁操作。相较于 Chef、Puppet、SaltStack 等 C/S(客户端/服务器)架构的自动化工具来讲,尽管 Ansible 的性能并不是最好的,但由于它基于 SSH 远程会话协议,不需要客户端程序,只要知道受管主机的账号密码,就能直接用 SSH 协议进行远程控制。
2012 年 2 月程序员 Michael DeHaan 发布了 Ansible 的第一个版本,Michael DeHaan 在配置管理和架构设计方面拥有丰富的经验,他此前在红帽公司任职时,就研发了 Cobbler 自动化系统安装工具。在此之前他被各种自动化软件折磨了好久,最终决定自己打造一款集众多软件的优点于一身的自动化工具。Ansible 由此诞生!在 GitHub 上的 star 和 fork 数量是 SaltStack 的两倍多,2015 年 Ansible 正式被红帽公司收购,这足以看出受欢迎的程度。
Ansible 服务本身并没有批量部署的功能,它仅仅是一个框架,真正具有批量部署能力的是其所运行的模块;Ansible 内置了上千个模块,会在安装 Ansible 时一并安装,通过调用指定的模块,就能实现特定的功能。如果需要更高级的功能,也可以运用 Python
语言对 Ansible 进行二次开发。
当前 Ansible 已经被 Amazon、Google、Microsoft、Cisco、HP、VMware、Twitter 等大科技公司投入使用。红帽公司更是对自家产品进行了不遗余力的支持,从 2020 年 8 月
1 日起,RHCE 考试的内容由配置多种服务改成 Ansible 专项考题内容。
在安装配置 Ansible 之前,我们先了解一下相关的专用术语。
RHEL 8 系统的镜像文件默认不带有 Ansible 服务程序,需要从 Extra Packages for Enterprise Linux(EPEL)扩展软件包仓库获取。EPEL 软件包仓库由红帽公司提供,是一个用于创建、维护和管理企业版 Linux 的高质量软件扩展仓库,通用于 RHEL、CentOS、Oracle
Linux 等多种红帽系企业版系统。
下面准备安装 Ansible 服务程序;在“虚拟机设置”界面中,将“网络适配器”的“网络连接”选项调整为“桥接模式”,并将系统的网卡设置成“Automatic(DHCP)”模式。
设置完成后重启网卡让其生效联通外网,可用 ping命令测试。
在原有软件仓库配置的下方追加 EPEL 扩展软件包安装源,如果系统未注册又要连接到 EPEL 仓库,可能会导致 yum 安装功能被停用,因此可以先下载 ansible 的rpm包到本地然后用rpm -ivh 安装。
安装完毕后 Ansible 服务便默认已经启动,使用 –version 参数可以看到 Ansible 服务的版本及配置信息。
16.2 设置主机清单
在初次配置 Ansible 服务时可能会遇到这种情况:参数明明已经修改好了却不生效。这是因为 Ansible 服务的主配置文件存在优先级的顺序关系,默认存放在/etc/ansible 目录中的主配置文件优先级最低。如果在当前目录或用户家目录中也存放着一份主配置文件,这时配置文件优先级顺序如图。
我们可以把要管理的主机 IP 地址预先写入/etc/ansible/hosts 文件,后续再通过 ansible 命令来执行任务时就自动包含这些主机了,也就不需要每次都重复输入受管主机的地址了。主机清单文件/etc/ansible/hosts 中默认存在大量的注释信息,可以全部删除,然后替换成实验信息。
为了尽量模拟生产环境中的常见需求,我们来用 5 台主机分别规划功能用途,有开发机(dev)、测试机(test)、产品机(prod)和负载均衡机(balancers)。对主机进行分类标注后,后期在管理时就方便多了。
主机清单文件在修改后会立即生效,可以使用“ansible-inventory –graph”命令以结构化的方式显示出受管主机的信息,在受管主机进行了分组的情况下,这种方式非常便于我们的阅读。
Ansible 服务是基于 SSH 协议进行自动化控制的,在初次连接时会要求用户接受一次对方主机的指纹信息,即输入受管主机的账号和密码。但自动化运维的优点之一就是能提高工作效率,如果每次执行操作都要输入受管主机的密码,是比较麻烦的事情。好在 Ansible 服务已经对此有了解决办法,那就是使用下图的变量。
我们只需要将对应的变量及信息填写到主机清单文件中,在执行任务时便会自动对账号和密码进行匹配(all 代表5台主机密码都为:rhel.9),而不用每次重复输入它们。继续修改主机清单文件 /etc/ansible/hosts。
再将 Ansible 主配置文件 /etc/ansible/ansible.cfg 中的第 71 行删除 # 号,即不需要 SSH 协议的指纹验证,第 107 行也删除 # 号,即执行剧本时所使用的远程用户名称为 root。
完成后立即生效不需要重启服务。由于刚才连接 epel 仓库网卡为桥接模式,现在将网卡修改回“仅主机模式”以及 192.168.187.128/24 的 IP 地址。在修改完成后重启网卡,执行 ping 操作。保证主机之间的网络能够互通。
16.3 运行临时命令
Ansible 服务的强大之处在于只需要一条命令,便可以操控成千上万台的主机节点,前文提到 Ansible 服务实际上只是一个框架,能够完成工作的是模块化功能代码,Ansible 的常用模块大致有 20 多个见下图;遇到这里没有提及的模块,可以使用“ansible-doc [模块名称]”的命令格式自行查询,或是使用 ansibe-doc -l 命令列出所有的模块信息。
在使用 ansible 命令时,必须指明受管主机的信息,如果已经设置过主机清单文件(/etc/ansible/hosts),则可以使用 all 参数来指全体受管主机,或是用 dev、test 等组名称来指某一组的主机。
ansible 命令常用的语法格式为“ansible 受管主机节点 -m 模块名称[-a 模块参数]”,常见的参数见下图。-a 是要传递给模块的参数,只有功能极其简单的模块才不需要额外参数,所以大多情况下-m 与-a 参数都会同时出现。
一般很难通过名称来判别一个模块的作用,要么是参考模块后面的介绍信息,要么是平时多学多练多积累。例如随机查看一个模块的详细信息。ansible-doc
命令会在屏幕上显示出这个模块的作用、可用参数及实例等信息。
前面已经将受管主机的 IP 地址填写到主机清单文件中,我们来检查一下这些主机的网络连通性。ping 模块用于进行简单的网络测试(类似于常用的 ping 命令),可以使用 ansible 命令针对所有主机调用 ping 模块,返回值若为 SUCCESS,则表示主机当前在线,由于 22 和 23 还有未截图到的 24 主机故意没开机所以连接失败。
除了使用-m 参数指定模块名称之外,还可以用 -a 参数将参数传递给模块,让模块的功能更高级,更好地满足当前生产的需求。比如 yum_repository 模块的作用是管理主机的软件仓库,能够添加、修改及删除软件仓库的配置信息。可以执行 ansible-doc yum_repository 对其进行了解。尤其是下面的 EXAMPLES 结构段会有该模块的实例,对用户来说有非常高的参考价值。
可见与此前学过的 /etc/yum.repos.d/目录中的 .repo 配置文件基本相似。现在为主机清单中的所有服务器新增下列软件仓库,该怎么操作呢?可以对照着 EXAMPLE 实例段,逐一对应填写需求值和参数,其标准格式是在 -a 参数后接整体参数(用单引号圈起),而参数值则用双引号圈起,这是最严谨的写法。
仓库名称 |
EX294_BASE |
仓库描述 |
EX294 base software |
仓库地址 |
file:///media/sr0/ |
GPG签名 |
启用 |
GPG密钥文件 |
file:///media/sr0/RPM-GPG-KEY-CentOS-7 |
在执行下述命令后如果出现 CHANGED 字样,则表示修改已经成功。
我们到主机清单中的任意机器上查看新建成功的软件仓库配置文件,尽管这条命令的参数很多,但是理解并不难。
16.4 剧本文件实战
Ansible 服务的 playbook(翻译为剧本)允许用户根据需求,在类似于 Shell 脚本的模式下编写自动化运维脚本,然后由程序自动、重复地执行,从而大大提高了工作效率。
playbook 文件采用 YAML 语言编写,具有强制性的格式规范,通过空格将不同信息分组,因此有时会因一两个空格错位而导致报错。YAML 文件的开头需要先写 3 个减号(—),多个分组的信息需要间隔一致才能执行,而且上下也要对齐,后缀名一般为.yml。
playbook 文件在执行后,会在屏幕上输出运行界面,内容会根据工作的不同而变化。绿色表示成功,黄色表示成功并进行了修改,而红色则表示执行失败。
文件的结构由 4 部分组成,分别是 target、variable、task、handler,其各自的作用如下。
➢ target:用于定义要执行剧本的主机范围。
➢ variable:用于定义剧本执行时要用到的变量。
➢ task:用于定义将在远程主机上执行的任务列表。
➢ handler:用于定义执行完成后需要调用的后续任务。
YAML 语言编写的 Ansible 剧本文件会按照从上到下的顺序自动运行,其形式类似于第 4 章介绍的 Shell 脚本,但格式有严格的要求。例如创建一个名为 install.yml 的剧本,让 dev、test 和 prod 组的主机可以自动安装数据库软件,并且将 dev 组主机的软件更新至最新。
安装和更新软件需要使用 yum 模块,先用 ansible-doc yum 看一下EXAMPLES 结构段信息中的示例。
在知道 yum
模块的使用方法和格式后,就可以开始编写剧本了;初次编写剧本文件时,请务必看准格式,模块及 play(动作)格式也要上下对齐,否则会出现“参数一模一样,但不能执行”
的情况。
上图 name 字段表示此项 play(动作)的名字,用于在执行过程中看名字知道执行到了哪一步,大家可以自定义命名;hosts 字段表示要在哪些主机上执行该剧本,多个主机组之间用逗号间隔,如果需要对全部主机进行操作,则使用 all 参数;tasks 字段用于定义要执行的任务,每个任务下都要有独立的 name 字段进行命名,并且每个任务的 name 字段和模块名称都要严格上下对齐,参数要与上级单独缩进。
下面开始用 ansible-playbook 命令运行这个剧本文件, 可用命令 ansible-playbook –syntax-check [剧本名] 来检测剧本有无错误,如果其中某台主机没开机出现了 fatal 失败,那么根据运行规则后面的安装也不会继续下去。
我们来观察最下方的输出信息;其中 ok 和 changed 表示执行及修改成功。如遇到 unreachable 或 failed 大于 0 的情况,建议手动检查剧本是否在所有主机中都正确运行了,在正确执行过 install.yml 文件后,随机切换到 dev、test、prod 组中的任意一台主机上,再次安装 mariadb 软件包,此时会提示该服务已经存在。
16.5 创建及使用角色
剧本在任务多时会有越来越长的情况,这不利于进行阅读和维护,而且还无法让其他剧本灵活地调用其中的功能代码。角色(role)这一功能则是自 Ansible 1.2 版本开始引入的新特性,用于层次性、结构化地组织剧本。角色功能分别把变量、文件、任务、模块及处理器配置放在各个独立的目录中,然后对其进行便捷加载。
角色的好处就在于将剧本组织成了一个简洁的、可重复调用的抽象对象,使得用户把注意力放到剧本的宏观大局上,只有在需要时才去深入了解细节。角色的获取有 3 种方法,分别是加载系统内置角色、从外部环境获取角色以及自行创建角色。
16.5.1 加载系统内置角色
在使用 RHEL 系统的内置角色时,我们不需要联网就能实现。用户只需要配置好软件仓库的配置文件,然后安装包含系统角色的软件包 rhel-system-roles,随后便可以在系统中找到它们了。
安装完毕后,可以使用 ansible-galaxy list 命令查看 RHEL 8 系统中有哪些自带的角色可用。
这些由系统镜像自带的角色,它们在日常的工作中能派上大用场,角色的主要功能如图。以 rhel-system-roles.timesync 角色为例,它用于设置系统的时间和 NTP 服务,让主机能够同步准确的时间信息。剧本模板文件存放在 /usr/share/doc/rhel-system-roles/timesync/目录中,可以复制过来修改使用。
在复制来的剧本模板文件中,删除掉多余的代码,将 NTP 服务器的地址填写到 timesync_ntp_servers 变量的 hostname 字段中即可。该变量的参数含义如图所示。稍后 timesync 角色就会自动为用户配置参数信息了。
16.5.2 从外部环境获取角色
Ansible Galaxy 是 Ansible 的一个官方社区,用于共享角色和功能代码,用户可以在网站自由地共享和下载 Ansible 角色。左侧有 3 个功能选项,分别是首页(Home)、搜索(Search)以及社区(Community)。单击 Search 按钮进入到搜索界面,这里以 nginx 服务为例进行搜索,即可找到 Nginx 官方发布的角色信息如图。
当单击 nginx 角色进入到详情页面后,会显示这个项目的软件版本、评分、下载次数等信息。在 Installation 字段可以看到相应的安装方式。
如果需要使用这个角色,可以在虚拟机联网的状态下直接按照“ansible-galaxy install
角色名称”的命令格式自动获取;安装成功后再次查看系统中已有的角色,便可找到 nginx 角色信息了。
➢ 在国内访问 Ansible Galaxy 官网时可能存在不稳定的情况,导致访问不了或者网速较慢。
➢ 某位作者将作品上传到了自己的网站,或者除 Ansible Galaxy 官网以外的其他平台。
在这两种情况下,就不能再用“ansible-galaxy install 角色名称”的命令直接加载了,而是需要手动先编写一个 YAML 语言格式的文件,指明网址链接和角色名称,然后再用 -r 参数进行加载。
例如刘遄老师在网站上传了一个名为 nginx_core
的角色软件包(一个用于对 nginx 网站进行保护的插件),这时需要编写如下内容的 yml
配置文件,然后使用 ansible-galaxy 命令的 -r 参数加载这个文件,完成后即可查看到新角色信息了。
16.5.3 自行创建角色
除了能够使用系统自带的角色和从 Ansible Galaxy 中获取的角色之外,也可以自行创建符合工作需求的角色。这种定制化的编写工作能够更好地贴合生产环境的实际情况,但难度也会稍高一些。
我们来创建一个名为 apache 的新角色:规划它能够实现自动安装、运行 httpd 网站服务,设置防火墙的允许规则,以及根据每个主机生成独立的 index.html 首页文件。在 Ansible 的主配置文件 /etc/ansible/ansible.cfg 第 68 行定义的是角色保存路径。如果用户新建的角色信息不在规定的目录内,则无法使用 ansible-galaxy list 命令找到;因此需要手动填写新角色的目录路径,或是进入/etc/ansible/roles 目录内再进行创建。
为了避免后期角色信息过于分散导致不好管理,我们还是在默认目录下进行创建;在 ansible-galaxy 命令后面跟一个 init 参数,创建一个新的角色信息,且建立成功后便会在当前目录下生成出一个新的目录;此时的 apache 即是角色名称,也是存放角色信息的目录名称;可以查看到里面的结构文件。
在创建新角色时,最关键的便是能够正确理解目录结构。通俗来说,就是要把正确的信息放入正确的目录中,这样在调用角色时才能有正确的效果。角色信息对应的目录结构及含义如表
下面准备创建 apache 下面用来完成工作的 playbook 文件。
第一步:
打开用于定义角色任务的 tasks/main.yml 文件。在该文件中不需要定义要执行的主机组列表,因为后面会单独编写剧本进行调用,此时应先对 apache 角色能做的事情(任务)有一个明确的思路,比如在调用角色后 yml 文件会按照从上到下的顺序自动执行哪些任务。
➢
任务1:安装 httpd 网站服务。
➢
任务2:运行 httpd 网站服务,并加入到开机启动项中。
➢
任务3:配置防火墙,使其放行 HTTP 协议。
➢
任务4:根据每台主机的变量值,生成不同的主页文件。
第一个任务使用 yum 模块安装 httpd 网站服务程序(注意格式)。
第二步:
第二个任务使用 service 模块启动 httpd 网站服务程序,并加入到启动项中。在初次使用模块前,再用 ansible-doc service 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
可以看到默认的 EXAMPLES 示例使用的就是 httpd 网站服务,通过输出信息可得知,启动服务为“state: started”参数,而加入到开机启动项则是“enabled: yes”参数。继续追加编写上面的main.yml 剧本。
第三步:
第三个任务使用 firewalld 模块配置防火墙的允许策略,让其他主机可以正常访问。同样用 ansible-doc firewalld 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
在 firewalld 模块设置防火墙策略时,指定协议名称为“service: http”
参数,放行该协议为“state: enabled”参数,设置为永久生效为“permanent: yes”参数,当前立即生效为“immediate: yes”参数(往下翻可以看到)。参数多了一些,但是基本与在第 8 章节学习的防火墙一致,继续追加编写上面的main.yml 剧本。
第四步:
让每台主机显示的主页文件均不相同;综上步骤可以发现在使用 Ansible 的常规模块时,都是采用“查询版主示例并模仿”的方式搞定的;这里为了增加新需求,让每台主机上运行的 httpd 网站都能显示不同的内容,例如显示当前服务器的主机名及 IP 地址,这就要用到 template 模块及 Jinja2 技术了。同样用 ansible-doc template 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
可以看出这是一个用于复制文件模板的模块,能够把文件从 Ansible 服务器复制到受管主机上。其中 src 参数用于定义本地文件的路径,dest 参数用于定义复制到受管主机的文件路径,而 owner、group、mode 参数可选择性地设置文件归属及权限信息。
一般我们可以直接复制文件的执行,受管主机上会获取到一个与 Ansible 服务器上的文件一模一样的文件。但现在我们想让每台客户端显示不同的文件信息,这就需要用到 Jinja2 技术了,Jinja2 格式的文件后缀是.j2。继续追加编写上面的main.yml 剧本。
Jinja2 是 Python 语言中一个被广泛使用的模板引擎,最初的设计思想源自 Django 的模块引擎;Jinja2 基于此发展了其语法和一系列强大的功能,能够让受管主机根据自身变量产生出不同的文件内容。在使用 template 模块进行复制的过程中,由 Ansible 服务负责在受管主机上收集这些变量名称所对应的值,然后再逐一填写到目标文件中,从而让每台主机的文件都根据自身系统的情况独立生成。
那么如何查询并收集到对应的变量名称、主机名及地址所对应的值保存在哪里?可以用 setup 模块进行查询,先用 ansible-doc setup 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
使用-a 参数外加 filter 命令可以对收集来的信息进行二次过滤。相应的语法格式为 ansible all -m setup -a ‘filter=”关键词“‘,其中*号是第 3 章节学习的通配符,用于辅助关键词查询;可以使用通配符搜索所有包含 fqdn 关键词的变量值信息。
FQDN(Fully Qualified Domain Name,完全限定域名)用于在逻辑上准确表示出主机的位置。FQDN 被作为主机名的完全表达形式,比/etc/hostname 文件中定义的主机名更加严谨和准确。通过输出信息可得知,ansible_fqdn 变量保存有主机名称。我们来进行 fqdn 查询看看结果。
继续查询 IP 相关信息;用于指定主机地址的变量可以用 ipv4 作为关键词进行检索;如果想要 ansible_all_ipv6_addresses
变量中的值则用关键词 IPv6 即可。
在确认了主机名与 IP 地址所对应的变量名称后,在角色所对应的 templates 目录内新建一个 Jinja2 格式文件(index.html.j2)将对应的名称与 IP 写入里面;格式为在变量名称的两侧加两个大括号。最后还需要编写一个用于调用 apache 角色的 yml
文件。
完成后就可以执行这个文件,顺利通过。
验证结果:
在浏览器中随机输入几台主机的 IP 地址,即可访问到包含主机 FQDN 和
IP 地址的网页了,或者就在命令行用 curl 命令也支持简单查看。
16.6 创建和使用逻辑卷
创建一个能自动管理逻辑卷设备的 playbook,不但能大大提高硬盘设备的管理效率,而且还能避免手动创建带来的错误。在每台受管主机上都创建出一个名为 log 的 150M 逻辑卷设备,归属于 research 卷组。如果创建成功,则进一步用 Ext4 文件系统进行格式化操作;如果创建失败,则给用户输出一条报错提醒,以便排查原因。
在这种情况下,使用 Ansible 剧本要比使用 Shell 脚本的优势大,原因主要有下面两点。
➢ Ansible 模块化的功能让操作更标准,只要在执行过程中无报错,那么便会依据远程主机的系统版本及配置自动做出判断和操作,不用担心因系统变化而导致命令失效的问题。
➢ Ansible 服务在执行剧本文件时会进行判断:如果该文件或该设备已经被创建过,或是某个动作(play)已经被执行过,则不会再重复执行;而使用 Shell 脚本有可能让设备被重复格式化导致数据丢失。
首先在 prod 组的主机上添加一块 20GB 硬盘设备,类型为 SCSI,其余选项选择默认值如图。热添加可能不会立即生效关机添加就好。
回忆第 7 章学习过的逻辑卷的知识,我们应该让剧本文件依次创建物理卷(PV)、卷组(VG)及逻辑卷(LV)。需要先使用 lvg 模块让设备支持逻辑卷技术,然后创建一个名为 research 的卷组。用 ansible-doc lvg 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
查看到创建逻辑卷总共有 3 个必备参数。其中 vg 参数用于定义卷组的名称,pvs 参数用于指定硬盘设备的名称,pesize 参数用于确定最终卷组的容量大小(可以用 PE 个数或容量值进行指定)。我们先创建出一个由 /dev/sdb 设备组成的名称为 research、大小为 150MB 的卷组 yml 文件。
由于刚才只在 prod 组的主机上添加了新硬盘设备,因此在执行上述操作时其余
3 台主机会提示未创建成功,这属于正常情况。接下来使用 lvol 模块创建出逻辑卷设备。用 ansible-doc lvol 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
可见 vg 参数用于指定卷组名称,lv 参数用于指定逻辑卷名称,size 参数则用于指定最终逻辑卷设备的容量大小(不用加单位,默认为 MB)。填写参数创建出一个大小为 150MB、归属于 research 卷组且名称为 log 的逻辑卷。继续追加编写lv.yml剧本。
如果还能将创建出的/dev/research/log 逻辑卷设备自动用 Ext4 文件系统进行格式化操作,则又能帮助运维管理员减少一些工作量。可使用 filesystem 模块来完成设备的文件系统格式化操作。用 ansible-doc filesystem 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
可见 filesystem 模块的参数很少,fstype 参数用于指定文件系统的格式化类型,dev 参数用于指定要格式化的设备文件路径。继续追加编写lv.yml剧本。
整个步骤顺利的话逻辑卷设备就能够自动创建好了。由于现在只有 prod 组的主机上添加了新的硬盘设备文件,其余主机是无法按照既定模块顺利完成操作的。这时就要使用类似于第 4 章学习的 if 条件语句来进行判断—如果失败……,则……。
首先用 block 操作符将上述的 3 个模块命令作为一个整体(相当于对这 3 个模块的执行结果作为一个整体进行判断),然后使用 rescue 操作符进行救援,且只有 block 块中的模块执行失败后才会调用 rescue 中的救援模块。其中 debug 模块的 msg 参数(类似echo)的作用是,如果 block
中的模块执行失败,则输出一条信息到屏幕,用于提醒用户。继续追加编写lv.yml剧本。
YAML 语言对格式有着硬性的要求,既然 rescue 是对 block 内的模块进行救援的功能代码,因此 recue 和 block 两个操作符必须严格对齐,错开一个空格都会导致剧本执行失败。可用命令 ansible-playbook –syntax-check lv.yml 检察一下语法,下图空行下给出名称为正常。
确认无误后就可以执行 playbook 了
在剧本运行完毕后的执行记录(PLAY RECAP)中可以看到只有 192.168.187.22 prod 组中的主机执行成功了,其余 3 台主机均触发了 rescue 功能。登录到 prod 组的主机上,找到新建的逻辑卷设备信息。
16.7 判断主机组名
在每个客户端中都会有一个名为 inventory_hostname 的变量,用于定义每台主机所对应的 Ansible 服务的主机组名称,也就是/etc/ansible/hosts 文件中所对应的分组信息,例如 dev、test、prod、balancers。
inventory_hostname 是 Ansible 服务中的魔法变量,这意味着无法使用 setup 模块直接进行查询,如 ansible all -m setup -a ‘filter=”*关键词*”‘这样的命令将对它失效。魔法变量需要在执行剧本文件时的 Gathering Facts 阶段进行搜集,直接查询是看不到的,只能在剧本文件中进行调用。
在获得了存储主机组名称的变量名称后,接下来开始实验。需求如下:
➢ 若主机在 dev 分组中,则修改/etc/issue 文件内容为 Development;
➢ 若主机在 test 分组中,则修改/etc/issue 文件内容为 Test;
➢ 若主机在 prod 分组中,则修改/etc/issue 文件内容为 Production。
在 Ansible 常用模块中,copy 模块的主要作用是新建、修改及复制文件,更符合当前的需要,此时便派上了用场;先用 ansible-doc copy 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
在输出信息中列举了两种管理文件内容的示例,第一种用于文件的复制行为,第二种是通过 content 参数定义内容,通过 dest 参数指定新建文件的名称;第二种更加符合当前的实验场景。编写剧本文件如下:
如果按照上图顺序执行下去,每一台主机的 /etc/issue 文件都会被重复修改 3 次,最终定格在“Production”字样,这显然不合适。我们应该依据 inventory_hostname
变量中的值进行判断,若主机为 dev 组,则执行第一个动作;若主机为 test 组,则执行第二个动作;若主机为 prod 组,则执行第三个动作。因此,要进行 3 次判断。
when 是用于判断的语法,我们将其用在每个动作的下方进行判断,使得只有在满足条件才会执行。继续追加插入编写 issue.yml 剧本,注意 when 语句要与 name 对齐。
完成后执行剧本文件,在过程中可清晰地看到由于 when 语法的作用,未在指定主机组中的主机将被跳过(skipping)。
直接用ansible 服务器查看结果,23 主机由于不在剧本内所以没有更改 issue 文件内容。
16.8 管理文件属性
创建文件、管理权限以及设置快捷方式几乎是每天都用到的技能。尤其是在第 5 章学习文件的一般权限、特殊权限、隐藏权限时,往往还会因命令的格式问题而导致出错。这么多命令该怎么记呢?Ansible 服务将常用的文件管理功能都合并到了 file 模块中,先用 ansible-doc file 命令查看位于信息最下方 EXAMPLES 结构段的实例帮助信息。
可见 path 参数定义了文件的路径,owner 参数定义了文件所有者,group 参数定义了文件所属组,mode 参数定义了文件权限,src 参数定义了源文件的路径,dest 参数定义了目标文件的路径,state 参数则定义了文件类型。
基本上把第 5 章学习过的管理文件权限的功能都包含在内了。
用 playbook 我们来挑战下面的实验吧。
创建出一个名为 /linuxprobe 的新目录,所有者及所属组均为 root 管理员身份;设置所有者和所属于组拥有对文件的完全控制权,而其他人则只有阅读和执行权限;给予 SGID 特殊权限; 且仅在 dev 主机组的主机上实施。
第二条权限是算术题,即将权限描述转换为数字表示法,即可读为 4、可写为 2、可执行为 1。此前在编写剧本文件时,hosts 参数对应的一直是 all,即全体主机,这次需要修改为仅对 dev 主机组成员生效,请注意区分值。
这里没能展示出 file 模块的强大之处,我们临时添加一个需求:再创建一个名称为 /linuxcool 的快捷方式文件,指向刚刚建立的 /linuxprobe 目录。
这样用户在访问两个目录时就能有相同的内容了。在使用 file 模块设置快捷方式时,不需要再单独创建目标文件,Ansible 服务会帮我们完成。继续追加编写 newfile.yml 剧本。
完成后执行剧本很顺利,可直接在 ansible 服务器查看结果。
16.9 管理密码库文件
自 Ansible 1.5 版本发布后,vault 作为一项新功能进入到了运维人员的视野。它不仅能对密码、剧本等敏感信息进行加密,而且还可以加密变量名称和变量值,从而确保数据不会被他人轻易阅读。使用 ansible-vault 命令可以实现内容的新建(create)、加密(encrypt)、解密(decrypt)、修改密码(rekey)及查看(view)等功能。
下面通过示例来学习 vault 的具体用法。
第一步:创建出一个名为 locker.yml 的配置文件,其中保存了两个变量值:
第二步:使用 ansible-vault 命令对文件进行加密。由于需要每次输入密码比较麻烦,因此还应新建一个用于保存密码值的文本文件,以便让 ansible-vault 命令自动调用。为了保证数据的安全性,在新建密码文件后将该文件的权限设置为 600,确保仅管理员可读可写。
在 Ansible 服务的主配置文件 /etc/ansible/ansible.cfg 中,第 140 行的 vault_password_file 参数后指定密码值保存的文件路径,去除 # 号表示启用调用。
第三步:在设置好密码文件的路径后,Ansible 服务便会自动进行加载。我们也就不用在每次加密或解密时都重复输入密码了。例如在加密刚刚创建的 locker.yml 文件时,只需要使用 encrypt 参数即可,文件将使用 AES 256 加密方式进行加密。查看加密后的内容为密密麻麻一片。
如果不想使用原始密码了呢?也可以使用 rekey 参数手动对文件进行改密操作,同时应结合–ask-vault-pass 参数进行修改,否则 Ansible 服务会因接收不到用户输入的旧密码值而拒绝新的密码变更请求:
第四步:如果想查看和修改加密文件中的内容,该怎么操作呢?对于已经加密过的文件,需要使用 ansible-vault 命令的 edit 参数进行修改,随后用 view 参数即可查看到修改后的内容。ansible-vault 命令对加密文件的编辑操作默认使用的是 Vim 编辑器,在修改完毕后请记得用: wq 保存后退出。
服务器租用托管,机房租用托管,主机租用托管,https://www.e1idc.com