RHCA - DO374 | Day01:使用红帽Ansible自动化平台开发剧本

课程介绍+练习环境说明

1. 关于DO374课程

红帽AAP高级自动化开发 ------ AAP,Ansible Automation Platform,Ansible自动化平台。

利用红帽Ansible自动化平台中以容器为主的全新工具,运用推荐做法,提高您的 Ansible 技能并开发可扩展的自动化。

适合自动化内容开发人员,帮助他们利用红帽Ansible自动化平台中以容器为主的全新工具,高效地开发可以使用自动化控制器管理的自动化。学习利用可复用代码进行自动化开发的推荐实践、高级剧本技巧、共享执行环境,以及使用自动化内容浏览器实现可扩展自动化的准备工作。

本课程基于红帽Ansible自动化平台2.2(DO374-RHAAP2.2-en-1-20230131版本)。

本课程适用于负责创建自动化内容的用户,包括以下角色:

  • 开发人员

  • DevOps工程师

  • Linux系统管理员

  • 其他具有使用红帽Ansible自动化平台的基础知识,能在Linux环境中自动化、调配、配置和部署应用和服务的IT专业人士

前置课程:

  • 利用Ansible实现红帽企业Linux自动化(RH294)

  • 已成为红帽企业Linux 8或更高版本的红帽认证工程师,或具备同等Ansible经验

课程内容摘要:

  • 利用自动化内容浏览器的功能开发Ansible Playbook。

  • 运用高效实用地使用Ansible实现自动化的推荐做法。

  • 使用红帽Ansible自动化平台的高级功能来处理数据,包括过滤器插件

  • 以滚动更新的形式执行自动化运维。

  • 创建自动化执行环境,以捆绑和分发运行自动化代码所需的依赖项。

教材章节安排:

chapter01-使用红帽Ansible自动化平台开发剧本

chapter02-管理内容集和执行环境

chapter03-通过自动化控制器运行剧本

chapter04-调整Ansible配置

chapter05-管理主机清单

chapter06-管理任务执行

chapter07-使用过滤器和插件转换数据

chapter08-配置滚动更新

chapter09-自建内容集和执行环境

chapter10-综合复习

2. 关于练习环境

场景选择:

  • 使用VMware虚拟机 f0_do374,其中封装了foundation0主机环境

  • 需要DO374环境下载地址,请私信联系博主

说明:开机用户 kiosk,密码 redhat

  • 真机配置(推荐):i7/64G/SSD 500G,VMware Workstation 17 Pro

虚拟网络拓扑(如图所示):

共13台虚拟机:

  • 学员网络:172.25.250.0/24

  • 教室网络:172.25.252.0/24

  • 主用虚拟机:workstation

  • 资源机:classroom、bastion、utility、git、hub、controller

  • 受管机:servera、serverb、serverc、serverd、servere、serverf

所有虚拟机都预设有用户student,密码也是student

虚拟机角色说明(如表所示):

|-------------------------------|------------------|--------------------|
| 主机名称 | IP**地址** | 角色 |
| classroom.lab.example.com | 172.25.254.254 | 外部素材/软件仓库等 |
| bastion.lab.example.com | 172.25.250.254 | 堡垒/路由(连接教室网络与学生网络) |
| workstation.lab.example.com | 172.25.250.9 | 工作站(学习过程中的主用站点) |
| server[a-f].lab.example.com | 172.25.250.10-15 | 6台受管机(A-F) |
| git.lab.example.com | 172.25.250.5 | GitLab服务器 |
| hub.lab.example.com | 172.25.250.6 | 专用自动化hub服务器 |
| controlller.lab.example.com | 172.25.250.7 | 自动化控制器 |
| utility.lab.example.com | 172.25.250.8 | 资源服务器 |

虚拟机控制:

可以在练习环境使用 rht-vmctl 脚本,以及运行 virt-mangager 虚拟系统管理器

1)重设指定的servera虚拟机

javascript 复制代码
[kiosk@foundation0 ~]$ rht-vmctl reset servera
Are you sure you want to reset servera? (y/n) y
.. ..

2)重设所有虚拟机(耗时较长,请耐心等待)

javascript 复制代码
[kiosk@foundation0 ~]$ rht-vmctl reset all
Are you sure you want to reset bastion git utility workstation hub controller servera serverb serverc serverd servere serverf? (y/n) y
.. ..

练习环境的启动/评分/结束:

通过lab脚本控制xx练习或xx实验的环境准备及清理。

javascript 复制代码
[student@workstation ~]$ lab <action> exercise-name

其中action是启动(start)、评分(grade)、结束(finish)其中的一种,只有综合实验才支持grade评分的动作;exercise-name是课堂练习或综合实验的名称,当前版本教材中提供了31个课堂练习、8个综合实验。

javascript 复制代码
[student@workstation ~]$ lab start   //按2次tab键可查看练习、实验列表
builder-custom    data-lookups     inventory-variables  task-escalation
builder-use      data-loops      inventory-yaml    task-execution
builder-validate   data-netfilters    manage-finding    task-review
config-ansible    data-review      manage-reusing    task-speed
config-navigator   develop-git      manage-review     task-tagging
config-review     develop-navigator   manage-selecting   update-delegation
controller-playbooks develop-practices   playbook-basic    update-management
controller-review   develop-review    playbook-multi    update-parallelism
create-review     exercise-source    review-cr1      update-review
create-writing    inventory-dynamic   review-cr2
data-filters     inventory-review   review-cr3

3. 课堂练习:构建do374练习环境

  • 1)释放f0_do374虚拟机,启动后以kiosk用户登入桌面环境(密码为redhat)

  • 2)从foundation0上执行 rht-vmctl reset all 重设所有虚拟机(如果真机性能较弱,可改用virt-manager虚拟系统管理器,按需启动指定虚拟机)

首次开机后,建议准备好classroom、basition、workstation、git、controller、utility


一、 红帽AAP2.2平台(Ansible Automation Platform)

1. 红帽AAP2平台的定位

红帽Ansible自动化平台(AAP2)是Red Hat在自动化方面的新一代产品,它提供了新的工具、服务和功能,实现了规模化运维的全新层次的定制和控制,为企业提供了更好的自动化体验。

红帽AAP2可以帮助您在多个部门实现目标。

  • 实现自动化以提高速度并加快业务成果

  • 实现跨团队协作和协调的自动化

  • 实现自动化以实现大规模增长和创新

2. 红帽AAP2平台的组件

AAP2平台包括多个不同的组件,这些组件共同提供了一套完整集成的自动化工具和资源。

1)Ansible 核心

Ansible Core,通过 ansible-core 软件包 提供了用来运行Ansible剧本的基本功能。它定义了用来编写YAML格式剧本的自动化语言,提供了自动化代码所需的关键函数,如循环、条件和其他Ansible命令。它还提供了驱动自动化的框架和基本命令行工具。

2)Ansible内容集(Collection)

Ansible Content Collections,内容集是Ansible功能模块、角色和插件的一种新的组合方式。

从历史上看,Ansible提供了许多模块作为核心包的一部分。随着自动化技术的不断发展,模块数量呈指数级增长。这导致了在模块支持方面面临着一些挑战,比如当你使用Ansible自带的某个模块但是需要更旧或者更新的版本的时候。

上游开发人员决定将大多数模块重组为单独的Ansible内容集合,由同一组开发人员支持的相关模块、角色和插件组成。ansible-core核心包只通过名为 ansible.builtin 的内容集提供一小部分模块,而其他模块就需要其他的内容集来提供。

通过内容集,用户可以根据需要来灵活选择不同版本的模块、角色和插件集合。另一方面,开发人员也能够单独更新内容集中的模块,而不是必须与ansible一起更新。

红帽的Ansible认证内容集合,由Red Hat及其合作伙伴通过AAP平台提供官方支持。

3)自动化内容导航器(Navigator)

Automation Content Navigator,是AAP2平台提供的用来开发和测试Ansible剧本的一个新的顶级工具,对应命令为 ansible-navigator 。这个工具替换并扩展了几个早期命令行实用程序的功能,包括ansible-playbook、ansible-inventory和ansible-config。

另外,ansible-navigator导航器通过在容器中运行剧本,将发起自动化任务的控制节点与执行任务的自动化执行环境分离开。这种方式使自动化代码从部署到生产的转换变得更加容易。

4)自动化执行环境(EE)

Automation Execution Environments,自动化执行环境实际上是一个容器镜像,其中包含Ansible核心、Ansible内容集合,以及运行剧本所需要的任何Python库、可执行文件或其他依赖项。

通过ansible-navigator导航器来运行剧本时,可以选择使用某一个自动化执行环境。部署自动化任务时,可以向自动化控制器(以前称为红帽Ansible Tower)提供剧本和自动化执行环境,自动化控制器拥有正确运行剧本所需的一切。

AAP2.2的默认环境提供了2.13版本的Ansible核心,还有许多红帽认证的Ansible内容集合,以提供与Ansible 2.9非常相似的用户体验;当然,也可以直接选用Ansible早期版本的自动化执行环境;我们还可以使用AAP2提供的ansible-builder工具来创建自定义的执行环境。

5)自动化控制器(Controller)

Automation Controller,以前称为Red Hat Ansible Tower,是Ansible自动化平台的组件,它提供了运行企业自动化代码的中心控制点。它提供了一个web UI和一个REST API,可以用来配置、运行和评估自动化作业。

在Ansible Tower中,系统既是控制节点,又是自动化执行环境。如果自动化任务在Ansible Tower上的自动化执行环境中需要的一组Python依赖项与默认提供的系统不同,就必须手动设置一个单独的Python虚拟环境(或"venv")。这就使一些自动化任务很难管理、很难分发,可能不得不对运行Ansible Tower的系统进行升级,扩展性很差。

新的自动化控制器设计通过将控制节点(提供web UI和API)与自动化执行环境(现在在容器中运行)分离来解决这一挑战。我们可以通过容器注册表来下载、使用基于容器的自动化执行环境,要运行新的Ansible剧本时只需在web UI中进行简单的配置更改就可以(如图-2所示)。

6)自动化中心(Hub)

Automation Hub,自动化中心,或称自动化集线器,主要用来管理和分发自动化内容。

从网站服务器console.redhat.com上可以访问红帽认证的Ansible内容集,下载需要的内容集并与ansible-galaxy(用于ansible-navigator)和自动化控制器一起使用。

当然,也可以设置一个私有的自动化中心(Private automation hub),在私有自动化中心可以创建自己的内容集合,也可以提供容器注册表以便分发自动化执行环境。私有自动化中心为Ansible工程师提供了一个更方便获取自动化内容的集中的节点(如图-3所示)。

7)托管服务

除了console.redhat.com上的托管自动化中心外,红帽还提供了另外两个托管服务(不常用)。

  • Red Hat Insights for Red Hat Ansible Automation Platform,可帮助您了解正在运行的自动化代码以及它是否成功。您还可以使用它来评估自动化对您的组织的积极影响。

  • Automation Analytics,有助于更好地了解自动化基础设施的性能,您可以使用它来分析您如何使用自动化,以及您最频繁使用的模块、行动手册和工作流。

3. 红帽AAP2平台的架构

红帽AAP2平台部署的组件以及一些使用者的角色如图-4所示。

基于AAP2平台开发剧本

Controller自动化控制器、Navigator自动化内容导航器都支持自动化执行环境,这就简化了从开发剧本到在生产中使用剧本的转换。因为不再需要使用虚拟环境或在自动化控制器上额外安装模块及其依赖关系,用户可以自定义执行引擎,以包含运行剧本所需要的一切内容。

假设自动化内容导航器和自动化控制器可以访问相同的自动化执行环境,那么一个剧本从开发环境到生产环境的过渡几乎是无缝的。

二、 通过导航器运行剧本

1)ansible-navigator 基本操作

ansible-navigator,自动化内容导航器是红帽AAP2中的一个新工具,可以更容易调试及修改可复用的剧本。ansible-navigator 将以前由ansible-playbook、ansible-inventory、ansible-config和ansible-doc提供的功能组合到同一个顶级接口中。

ansible-navigator导航器提供了基于文本的交互用户界面(TUI),也可以使用--mode stdout(或 -m stdout)选项运行来实现 免交互 的原始格式的输出。

例如,要使用ansible-playbook运行playbook,可以输入以下命令:

javascript 复制代码
[user@host ~]$ ansible-playbook playbook.yml -i inventory

使用ansible-navigator命令可以做同样的事情,并以相同的格式获得剧本输出,如下所示:

javascript 复制代码
[user@host ~]$ ansible-navigator run playbook.yml -i inventory -m stdout

当省略-m stdout选项时,ansible-navigator将采用交互模式,方便用户通过TUI界面来查看剧本执行的实时结果(如图-5所示)。

在上图中,可以看到ansible-navigator运行了一个包含三个play的剧本。

  • 第一个名为"Ensuring HAProxy is deployed"执行了9项任务,其中6项任务的状态为changed。

  • 第二个名为"Ensuring Apache HTTP Server is deployed"的play运行了14个任务,其中8个任务的状态为changed。

  • 第三个名为"Ensuring web content is deployed"的play执行了4项任务,其中2项任务的状态为changed。

可以通过按0 或在ansible-navigator中键入**:0**来获取有关第一个play运行的任务的更多信息(如图-6所示)。

在前面的示例中,如果按2或键入 :2,则会进一步显示关于"Ensure HAProxy is started and enable"这个任务的详细信息,可以使用箭头键滚动查看结果(如图-7所示)。

要从ansible-navigator导航器的最顶层退出,或是在操作中返回到前几页,请按Esc 键

2)利用自动化执行环境提高便携性

红帽AAP2的一个新功能是支持自动化执行环境。自动化执行环境是一个容器镜像,其中包括Ansible内容集、软件依赖项,以及用来运行剧本的最小Ansible引擎。Navigator导航器和Controller控制器(以前称为ansible Tower)都使用自动化执行环境来简化自动化代码的开发、测试和部署。

红帽提供了多个采用不同Ansbile部署的自动化执行环境,用户也可以创建自己的自动化执行环境。通过使用自动化执行环境,可以避免在控制器上创建多个Python虚拟环境(旧版本的Ansible Tower就需要多个Python虚拟环境来支持Ansible、模块、Python库和其他软件依赖项的不同组合)。

红帽AAP2使用多个自动化执行环境,而不是多个Python虚拟环境。在AAP2平台中,我们可以在自定义执行环境中创建自定义环境,使用ansible-navigator对其进行测试,并将其作为容器镜像分发给自动化控制器使用。

使用ansible-navigator运行剧本时,如果没有指定用哪一个自动化执行环境,而且系统上也没有默认的自动化执行环境,ansible-navigator会自动尝试从 registry.redhat.io 站点中提取默认的自动化执行环境(比如,registry.redhat.io/ansible-automation-platform-22/ee-supported-rhel8:latest)。


重要提示:

要让ansible-navigator能够访问registry.redhat.io上的容器注册表,需要进行身份验证(此身份拥有对AAP平台的有效订阅,并已成功登录);先执行一次 podman login registry.redhat.io 命令,然后再运行ansible-navigator命令。如果此容器镜像已经下载,那么ansible-navigator可以直接使用它,而无需再次拉取。

本课程中的容器镜像基本都能从hub.lab.example.com上的容器注册表下载,必要时应先执行以下命令登录验证(用户名:admin,密码:redhat):

javascript 复制代码
podman login hub.lab.example.com

3)选择替代的自动化执行环境

运行ansbile-navigator时,可以结合--execution-environment-image(--eei)选项来选择一个特定的容器镜像(例如ee-supported-rhel8)用作自动化执行环境。指定容器镜像时,可以同时指定此容器的 tags标签,例如ee-supported-rhel8:latest表示此镜像的最新版本。

还可以使用--pull-policy(--pp)选项来控制ansible-navigator导航器如何提取容器镜像。当配置了--pull-policy missing时,仅在本地系统上不存在此容器镜像的情况下才会去提取此容器镜像。

2. 安装Navigator自动化内容导航器

安装ansible-navigator导航器

只需要在控制节点上安装ansible导航器,受管机上不需要安装。

需要有效的Red Hat Ansible Automation Platform订阅才能在控制节点上安装自动化内容导航器。如果您尚未使用该产品,可通过www.redhat.com获得试用授权。

注意:本DO374练习环境中,并不需要运行subscription-manager来进行订阅。

如果已经激活了"Simple Content Access"订阅,安装过程如下:

1)使用Red Hat Subscription Manager注册您的系统

javascript 复制代码
[root@host ~]# subscription-manager register

2)启用红帽AAP2仓库

javascript 复制代码
[root@host ~]# subscription-manager repos \
--enable ansible-automation-platform-2.2-for-rhel-8-x86_64-rpms

3)安装ansible-navigator包

javascript 复制代码
[root@host ~]# yum install ansible-navigator

3. 配置访问受管机的认证

自动化内容导航器需要能够登录到受管主机,并在这些主机上获得超级用户权限。实现这一点的最简单方法是对一个帐户使用基于SSH密钥的身份验证,该帐户允许在没有密码的情况下通过sudo提权为root。

1)准备基于SSH密钥的身份验证

受管主机配置的初始部分与用于ansible-playbook命令的过程相同:

  • 在控制机Ansible配置文件的 [defaults] 部分,将 remote_user 设为用来登录受管机的用户名

  • 使用 ssh-keygen 命令为用来运行 ansible-navigator 的用户生成ssh密钥对

  • 为每个受管机 remote_user 账号的 ~/.ssh/authorized_keys 文件中安装该密钥对的公钥 ------ 可以使用ssh-copy-id user@host 命令来远程部署公钥,其中user是远程用户名,host是受管机的地址

  • 在每个受管机上,将sudo配置为允许指定的远程用户以无密码的方式运行所有命令

2)为自动化执行环境提供私钥

在向受管机验证登录时,ansible-navigator 和 ansible-playbook 的主要区别在于:ansible-navigator在容器中运行剧本,而容器中无法正常访问 ~/.ssh目录。

因此,需要在控制节点上运行 ssh-agent 来代理存储ssh私钥,这样的话运行ansible-navigator时,代理会自动将私钥提供给执行环境。

  • 如果是从图形桌面环境登录到控制节点,则会自动启动ssh代理,并自动运行ssh-add命令将私钥添加到代理中。如果你的任何SSH私钥都受密码保护,则登录后会提示你输入密码。然后,身份验证将自动适用于该图形登录会话中的所有终端。

  • 如果是通过命令行或使用ssh远程登录到控制节点,则必须通过运行eval $(ssh-agent) 命令来手动启动ssh-agent,然后再运行ssh-add,并在必要时提供私钥的密码短语。然后,就可以再同一个环境中运行ansible-navigator并完成身份验证了。

4. 使用ansible-navigator导航器

使用ansible-navigator命令来运行自动化内容导航器。

如果在不带参数的情况下运行ansible-navigator命令,或者运行ansible-navigator welcome,它将以交互模式启动。这将显示一个帮助页面,描述该工具提供的子命令。

许多早期的Ansible命令可以替换为自动化内容导航器子命令(如表所示)

|-------------------|-----------------------------|
| 早期的Ansible命令 | 导航器及子命令 |
| ansible-config | ansible-navigator config |
| ansible-doc | ansible-navigator doc |
| ansible-inventory | ansible-navigator inventory |
| ansible-playbook | ansible-navigator run |

自动化内容导航器大多数的子命令可以从命令行或交互式会话中运行,但有个别命令不支持-m stdout选项。

下面简要介绍了可用的子命令(如表所示)

|-------------|-------------------------|
| 子命令 | 描述 |
| collections | 获取已安装的内容集合信息 |
| config | 检查当前的Ansible配置 |
| doc | 检查Ansible插件文档 |
| help | 显示ansible-navigator帮助信息 |
| images | 检查执行环境(容器镜像) |
| inventory | 浏览主机清单 |
| log | 查看日志文件 |
| open | 在文本编辑器中打开当前页面 |
| replay | 回看剧本工件(执行信息) |
| run | 运行剧本 |

执行 ansible-navigator welcome 命令显示的帮助页面与上表内容类似。

在交互式会话中运行子命令时,需要先键入 : 来启动此命令,例如:

: config


1)运行剧本

使用 ansible-navigator run 命令,或从ansible-navigator交互界面中使用**:run**子命令。ansible-navigator run命令支持与ansible-playbook命令相同的大多数选项。

当使用默认的交互模式(而不是stdout模式)时,可以交互地检查剧本输出,如前所述。例如,可能想显示执行失败的play或失败的play中的某个task的详细信息。

2)回看之前的剧本执行情况

导航器提供了一个新的回看功能,可以显示以前运行的剧本的输出。如果启用了剧本工件(默认值),那么ansible-navigator run命令将生成一个工件文件,该文件使用像 site-artifact-2022-10-25T20:09:57.939910+00:00.json 这样的名称。

  • 文件名的第一部分指的是剧本名称,因此site表示运行的是site.yml剧本
  • 文件名的第二部分是日期和时间,时区从UTC偏移(+00:0表示时间以UTC记录)

通过在命令行中使用 ansible-navigator replay 命令或在交互模式中使用**:replay**子命令,可以查看以前运行的剧本。回看文件的一个优点是,当剧本运行失败时,可以与另一个开发人员或支持团队共享回看文件。他们可以继续进行故障排除,而无需访问项目目录中的所有文件,如剧本、角色、清单文件、变量文件等。如果用不到这些回看文件,那么可以无视甚至删除它们。

3)阅读文档

导航器提供了对插件文档的访问,如模块、查找和回调,非常类似于ansible-doc命令。

有一个主要区别是,ansible-navigator不支持使用--list(-l)选项 来列出特定类型的所有插件。相反,查看文档时必须明确指定插件的名称。

例如,可以从命令行运行 ansible-navigator doc ansible.posix.firewalld ,以显示ansible_posix.firevalld模块的文档。也可以通过在交互式自动化内容导航器会话中运行**:doc** ansible.posix.firewalld子命令来执行同样的操作。

4)获取帮助

自动化内容导航器提供了多种获取帮助的方法。

如果在交互模式下运行ansible-navigator,则可以键入**:help** 以打开帮助页面。

或者,将 --help(-h)选项添加到ansible-navigator命令中。使用此选项可显示命令语法并描述命令选项。

5. 课堂练习:通过导航器运行剧本

开始练习(部署环境):

以用户student登入workstation虚拟机,使用lab命令来构建案例环境。

javascript 复制代码
[student@workstation ~]$ lab start develop-navigator

步骤说明:

1)安装ansible-navigator软件包

javascript 复制代码
[student@workstation ~]$ sudo yum install ansible-navigator
[sudo] password for student: student
...output omitted...

2)观察练习用的剧本文件

进入 /home/student/develop-navigator/ 目录。

javascript 复制代码
[student@workstation ~]$ cd ~/develop-navigator/

使用tree命令查看目录下的文件。

javascript 复制代码
[student@workstation develop-navigator]$ tree
.
├── ansible.cfg
├── intranet.yml
└── inventory
0 directories, 3 files

查看 intranet.yml 剧本。

javascript 复制代码
[student@workstation develop-navigator]$ cat intranet.yml
---
- name: Enable intranet services
  hosts: servera.lab.example.com
  become: true
  tasks:
    - name: latest version of httpd and firewalld installed
      ansible.builtin.yum:
        name:
          - httpd
          - firewalld
        state: latest

    - name: test html page is installed
      ansible.builtin.copy:
        content: "Welcome to the example.com intranet!\n"
        dest: /var/www/html/index.html

    - name: firewalld enabled and running
      ansible.builtin.service:
        name: firewalld
        enabled: true
        state: started

    - name: firewalld permits http service
      ansible.posix.firewalld:
        service: http
        permanent: true
        state: enabled
        immediate: true

    - name: httpd enabled and running
      ansible.builtin.service:
        name: httpd
        enabled: true
        state: started

- name: Test intranet web server
  hosts: localhost
  become: false
  tasks:
    - name: connect to intranet web server
      ansible.builtin.uri:
        url: http://servera.lab.example.com
        return_content: true
        status_code: 200

3)通过ansible-navigator运行intranet.yml剧本文件

导航器需要先访问自动化中心或其他容器注册表,以便将其自动化执行环境的容器镜像下载到workstation上。

这里可以使用podman login命令登录到hub.lab.example.com这个私有自动化中心

用户名是student,密码是redhat123。

javascript 复制代码
[student@workstation develop-navigator]$ podman login hub.lab.example.com
Username: student
Password: redhat123
login Succeeded!

然后执行 ansible-navigator run intranet.yml -m stdout --eei ee- supported-rhel8 命令来运行intranet.yml剧本,通过导航器stdout模式输出的结果与通过ansible-playbook 命令运行剧本时的输出结果是一样的。

javascript 复制代码
[student@workstation develop-navigator]$ ansible-navigator run intranet.yml -m stdout --eei ee-supported-rhel8

4)在ansible-navigator中使用ee-supported-rhel8执行环境来交互式运行intranet.yml剧本

运行ansible-navigator命令来启动导航器

javascript 复制代码
[student@workstation develop-navigator]$ ansible-navigator --eei ee-supported-rhel8


0│Welcome
1│---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2│
3│Some things you can try from here:
4│- :collections                                    Explore available collections
5│- :config                                         Explore the current ansible configuration
6│- :doc <plugin>                                   Review documentation for a module or plugin
7│- :help                                           Show the main help page
8│- :images                                         Explore execution environment images
9│- :inventory -i <inventory>                       Explore an inventory
10│- :log                                            Review the application log
11│- :lint <file or directory>                       Lint Ansible/YAML files (experimental)
12│- :open                                           Open current page in the editor
13│- :replay                                         Explore a previous run using a playbook artifact
14│- :run <playbook> -i <inventory>                  Run a playbook in interactive mode
15│- :settings                                       Review the current ansible-navigator settings
16│- :quit                                           Quit the application
17│
18│happy automating,
19│
20│-winston

在末行键入**:run intranet.yml**来交互运行intranet.yml剧本。

javascript 复制代码
  Play name                                               Ok     Changed           Unreachable                Failed          Skipped           Ignored           In progress               Task count                          Progress
0│Enable intranet services                                 6           0                     0                     0                0                 0                     0                        6                          Complete
1│Test intranet web server                                 2           0                     0                     0                0                 0                     0                        2                          Complete

键入 0 来显示Enable intranet services这个play的详细信息。

javascript 复制代码
  Result       Host                                       Number       Changed       Task                                                                                   Task action                                 Duration
0│Ok           servera.lab.example.com                         0       False         Gathering Facts                                                                        gather_facts                                      2s
1│Ok           servera.lab.example.com                         1       False         latest version of httpd and firewalld installed                                        ansible.builtin.yum                               7s
2│Ok           servera.lab.example.com                         2       False         test html page is installed                                                            ansible.builtin.copy                              2s
3│Ok           servera.lab.example.com                         3       False         firewalld enabled and running                                                          ansible.builtin.service                           1s
4│Ok           servera.lab.example.com                         4       False         firewalld permits http service                                                         ansible.posix.firewalld                           1s
5│Ok           servera.lab.example.com                         5       False         httpd enabled and running                                                              ansible.builtin.service                           1s

键入 ESC 返回剧本摘要页,然后键入1来显示 Test intranet web server这个 play的详细信息。

javascript 复制代码
  Result            Host                     Number           Changed             Task                                                                          Task action                                       Duration
0│Ok                localhost                     0           False               Gathering Facts                                                               gather_facts                                            1s
1│Ok                localhost                     1           False               connect to intranet web server                                                ansible.builtin.uri                                     1s

结束练习(清理环境):

在workstation虚拟机上,切换到student用户主目录,使用lab命令来清理案例环境,确保先前练习的资源不会影响后续的练习。

javascript 复制代码
[student@workstation ~]$ lab finish develop-navigator

三、 使用Git管理Ansible项目代码

1. 关于Git

DevOps运维开发中的一个关键概念是基础设施即代码(IaC),我们可以通过运行自动化代码来定义和构建系统,而不是手动管理基础架构。红帽AAP也是用来实现IaC基础设施即代码的重要工具。

Ansible项目主要是用来定义基础设施的代码,因此可以使用版本控制系统(VCS)(如Git)来跟踪和控制代码的更改。

版本控制能够为基础设施代码的不同阶段(如开发、QA和生产)实现生命周期控制,可以将更改提交到一个分支,并在非关键的开发和QA环境中测试这些更改。当这个分支的代码足够完善以后,可以将其合并到主版本代码中,并应用到生产环境。

Git是一个分布式版本控制系统(DVCS),能够实现协作开发、管理项目中的代码变更。

使用Git有许多好处:

  • 可以查看和恢复早期版本的文件。

  • 可以比较同一文件的两个版本以识别更改。

  • 可以记录谁进行了哪些更改以及何时进行这些更改的日志。

  • 多个用户可以协作修改文件,解决冲突的变更,以及合并变更。

使用 Git,一般从远程存储库中 clone(克隆)现有的共享项目开始。clone克隆项目的操作会创建原始远程存储库的完整副本作为本地存储库。这个本地副本具有Git中文件的全部历史记录,而不仅仅是项目文件的最新快照。

可以在 working tree (工作树)中对代码文件进行编辑/修改,工作树是对项目的单个快照的 checkout (检出)。修改后的文件会放在 staging area (暂存区),准备将变更的结果 commit提交到本地存储库。

此时,还没有对共享的远程存储库做任何更改。

当准备好共享已完成的工作时,可以执行 push推送操作将变更发送到远程存储库。

同样的,如果想使用远程存储库的最新版本来更新本地存储库,可以执行 pull拉取操作来从远程存储库中提取这些更改到本地存储库中。

Git工作树中文件的三种可能状态(如表所示)

|--------------|----------------------------------------------|
| 状态 | 描述 |
| Modified,已修改 | 工作树中的文件副本已被修改,内容与远程存储库不一样。 |
| Staged,暂存 | 已经将修改后的文件添加到已更改文件的列表中,以便作为一个集合提交,但暂存文件还没有提交。 |
| Committed,提交 | 已将修改后的文件提交到本地存储库。 |

如果将文件 commit 提交到了本地存储库,这些文件就可以被 push 推送到远程存储库,以及由远程存储库pull拉取回来(如图-8所示)。

2. 初始化Git配置

Git用户参与的代码项目通常是由多人协作开发的,Git在每次提交时都会记录用户的姓名和电子邮件地址。这些参数可以在项目级别定义,也可以设置为用户的全局默认值。

使用 git config 命令,结合 --global 选项一起,可以设置所参与的所有git项目的默认设置,最终保存到 ~/.gitconfig 文件中。

javascript 复制代码
[user@host ~]$ git config --global user.name 'Peter Shadowman'
[user@host ~]$ git config --global user.email peter@host.example.com

如果使用Bash Shell,也可以将终端提示配置为能指示工作树的当前状态。最简单的方法是使用git包附带的git-prompt.sh脚本,比如在~/.bashrc文件中添加以下行:

javascript 复制代码
source /usr/share/git-core/contrib/completion/git-prompt.sh export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWUNTRACKEDFILES=true
export PS1='[\u@\h \W$(declare -F  git_ps1 &>/dev/null &&  git_ps1 " (%s)")]\$ '

如果当前目录位于Git工作树中,则工作树的当前Git分支的名称将显示在括号中。如果在工作树中有未跟踪、修改或暂存的文件,则提示符可能会出现以下指示:

  • (branch *) 表示已经修改了被跟踪的文件。

  • (branch +) 表示已经修改了被跟踪的文件,并且使用git add将其暂存。

  • (branch %) 表示在工作树中存在未跟踪的文件。

  • 上述符号的组合 比如 (branch *+)。

3. 开始Git工作流

在开始Git工作流时,可以先使用 git clone 命令克隆现有的上游存储库。提供的路径名或URL决定将哪个存储库克隆到当前目录中。clone的过程将创建一个可供修订的干净状态的文件工作树,干净状态意味着工作树不包含任何修改的、暂存的或新的文件。

例如,以下命令将克隆git.lab.example.com上的project.git存储库(使用SSH协议进行连接并以git用户身份进行身份验证):

javascript 复制代码
[user@host ~]$ git clone git@git.lab.example.com:project.git

另一种开始Git工作流的方法是,通过 git init 命令来创建一个新的、专有的本地Git项目,采用git init的方法开始Git工作时,并不会在远程库中建立项目。

Git服务器通常包含裸存储库(使用 git init --bare 命令创建),因为服务器上不需要工作树。当创建存储库的本地副本时,通常需要一个工作树来进行本地更改,因此可以创建一个非裸克隆。服务器还必须设置为允许用户使用HTTPS或SSH协议克隆、从存储库提取和推送到存储库。

基于Git克隆的副本工作时,可以在工作树中创建新文件和修改现有文件,这会导致工作树的状态变更为dirty脏状态。使用 git status 命令可以查看工作树中有哪些文件已修改但未暂存、未跟踪(新)或为下一次提交暂存等详细信息。

1)Git常用操作

使用 git add命令用来暂存文件,以准备提交这些文件。只有暂存到stage暂存区域的文件才会在下次提交时保存到存储库。

使用 git rm命令从工作目录中删除文件,并在下一次提交时将其从存储库中分阶段删除。

使用 git reset 命令从stage暂存区域中删除为下一次提交添加的文件,此命令对工作树中文件的内容没有影响。

使用git commit命令将暂存的文件提交到本地git存储库。commit提交时必须提供一条日志消息,用来解释保存当前暂存文件集的原因。日志消息不一定要很长,但它们应该是有意义的。如果不提供消息将无法提交。

注意,git commit命令本身不会自动提交工作树中已更改的文件;加上 -a 选项(即git commit -a),可以一步到位并提交所有修改过的文件。添加新文件时,必须先运行 git add 命令来暂存新文件,否则git commit -a也不会提交这些未暂存的文件。

使用 git push 命令将对本地存储库所做的更改推送到远程存储库。与Git协同工作的一种常见方式是让所有开发人员将他们的工作推送到同一个共享的远程存储库。在Git推送工作之前,必须先定义采用的默认推送方法。以下命令将默认的推送方法设置为simple,比较适合初学者。

javascript 复制代码
[user@host ~]$ git config --global push.default simple

使用 git pull命令可以完成下列任务:

  • 从远程存储库获取最新的commit提交结果。

  • 将这些结果下载到本地目录。

  • 将更改合并到工作树中的文件中。

经常运行git pull命令,可以及时获取其他人对远程存储库中的项目所做的更改。

2)检查Git日志

每一次commit提交都会有独特的哈希值标记,以便能够及时跟踪代码变更的历史记录,这是版本控制系统的一个重要目的。

  • 使用 git log命令可以查看commit日志消息以及每个提交的相关ID哈希值。

  • 使用 git show commit-hash命令可查看特定哈希值的提交更改了哪些内容。不需要提供完整的哈希值串,只需要提供足以区分这一次提交的一部分哈希值串即可。哈希值还可以用来恢复到以前的commit提交,或者以其他方式探索版本控制系统的历史。

3)Git指令快速参考

|------------------------|--------------------------|
| 命令 | 描述 |
| git clone URL | 从URL指定的远程仓库克隆一个项目到当前目录 |
| git status | 显示工作树中的文件的状态 |
| git add file | 暂存新文件、变化过的文件,以便下一次提交 |
| git rm file | 标记在下一次提交时要删除的文件 |
| git reset | 取消暂存标记(重置状态) |
| git commit | 提交暂存的文件到本地仓库(添加说明信息) |
| git push | 将本地仓库的变化推送到远程仓库 |
| git pull | 获取远程仓库的更新内容到本地仓库,并合并到工作树 |
| git revert commit-hash | 创建一个新提交,撤消指定哈希值引用的提交中的更改 |
| git init | 创建一个新项目 |
| git log | 显示提交日志消息 |
| show commit-hash | 查看指定哈希值的提交的具体变化 |

注意:以上是对Git的高度简化的介绍,避免了讨论分支和合并的重要话题。主要适用于从远程仓库库克隆了本地存储库、只使用一个本地分支机构,并已提供了对远程存储库的写访问权限。

4. Git分支及引用

Branch分支,允许开发者在不更改主分支的情况下对项目进行更改、进行新的开发。然后,当对分支的更改感到满意时,可以将分支中的更改合并到开发的主分支,并对它们进行集成。

分支本质上是指向提交树中特定提交的指针,每个提交都包含它所做的更改,以及关于如何引用它以及它与提交树中其他提交的关系的信息。

分支提交中的信息包括:

  • 一个40个字符的十六进制字符串形式的唯一ID,此ID是提交内容的SHA-1哈希。

  • 它更改的存储库文件的列表,以及每个文件的确切更改。

  • 在应用有问题的提交之前,定义存储库状态的父提交的ID。

  • 提交数据中关于提交的作者和创建者(或提交者)的信息。

  • 参考文献列表。引用就像一个指向提交的命名指针。最常见的引用是标记和分支。

针对分支使用git commit命令会生成一个新的commit,可以将Git存储库理解为提交图,并将分支认为是针对提交的引用(如图-11)。

上图显示了一个包含11个提交的示例Git存储库,最近的提交在右侧,箭头指向较早的提交。这个存储库中有三个分支(main、feature/1和feature/2)和一个标记(tag/1.0)。

HEAD引用是本地工作树中的当前提交。如果对工作树进行了更改,请使用git add命令暂存,然后使用git commit命令提交。之后创建一个新的提交,会将最近的提交作为其父提交,HEAD会移动到新的提交。

1)创建分支

Git中的不同分支使不同的工作流能够在同一个Git存储库上并行发展。每个工作流的提交仅附加到具体的某一个分支。使用 git branch 从当前HEAD提交处创建一个新分支,这个命令会创建一个到新分支的引用,但不会把HEAD设置当前这个分支。使用 git checkout 命令可以将HEAD移动到到适当的分支。

在上图中,主分支的最新提交(HEAD也是在这个时间)是commit 5749661。假设你运行了git branch feature/1命令,创建名为feature/1的分支;然后,再运行git checkout feature/1命令表示后续提交都针对这个分支。

最后,你将60c6c2c和8f7c801这两个提交commit到feature/1分支。运行这些命令后,HEAD会位于8f7c801,新的提交会被添加到feature/1 branch。

接下来,当你想将提交添加到main主分支时,可以在完成分支feature/1的提交之后,执行git checkout main命令,实际上做了96e9ce7和44bd644这两次提交。HEAD指向44bd644,提交会被添加到主分支。

2)合并分支

针对分支的开发工作完成后,可以将该分支与原始分支合并。

在上图中,确定了应该将feature/2合并到main主分支。也就是说,有人希望main的最新提交是两个分支的所有提交的结果。此结果是通过首先运行 git checkout main 命令以确保HEAD位于main主分支上的最近一次提交,e8ce346。然后,再运行 git merge feature/2 命令,创建了一个新的提交,5749661, 其中包括来自feature/2分支和main分支的所有提交,它将HEAD移动到最近的提交。

有时,多个分支上的更改无法自动合并,因为每个分支都会对相同文件的相同部分进行更改。这种情况被称为合并冲突,您需要手动编辑受影响的文件来解决它。

合并策略、冲突解决和分支机构保护等为超纲内容,这里不再讨论。

3)从之前的commit提交创建分支

使用 git checkout 命令可以将HEAD指向某个特定的commit。例如,运行git checkout 790dd94命令检查ID为790dd94的提交。之后,就可以运行git brach和git checkout命令来创建一个新的分支。例如,可能你选用一个特定的commit来忽略对这个分支的最近的更改。你也可以在运行git checkout命令的时候添加-b选项来创建一个分支并切换到这个分支。

javascript 复制代码
[user@host ~]$ git checkout -b feature/3
Switched to a new branch 'feature/3'

4)向远程仓库推送分支

创建的任何新分支最初都只存在于本地存储库中。如果要与远程存储库的用户共享这个分支,则必须将它们推送到存储库。

最常见的方法是使用 git push命令 和--set upstream(或-u)选项在远程存储库上创建分支。然后,当前的本地分支就会跟踪这个分支。

例如,要将新的feature/3分支推送到远程存储库,请运行以下命令:

javascript 复制代码
[user@host ~]$ git checkout feature/3
Switched to branch 'feature/3'

[user@host ~]$ git push --set-upstream origin feature/3

远程的源存储库指的是你最初克隆的Git存储库。这条命令表示要将当前分支推送到原始存储库,从而创建feature/3。当Git审核人员批准推送请求之后,Git会在远程存储库中创建feature/3分支。

在这个分支上运行git pull命令会将远程存储库中的任何提交下载并合并到本地副本中。

5. 使用Git结构化Ansible项目

每个Ansible项目都应该有自己的Git存储仓库,这个仓库的目录和文件结构可以参考https://docs.ansible.com/ansible/6/user_guide/sample_setup.html#sample-directory-layout.

例如,目录结构可能像下面这样:

1)角色和Ansible内容集

可以在Ansible项目的Git存储库中包含角色和Ansible内容集合。

在这种情况下,每个集合通常存储在collections/子目录中,每个角色存储在roles子目录中。其中一个或两个目录中可能还有一个requirements.yml文件,用于指定此项目使用的集合或角色,以便ansible-galaxy命令可以根据需要下载这些文件。

如果你的角色和集合是作为剧本的一部分来进行管理,那最好把它们与剧本放在一起。然而,大多数角色和集合都是由多个项目共享的,如果每个项目都有自己的每个角色或集合的副本,那么它们可能会相互偏离,从而丧失一些优势。

角色或集合应该有自己的Git存储库。有些人试图通过使用Git的一个称为子模块的高级功能将这些存储库包括在他们的项目存储库中。

由于子模块可能难以成功管理,因此不建议采用这种方法。

更好的做法是在roles/和collections/目录中设置requirements.yml文件,并在运行项目的剧本之前,使用ansible-galaxy命令从自动化中心、Ansible Galaxy或其Git存储库中获取最新版本的角色。

自动化控制器会根据roles/requidents.yml和collections/requidents.yml文件,更新项目使用的角色和内容集合。

2)配置Git忽略文件

Ansible项目中的有些文件或目录并不需要通过Git来跟踪和管理,我们可以将Git配置为忽略这些文件或目录。

例如,ansible-navigator命令会生成或更新ansible-navigator.log文件,每次运行剧本时都创建一个工件文件,并创建一个.ssh目录,这些临时文件都不需要提交到Git存储库中。

同样,如果使用requirements.yml文件与ansible-galaxy命令一起使用来部署项目的角色和集合目录,那么也可以让Git忽略这些内容。

要指示Git忽略哪些文件或目录,可以在Ansible项目的顶层目录添加 .gitignore 文件。记得将其记录在Ansible项目的README自述文件中。

.gitignore文件中的每一行都表示要匹配的模式,该模式决定Git是否忽略存储库中的文件。通常,与文件名匹配的行表示Git忽略的文件。以感叹号(!)开头的行表示Git不应忽略的文件,即使它们与以前的模式匹配。允许使用空行来提高可读性,任何以#开头的行都是注释。

有关此文件的模式匹配格式的详细信息,请参阅gitignore(5)手册页中的"PATTERl format"。特别注意这些图案匹配线中单星号(*)和双星号(**)之间的区别。(双星号可以匹配多个目录级别。)

下面是一个.gitignore文件的示例:

roles/**

!roles/requirements.yml

collections/ansible_collections

ansible-navigator.log

*-artifact-*

.ssh

6. 课堂练习:使用Git管理Ansible项目材料

开始练习(部署环境):

以用户student登入workstation虚拟机,使用lab命令来构建案例环境。

javascript 复制代码
[student@workstation ~]$ lab start develop-git

步骤说明:

1)从 https://git.lab.example.com/student/develop-git.git 克隆项目库到/home/student/git-repos目录,并为本练习创建一个新的分支

新建目录/home/student/git-repos目录,并进入此目录:

javascript 复制代码
[student@workstation ~]$ mkdir -p ~/git-repos/
[student@workstation ~]$ cd ~/git-repos/

克隆 https://git.lab.example.com/student/develop-git.git 项目到本地,然后进入本地仓库目录:

javascript 复制代码
[student@workstation git-repos]$ git clone https://git.lab.example.com/student/develop-git.git
Cloning into 'develop-git'...
...output omitted...

[student@workstation git-repos]$ cd develop-git

检出名为exercise的开发分支:

javascript 复制代码
[student@workstation develop-git]$ git checkout -b exercise
Switched to a new branch 'exercise'

2)为用户student配置Git全局参数:指定用户名、电子邮箱地址、默认推送方法,连接到https://git.lab.example.com,允许Git记住密码2小时

使用 git config 命令来定义Git全局参数:

javascript 复制代码
[student@workstation develop-git]$ git config --global user.name 'Student User'

[student@workstation develop-git]$ git config --global user.email student@lab.example.com

[student@workstation develop-git]$ git config --global push.default simple      //推送方法

[student@workstation develop-git]$ git config --global credential.https://git.lab.example.com.username student      //认证方式

[student@workstation develop-git]$ git config --global credential.helper cache --timeout=7200    //缓存时间

确认设置结果:

javascript 复制代码
[student@workstation develop-git]$ git config --global -l
user.name=Student User
user.email=student@lab.example.com
push.default=simple
credential.https://git.lab.example.com.username=student
credential.helper=cache

3)使用tree命令检查项目目录下的文件:

javascript 复制代码
[student@workstation develop-git]$ tree
.
├── apache-setup.yml
└── templates
├── httpd.conf.j2
└── index.html.j2
1 directory, 3 files
  • apache-setup.yml是剧本文件
  • 模板文件httpd.conf.j2用来定义Apache服务器的配置
  • 模板文件index.html.j2 用来建立网站服务器的默认页

4)修改apache-setup.yml剧本,用来管理web_servers清单主机组

在项目目录下创建 inventory 清单文件,内容如下:

javascript 复制代码
[student@workstation develop-git]$ vim inventory
[web_servers]
serverd

在项目目录下创建Ansible配置文件,使用inventory清单、以用户devops连接到受管机,文件ansible.cfg的内容如下:

javascript 复制代码
[student@workstation develop-git]$ vim ansible.cfg
[defaults]
inventory = inventory
remote_user = devops

修改 apache-setup.yml 剧本文件,管理目标为web_servers主机组,剧本开头包含以下内容:

javascript 复制代码
[student@workstation develop-git]$ vim apache-setup.yml
---
name: Install web servers with WSGI interface
hosts: web_servers      # 修改主机清单
become: true
vars:
  httpd_packages:
    - httpd
    - python3-mod_wsgi
  apache_test_message: This is a test message
  apache_max_keep_alive_requests: 115
...output omitted...

检查本地Git仓库的当前状态:

javascript 复制代码
[student@workstation develop-git]$ git status
On branch exercise
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: apache-setup.yml
Untracked fiLes:
(use "git add <file>..." to include in what will be committed)
ansible.cfg
inventory


no changes added to commit (use "git add" and/or "git commit -a")

使用git add命令来暂存这3个文件,以便下一次提交:

javascript 复制代码
[student@workstation develop-git]$ git add .

[student@workstation develop-git]$ git status

On branch exercise
Changes to be committed:

(use "git restore --staged <file>..." to unstage)
new fiLe: ansible.cfg
modified: apache-setup.yml
new fiLe: inventory

提交更改,标注信息为"Target the web_servers group":

javascript 复制代码
[student@workstation develop-git]$ git commit -m "Target the web_servers group"

[exercise cc04da0] Target the web_servers group
3 files changed, 6 insertions(+), 1 deletion(-)
create mode 100644 ansible.cfg
create mode 100644 inventory

推送本地已提交的更改到远程服务器,如果提示需要密码,请使用Student@123:

javascript 复制代码
[student@workstation develop-git]$ git push -u origin exercise

Password for 'https://student@git.lab.example.com': Student@123


Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 494 bytes | 494.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0), pack-reused 0 remote:
remote: To create a merge request for exercise, visit:
remote: https://git.lab.example.com/student/develop-git/-/merge_requests/new? 
merge_request%5Bsource_branch%5D=exercise


remote:
To https://git.lab.example.com/student/develop-git.git

 [new branch] exercise -> exercise

Branch 'exercise' set up to track remote branch 'exercise' from 'origin'.

5)通过ansible-navigator导航器运行apache-setup.yml剧本,然后确认网站服务器的页面内容

使用podman login命令登录到位于hub.lab.example.com的私有自动化中心,以用户student、密码redhat123来验证。此步骤模拟客户登录registry.redhat.io,并确保指定的自动化执行环境被拉取到本地系统:

javascript 复制代码
[student@workstation develop-git]$ podman login hub.lab.example.com
Username: student
Password: redhat123
login Succeeded!

使用ee-supported-rhel8:latest执行环境来运行 apache-setup.yml 剧本:

javascript 复制代码
[student@workstation develop-git]$ ansible-navigator run apache-setup.yml --eei ee-supported-rhel8:latest

  Play name                                                                     Ok    Changed         Unreachable            Failed        Skipped         Ignored        In progress            Task count                     Progress
0│Install web servers with WSGI interface                                        8          7                   0                 0              0               0                  0                     8                     Complete

按Esc键退出ansible-navigator交互环境。

使用curl命令检查Web网站的页面内容:

javascript 复制代码
[student@workstation develop-git]$ curl serverd

This is a test message RedHat 8.4 <br>

Current Host: serverd <br>

Server list: <br>

serverd <br>

检查本地Git仓库的状态。ansible-navigator命令创建了.ssh/目录、ansible-navigator.log文件,以及每次通过ansible-navigator 运行剧本时会生成一个当时的 artifact工件文件:

javascript 复制代码
[student@workstation develop-git]$ git status

On branch exercise
Your branch is up to date with 'origin/exercise'.

Untracked fiLes:
(use "git add <file>..." to incNude in what will be committed)
ansible-navigator.log

apache-setup-artifact-2022-09-12T20:00:56.911737+00:00.json

nothing added to commit but untracked files present (use "git add" to track)

新建一个.gitignore文件以便忽略上述由ansible-navigator命令创建的文件,内容如下:

javascript 复制代码
[student@workstation develop-git]$ vim .gitignore
ansible-navigator.log
*-artifact-*

检查本地Git仓库的状态,可以看到这些文件已经被忽略了:

javascript 复制代码
[student@workstation develop-git]$ git status

On branch exercise

Your branch is up to date with 'origin/exercise'.

Untracked files:
(use "git add <file>..." to incNude in what will be committed)
.gitignore

添加并提交新的Git更改,标记信息为"Ignore generated files":

javascript 复制代码
[student@workstation develop-git]$ git add .gitignore

[student@workstation develop-git]$ git commit -m "Ignore generated files"

[exercise b780076] Ignore generated files
1 file changed, 2 insertions(+)
create mode 100644 .gitignore

将最新的提交推送到远程的Git仓库,如果需要的话,使用Student@123密码:

javascript 复制代码
[student@workstation develop-git]$ git push

Enumerating objects: 4, done. Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 323 bytes | 323.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 remote:
remote: To create a merge request for exercise, visit:
remote: https://git.lab.example.com/student/develop-git/-/merge_requests/new? 
merge_request%5Bsource_branch%5D=exercise
remote:
To https://git.lab.example.com/student/develop-git.git
 6f87080..4ec3448 exercise -> exercise

结束练习(清理环境):

在workstation虚拟机上,切换到student用户主目录,使用lab命令来清理案例环境,确保先前练习的资源不会影响后续的练习。

javascript 复制代码
[student@workstation ~]$ lab finish develop-git

四、 Ansible最佳实践

1. Ansible的有效性

本课程介绍了红帽Ansible自动化平台的一些高级功能。有效地使用Ansible不仅仅是功能或工具,而是通过更好的实践和组织,来管理和维护剧本以及有效使用这些剧本。

Ansible开发人员Jeff Geerling提出,有效地使用Ansible依赖于三个关键实践:

  • 保持简单

  • 保持有序

  • 定期测试

2. 保持简单

Ansible的优点之一是它的简单性。简单的剧本更易于使用、修改和理解。

1)提高剧本的可读性

为剧本添加完善的 注释 ,按需使用 空行,让剧本更易读、易懂。

为play、task设置 有意义的名字,明确剧本或任务在做什么。

这些做法有助于为剧本形成文档,当剧本运行失败时也更容易进行故障排除。

YAML不是一种编程语言,它更适合表达任务或项目的列表,或一组键值对。如果想在剧本中表达一个复杂的控制结构或条件,那么可以考虑用不同的方式来处理,比如模板、Jinja2过滤器提供了处理变量中数据的功能,这可能会更好用。

使用 原生YAML语法 ,而不是"折叠"语法。例如,不推荐使用等号的写法:

javascript 复制代码
- name: Postfix is installed and updated
  ansible.builtin.yum: name=postfix state=latest notify: restart_postfix

- name: Postfix is running
  ansible.builtin.service: name=postfix state=started

更推荐这种冒号分隔的键值对写法:

javascript 复制代码
- name: Postfix is installed and updated
  ansible.builtin.yum:
    name: postfix
    state: latest
  notify: update_postfix

- name: Postfix is running
  ansible.builtin.service:
    name: postfix
    state: started

2)使用专有模块

写一个新剧本时,可以从一个基本的剧本开始,尽量从一份静态清单开始。

在设计剧本内容时,使用 ansible.buildin.debug 任务进行调试。

如果剧本能够按预期运行,请使用 import 导入和 include 包含将剧本分解为更小的逻辑组件。

尽可能使用Ansible内置的专有模块,而不是 ansible.builtin.command、ansible.builtin.shell、ansible.builting.raw或其他类似模块。使用为特定任务设计的专有模块,会更容易实现剧本幂等,剧本也更容易维护。

很多模块都有默认的state或一些变量来控制它们的操作,例如yum模块会假设你给定名称的软件包的state都应该是present。但是,推荐的做法是应该明确指出你想要的state,而不是什么都不写(按默认值),这样做可以让剧本更容易阅读。

3)采用一致/标准的风格

在编写Ansible项目时,考虑采用同一种标准的"风格"。例如,缩进了多少个空格?如何使用垂直空白?如何命名任务、角色、角色和变量?哪些内容应该添加注释、如何添加注释?有一个一致的标准可以帮助提高可维护性和可读性。

3. 保持有序

组织良好的标准有助于维护、排错。利用好Ansible的组织功能,像role角色,以便可以重用它们。

1)命名变量的约定

尽量使用描述性变量,如 apache_tls_port ,而不是解释性较差的变量,如 p.in

最好将角色名称作为角色变量的前缀。如果角色名称是myapp,那么在变量前面加myapp_,这样就可以很容易地区分出这个变量了。

变量名称应明确内容,例如 apache_max_keepalive 这样的名称可以清楚表明它的含义。

使用变量所属的角色或组的名称作为角色和组变量的前缀。例如使用apache_port_number,比起使用port_number更能避免错误。

2)标准化项目结构

构建Ansible项目的文件时,请使用一致的模式。以下是一个很好的例子(如图-13所示)。

site.yml文件是 主要的剧本,通过它包含或导入执行特定任务的其他剧本:dbservers.yml、storage.yml和webservers.yml。

每个角色都位于 roles目录 中的一个子目录中,例如std_server。

inventories/prod 和 inventories/stage 目录中的两个静态清单提供了单独的清单变量文件,因此可以通过变更使用的清单来选择不同的受管主机。

剧本结构的好处之一是,可以将大量的剧本分成更小的文件,使其更具可读性。那些较小的剧本可以包含特定目的的剧本,您可以独立运行。

3)使用动态清单

如果可能,尽量使用动态清单。

动态清单使得集中管理主机和组时能有一个可信的受管机来源,确保在运行剧本之前,有一个更新的主机和组列表。如果与云服务商、容器和虚拟机管理系统配合使用,动态清单更加灵活和强大。

如果不能使用动态清单,那么其他工具可以用来构建组,或者额外的信息。例如,通过 group_by 模块可以根据facts指标来生成组成员身份,组成员身份对剧本的其余部分也是有效的。

javascript 复制代码
- name: Generate dynamic groups
  hosts: all
  tasks:
    - name: Generate dynamic groups based on architecture
      ansible.builtin.group_by:
        key: arch_"{{ ansible_facts['architecture'] }}"

- name: Configure x86_64 systems
  hosts: arch_x86_64
  tasks:
    - name: First task for x86_64 configuration

...output omitted...

4)用好主机分组

主机可以是多个组的成员,考虑根据不同的特性将主机分为不同的类别。

  • 按地理位置:区分不同地区、国家/地区、大洲或数据中心的主机。

  • 按环境:区分专用于软件生命周期不同阶段的主机,包括开发阶段、测试和生产。

  • 按站点用途:提供或链接到功能子集的组主机,如特定网站、应用程序或功能子集。

请记住,受管主机从其所属的所有组继承变量。如果两个组对同一变量具有不同的设置,并且主机是这两个组的成员,则使用的值是最后加载的值。

5)使用角色和内容集合以便重用

角色和内容集合可以让剧本更简单,并且更方便用在跨多个项目的场景。如果你编写自己的角色和内容集,就要像写剧本一样,聚焦在特定的目的或功能上。尽量使角色具有通用性并可通过变量进行配置,这样当需要将这些角色与不同的剧本一起使用时,就不需要再重复编辑了。

使用ansible-galaxy命令初始化角色或集合的目录层次结构,并提供初始模板文件,这样会更容易通过私有自动化中心或社区Ansible Galaxy网站共享内容。

多使用红帽认证的Ansible内容集合,AAP平台订阅支持这些功能,并提供许多有用的功能和特性。

将你的角色放置在项目的roles子目录中,将集合放置在项目的collections子目录中。使用ansible-galaxy命令自动从自动化中心或单独的Git存储库中获取角色。

6)通过集中的方式运行剧本

要控制对系统的访问并审核Ansible活动,请使用一个专用的控制节点来运行所有Ansible剧本,比如自动化控制器。即使您不使用自动化控制器,使用中央控制节点也是有益的。

系统管理员仍应在系统上拥有自己的账户,以及连接到托管主机的凭据和升级权限(如果需要)。当系统管理员离开时,他们的SSH密钥可以从托管主机的authorized_keys文件中删除,并且他们的sudo命令权限将被吊销,而不会影响其他管理员。

自动化控制器包含在Red Hat Ansible Automation Platform订阅中,它提供的功能使您更容易控制对凭据的访问、控制剧本执行、为不熟悉Linux命令行的用户简化自动化,以及审核和跟踪剧本运行。

7)构建自动化执行环境

如果需要频繁使用特定的Ansible内容集合,特别是当该集合具有Python依赖项或系统可执行文件而不包含在支持的自动化执行环境中时,可以创建自定义的自动化执行环境。

但是,如果已经有可用的自动化执行环境来运行您的剧本,尽量重用这些自动化执行环境,这样可以减少维护工作量和必须管理的执行环境的数量。

4. 定期测试

在开发过程中、任务运行时以及使用剧本后,经常测试剧本和任务。

1)测试任务的结果

要确认任务成功,尽可能要验证任务的结果,而不是信任模块的返回代码。根据所涉及的模块,有多种方法可以验证任务。

javascript 复制代码
- name: Start web server ansible.builtin.service:
  name: httpd
  status: started

- name: Check web site from web server
  ansible.builtin.uri:
    url: http://{{ ansible_fqdn }}
    return_content: true
  register: example_webpage
  failed_when: example_webpage.status != 200

2)使用block和rescue实现故障恢复或回滚

block指令有助于对任务进行分组,与rescue指令一起使用时,对错误或故障中恢复非常有用。

javascript 复制代码
- block:
  - name: Check web site from web server
    ansible.builtin.uri:
      url: http://{{ ansible_fqdn }}
      return_content: true
    register: example_webpage
    failed_when: example_webpage.status != 200

  rescue:
    name: Restart web server
    ansible.builtin.service:
     name: httpd
     status: restarted

3)用最新的Ansible版本开发剧本

即使你在生产中没有使用最新版本的Ansible Core,你也应该根据最新版本Ansible Core定期测试你的剧本。此测试可帮助你避免随着Ansible模块和功能的发展而出现问题。

自动化执行环境可以通过提供Ansible Core的当前版本和遗留版本来帮助简化这一过程,您可以使用这些版本来测试您的剧本。

如果你的剧本在运行时打印出警告或弃用信息,那么你应该注意并做出调整。如果Ansible Core中的某个功能被弃用或正在更改,那么在删除或更改该功能之前,该项目将为四个次要版本提供弃用通知。

4)使用测试工具

有很多命令和工具可以用来测试你的剧本。可使用 ansible-navigator run playbook --syntax-check -m stdout 命令来验证你的剧本的语法,而不是直接运行这个剧本。

在红帽AAP 2.2中作为技术预览添加的ansible-lint工具可以分析你的剧本并查找可能的问题。它报告的问题不一定都会导致剧本失败,但报告的问题可能表明存在错误。

5. 课堂练习:Ansible最佳实践

开始练习(部署环境):

以用户student登入workstation虚拟机,使用lab命令来构建案例环境。

javascript 复制代码
[student@workstation ~]$ lab start develop-practices 

步骤说明:

1)lab start命令在~/develop-practices目录创建了一个项目,并通过deploy.yml剧本部署了httpd网站服务、mariadb数据库服务

进入项目目录,并检查 deploy.yml 剧本:

javascript 复制代码
[student@workstation ~]$ cd ~/develop-practices/

[student@workstation develop-practices]$ cat deploy.yml
---
- name: Deploy a web application
  hosts: webservers

.. ..

2)第二个play用来在serverc.lab.example.com和serverd.lab.example.com主机上安装MariaDB数据库,为这个play起一个名称,并指定受管主机组以便更容易管理

在清单文件 ~/develop-practices/inventory 中,创建dbservers组,包括主机serverc.lab.example.com 和serverd.lab.example.com,内容就像这样:

javascript 复制代码
[student@workstation develop-practices]$ vim inventory
*...output omitted...*

[webservers]
servera.lab.example.com
serverb.lab.example.com

[dbservers]         # 创建dbservers组
serverc.lab.example.com
serverd.lab.example.com

在剧本 ~/develop-practices/deploy.yml 中, 配置第2个play在dbservers组运行,并将play名称设置为"Deploy database servers",内容就像这样:

javascript 复制代码
[student@workstation develop-practices]$ vim deploy.yml
...output omitted...
- name: Deploy database servers    # 名称设置
  hosts: dbservers    # 设置dbservers组
  vars:
    service: mariadb
    fw_service: mysql
    package:
      - mariadb-server
  
...output omitted...

3)按下列说明修改deploy.yml剧本中开头2个play的变量

新建组变量文件 ~/develop-practices/group_vars/webservers;把第1个play中的 service、fw_service、package 变量移过来,变量名分别改为 web_service、web_fw_service、web_package。

javascript 复制代码
[student@workstation develop-practices]$ vim group_vars/webservers
---
web_dest: /var/www/html/index.html
web_service: httpd
web_fw_service: http
web_package:
  - httpd

删除 ~/develop-practices/deploy.yml 剧本中第1个play的vars变量定义:

javascript 复制代码
---
- name: Deploy a web application
  hosts: webservers
  tasks:
    - name: Install the webserver
      ansible.builtin.yum: name={{ package }} state=latest

...output omitted...

修改 ~/develop-practices/deploy.yml剧本中以下这三个任务使用的变量名:

  • Install the webserver

  • Start the webserver

  • Enable the {{ fw_service }} service in the firewall

更新的task设置就像这样:

javascript 复制代码
[student@workstation develop-practices]$ vim deploy.yml
- name: Install the webserver
  ansible.builtin.yum: name={{ web_package }} state=latest

...output omitted...

- name: Start the webserver
  ansible.builtin.service:
    name: "{{ web_service }}"
    state: started
    enabled: true
  

- name: Enable the {{ web_fw_service }} service in the firewall
  ansible.posix.firewalld:
    service: "{{ web_fw_service }}"
    state: enabled
    permanent: true
    immediate: true

新建组变量文件 ~/develop-practices/group_vars/dbservers ; 把第2个play中的service、fw_service、package变量移过来,变量名分别改为 db_service、db_fw_service、db_package。文件内容就像这样:

javascript 复制代码
[student@workstation develop-practices]$ vim group_vars/dbservers
---
db_service: mariadb
db_fw_service: mysql
db_package:
  - mariadb-server

删除 ~/develop-practices/deploy.yml 剧本中第2个play的vars变量定义:

javascript 复制代码
...output omitted...

- name: Deploy database servers
  hosts: dbservers
  tasks:

...output omitted...

修改**~/develop-practices/deploy.yml** 剧本中以下这三个任务使用的变量名:

  • Install thedatabase server

  • Start the database server

  • Enable the {{fw_service}} service in the firewall

更新的task设置就像这样:

javascript 复制代码
[student@workstation develop-practices]$ vim deploy.yml
- name: Install the database server
  ansible.builtin.yum:
    name: "{{ db_package }}"
    state: latest

 - name: Start the database server
  ansible.builtin.shell:
    cmd: systemctl enable --now {{ db_service }}

- name: Enable the {{ db_fw_service }} service in the firewall
  ansible.posix.firewalld:
    service: "{{ db_fw_service }}"
    state: enabled
    permanent: true
    immediate: true

4)第1个play中的Install The webserver任务使用ansible.builtin.yum模块的折叠语法,可以将此任务更改为使用原生YAML语法

更新后的任务内容就像这样:

javascript 复制代码
- name: Install the webserver
  ansible.builtin.yum:
    name: "{{ web_package }}"
    state: latest

5)任务Start the webserver和 Enable the {{ web_fw_service }} service in the firewall 使用了与剧本中其他部分不一致的缩进,可以修正缩进

更新后的任务内容就像这样:

javascript 复制代码
- name: Start the webserver
  ansible.builtin.service:
    name: "{{ web_service }}"
    state: started
    enabLed: true

- name: Enable the {{ web_fw_service }} service in the firewall
  ansible.posix.firewalld:
    service: "{{ web_fw_service }}"
    state: enabled
    permanent: true
    immediate: true

6)任务Start the database server使用了ansible.builtin.shell模块来运行systemctl命令以激活及启用一个服务,可以改用ansible.builtin.service模块

更新后的任务内容就像这样:

javascript 复制代码
- name: Start the database server
  ansible.builtin.service:
    name: "{{ db_service }}"
    state: started
    enabled: true

7)剧本~/develop-practices/deploy.yml的第3个play没有设置tasks,可以为这个play添加一个block、rescue语句设置,当网站应用不可用时来为webservers组的主机重启web服务

更新后的任务内容就像这样:

javascript 复制代码
- name: Test web application
  hosts: webservers
  tasks:
    - name: Web application test
      block:
        - name: Check web application
          ansible.builtin.uri:
            url: http://{{ item }}
          loop: "{{ groups['webservers'] }}"
      rescue:
        - name: Restart web server
          ansible.builtin.service:
            name: "{{ web_service }}"
            state: restarted

8)检查剧本文件,确保内容无误

9)通过ansible-navigator导航器运行deploy.yml剧本(如图-14所示)

结束练习(清理环境):

在workstation虚拟机上,切换到student用户主目录,使用lab命令来清理案例环境,确保先前练习的资源不会影响后续的练习。

javascript 复制代码
[student@workstation ~]$ lab finish develop-practices

五、 综合实验:使用红帽AAP平台开发剧本

开始实验(部署环境):

以用户 student 登入workstation虚拟机,使用lab命令来构建案例环境。

javascript 复制代码
[student@workstation ~]$ lab start develop-review

解决方案:

1. 从https://git.lab.example.com/student/develop-review.git克隆项目到 /home/student/git-repos 目录下,并创建一个名为 exercise 的新分支

1)新建目录/home/student/git-repos,并进入此目录

javascript 复制代码
[student@workstation ~]$ mkdir -p ~/git-repos/
[student@workstation ~]$ cd ~/git-repos/

2)从https://git.lab.example.com/student/develop-review.git克隆Git项目,并进入此项目

javascript 复制代码
[student@workstation git-repos]$ git clone https://git.lab.example.com/student/develop-review.git

Cloning into 'develop-review'...
remote: Enumerating objects: 17, done.
remote: Counting objects: 100% (17/17), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 17 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (17/17), done.

[student@workstation git-repos]$ cd develop-review

3)检出exercise分支

javascript 复制代码
[student@workstation develop-review]$ git checkout -b exercise

2. 为 site.yml 剧本中的play添加role名称,为 roles/test/tasks/main.yml 角色文件中的两个task添加名称,确保play 和 task 的名称有意义

1)修改site.yml剧本文件,为play设置名称

javascript 复制代码
[student@workstation develop-review]$ vim site.yml
---
- 
hosts: all
  become: true
  roles:
    - role: grub    # 设置role名称

2)修改roles/test/tasks/main.yml角色文件,为每一个task设置名称

javascript 复制代码
[student@workstation develop-review]$ vim roles/test/tasks/main.yml
---
- name: Sets persistent GRUB timeout    # 设置名称
  ansible.builtin.lineinfile:
    path: /etc/default/grub
    regexp: "^GRUB_TIMEOUT="
    line: "GRUB_TIMEOUT={{ timeout | int }}"
  when: persistent | bool == true

- name: Sets temporary GRUB timeout    # 设置名称
  ansible.builtin.lineinfile:
    path: /boot/grub2/grub.cfg
    regexp: "^set timeout="
    line: "set timeout={{ timeout | int }}"

3. 剧本 site.yml 剧本使用test角色来部署配置变更,但是这个角色没有合适的名称,请将此角色重命名为grub,并对site.yml剧本做相应修改

1)编辑 site.yml文件 以调用新的grub角色

javascript 复制代码
---
- name: Sets the GRUB timeout # 设置名称
  hosts: all
  become: true
  roles:
    - role: grub

2)将角色roles/test改名为 roles/grub(这里使用git mv,可以自动将变更添加到暂存区)

javascript 复制代码
[student@workstation develop-review]$ ls roles/
test
[student@workstation develop-review]$ git mv roles/test roles/grub

4. 修改 roles/grub/defaults/main.yml 和 group_vars/lb_servers.yml 文件,为两个角色变量名称(timeout和persistent)添加 grub_ 前缀

1)修改 roles/grub/defaults/main.yml 角色文件,添加 grub_前缀

javascript 复制代码
--- 
grub_timeout:0
grub_persistent: true

2)修改 group_vars/lb_servers.yml 组变量文件,添加 grub_前缀

javascript 复制代码
---
grub_timeout: 30
grub_persistent: true

3)修改 roles/grub/tasks/main.yml 文件,persistent 添加 grub_前缀

javascript 复制代码
---
- name: Sets persistent GRUB timeout
  ansible.builtin.lineinfile:
    path: /etc/default/grub
    regexp: "^GRUB_TIMEOUT="
    line: "GRUB_TIMEOUT={{ grub_timeout | int }}"    #修改前缀
  when: grub_persistent | bool == true    #修改前缀

- name: Sets temporary GRUB timeout
  ansible.builtin.lineinfile:
    path: /boot/grub2/grub.cfg
    regexp: "^set timeout="
    line: "set timeout={{ grub_timeout | int }}"    #修改前缀

5. 测试~/git-repos/development/review/site.yml剧本 ------ 使用ee-supported-rhel8执行环境,确保site.yml文件能够正确运行。

EE环境可从hub.lab.example.com获得,用户名student,密码redhat123

使用ee-supported-rhel8执行环境运行site.yml剧本,确认剧本运行无误

javascript 复制代码
[student@workstation develop-review]$ ansible-navigator run site.yml --eei ee-supported-rhel8 --pp missing -m stdout

6. 将上述对项目文件的所有更改推送到远程Git存储库的exercise分支。

1)查看本地Git仓库发生了哪些变化

javascript 复制代码
 [student@workstation develop-review]$ git status

On branch exercise
 Changes to be committed:
(use "git restore --staged <file>..." to unstage)
 renamed: roles/test/README.md -> roles/grub/README.md
 renamed: roles/test/defaults/main.yml -> roles/grub/defaults/main.yml
 renamed: roles/test/meta/main.yml -> roles/grub/meta/main.yml
 renamed: roles/test/tasks/main.yml -> roles/grub/tasks/main.yml

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
 modified: group_vars/lb_servers.yml
 modified: roles/grub/README.md
 modified: roles/grub/defaults/main.yml
 modified: roles/grub/tasks/main.yml
 modified: site.yml

2)将新建及修改的文件加入到暂存区

javascript 复制代码
[student@workstation develop-review]$ git add group_vars/ roles/ site.yml

3)将暂存区的文件提交到本地Git仓库

javascript 复制代码
[student@workstation develop-review]$ git commit -m 'Changes for exercise'

4)将本地Git仓库中的提交(对exercise分支的更改)推送给远程Git仓库,密码Student@123

javascript 复制代码
[student@workstation develop-review]$ git push -u origin exercise
Password for 'https://student@git.lab.example.com': Student@123

5)确认exercise分支的更改已经推送成功

javascript 复制代码
[student@workstation develop-review]$ git status
On branch exercise

Your branch is up to date with 'origin/exercise'.

nothing to commit, working tree clean

结束实验(清理环境):

在workstation虚拟机上,切换到student用户主目录,使用lab命令来清理案例环境,确保先前练习的资源不会影响后续的练习。

javascript 复制代码
[student@workstation ~]$ lab finish develop-review

思维导图:

小结:

本篇为 **【RHCA认证 - DO374 | Day01:使用红帽Ansible自动化平台开发剧本】**的学习笔记,希望这篇笔记可以让您初步了解红帽AAP2.2平台、如何通过导航器运行剧本、使用Git管理Ansible项目材料/代码、Ansible最佳实践等,不妨跟着我的笔记步伐亲自实践一下吧!


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关环境、视频,可评论666并私信小安,请放下你的羞涩,花点时间直到你真正的理解。

相关推荐
咬_咬5 小时前
C++仿mudo库高并发服务器项目:Buffer模块
服务器·开发语言·c++·缓冲区·buffer·muduo库
刘岩Tony5 小时前
ssh别名和多服务器同步文件
运维·服务器·ssh
zzy20887402715 小时前
自定义服务器实现时间同步
运维·服务器
LXY_BUAA6 小时前
在电脑中安装双系统(win11 + linux)20251019
linux·运维·服务器
白帽子黑客罗哥6 小时前
云原生安全深度实战:从容器安全到零信任架构
安全·云原生·架构·零信任·容器安全·kubernetes安全·服务网络
Rverdoser6 小时前
关于网站整体实现流程有哪些
服务器
嫄码6 小时前
HTTPS的四次握手过程
服务器·网络·https
TG_yunshuguoji6 小时前
亚马逊云代理商:怎么快速构建高安全区块链应用?
网络·安全·云计算·区块链·aws
喜欢你,还有大家7 小时前
企业安全防护之——防火墙
服务器·网络·安全