Puppet新手教程:什么是Puppet及如何使用?
在学习 Puppet 之前,让我们先了解
什么是配置管理?
配置管理是维护软件和计算机系统(例如服务器、存储、网络)处于已知、期望和一致状态的过程。它还允许访问准确的系统状态历史记录,以用于项目管理和审计目的。
系统管理员主要执行重复性任务,例如安装服务器、配置这些服务器等。这些专业人员可以通过编写脚本来自动化此任务。
然而,当他们处理大规模基础设施时,这是一项艰巨的任务。像 Puppet 这样的配置管理工具的出现就是为了解决这些问题。
什么是 Puppet?
Puppet 是一款系统管理工具,用于集中和自动化配置管理过程。Puppet 也被用作软件部署工具。它是一款开源的配置管理软件,广泛用于服务器配置、管理、部署以及组织整个基础设施的各种应用程序和服务编排。
Puppet 专门设计用于管理 Linux 和 Windows 系统的配置。它用 Ruby 编写,并使用其独特的领域特定语言 (DSL) 来描述系统配置。
Puppet 有哪些版本?
Puppet 有两个版本
- 开源 Puppet:它是 Puppet 配置管理工具的基本版本,也称为开源 Puppet。它可以直接从 Puppet 网站下载,并根据 Apache 2.0 系统获得许可。
- Puppet Enterprise:商业版本,提供合规性报告、编排、基于角色的访问控制、GUI、API 和命令行工具等功能,用于有效管理节点。
Puppet 能做什么?
例如,您拥有大约 100 台服务器的基础设施。作为系统管理员,您的职责是确保所有这些服务器始终保持最新状态并 fully functional 运行。
要做到这一点,您可以使用 Puppet,它允许您编写简单的代码,这些代码可以自动部署到这些服务器上。这减少了人为努力,并使开发过程快速而有效。
Puppet 执行以下功能
- Puppet 允许您为每个主机定义不同的配置。
- 该工具允许您持续监控服务器,以确认所需配置是否存在且未被更改。如果配置发生更改,Puppet 工具将恢复到主机上预定义的配置。
- 它还控制所有已配置的系统,因此集中的更改会自动生效。
- 它也用作部署工具,因为它会自动将软件部署到系统。它实现了基础设施即代码,因为策略和配置是作为代码编写的。
Puppet DSL 和编程范例
在学习 Puppet DSL 之前,让我们先了解编程范例
编程范例是您在计算机编程中使用的风格。
四种范例是
- 命令式。
- 声明式。
- 函数式(被认为是声明式范例的一个子集)
- 面向对象。
我们将重点关注命令式和声明式。
命令式范例
这种编程范例表达了计算的逻辑(做什么)并描述了其控制流(如何做)
示例
假设您要去办公室,您预订了一辆出租车,并开始向司机提供一步步的指示,直到您到达办公室。指定做什么和如何做是命令式风格。
声明式范例
这种编程范例表达了计算的逻辑(做什么)而不描述其控制流(如何做)
示例
假设您要去办公室,您预订了一辆 Uber 出租车并指定最终目的地(办公室)。指定做什么而不是如何做是声明式风格。
范例 | 做什么 | 怎么做 |
---|---|---|
命令式 | 是 | 是 |
声明式 | 是 | 否 |
Puppet 使用声明式编程范例
Puppet 使用声明式编程方法。
示例:在系统上创建用户
可以使用命令式编程模式通过 shell 脚本完成:这里我们指定如何创建用户以及在操作系统上使用什么命令。
然而,可以使用声明式编程模式,只需几行 puppet 代码,Puppet 领域特定语言 (DSL),即可实现相同的结果。
配置管理工具的部署模型
有两种配置管理工具的部署模型
- 推送式部署模型:由主节点发起。
- 拉取式部署模型:由代理发起。
推送式部署模型
在此部署模型中,主服务器将配置和软件推送到各个代理。在验证安全连接后,主服务器在代理上远程运行命令。例如,Ansible 和 Salt Stack。
拉取式部署模型。
在此部署模型中,各个服务器联系主服务器,验证并建立安全连接,下载其配置和软件,然后进行相应的自我配置 — 例如,Puppet 和 Chef。
Puppet 是如何工作的?
Puppet 基于拉取部署模型,代理节点每 1800 秒定期与主节点检查一次,以查看是否有任何需要更新的代理。如果有需要更新的内容,代理将从主节点拉取必要的 puppet 代码并执行所需操作。
让我们通过一个例子来解释
示例:主代理设置
主节点
安装了 Puppet 主软件的基于 Linux 的机器。它负责以 puppet 代码形式维护配置。主节点只能是 Linux。
代理
由 puppet 管理的目标机器,上面安装了 puppet 代理软件。
代理可以配置在任何支持的操作系统上,例如 Linux 或 Windows 或 Solaris 或 Mac OS。
主节点和代理之间的通信通过安全证书建立。
主节点与代理之间的通信
步骤 1) 一旦代理和主节点之间的连接建立,Puppet 代理会将有关其状态的数据发送到 Puppet 主服务器。这些称为 Facts:此信息包括主机名、内核详细信息、IP 地址、文件名详细信息等……
步骤 2) Puppet Master 使用此数据并编译一个列表,其中包含要应用于代理的配置。此要对代理执行的配置列表称为目录 (catalog)。这可以包括诸如软件包安装、升级或删除、文件系统创建、用户创建或删除、服务器重启、IP 配置更改等更改。
步骤 3) 代理使用此配置列表在节点上应用任何所需的配置更改。
如果配置没有偏差,代理将不执行任何配置更改,让节点以相同的配置运行。
步骤 4) 完成后,节点会向 puppet master 报告,表明配置已应用并完成。
Puppet 块
Puppet 通过 Puppet API 提供了与第三方工具集成 Reports 的灵活性。
Puppet 的四种构建块是
- 资源
- 类
- Manifest
- Modules
Puppet 资源
Puppet 资源是 Puppet 的构建块。
资源是后端运行以在 puppet 中执行所需操作的内置功能。
Puppet 类
不同的资源可以组合成一个称为类的单元。
Puppet Manifest
Manifest 是一个包含 puppet DSL 文件的目录。这些文件具有 .pp 扩展名。 .pp 扩展名代表 puppet 程序。 Puppet 代码包含 Puppet 类的定义或声明。
Puppet Modules
Modules 是文件和目录的集合,例如 Manifests、Class 定义。它们是 Puppet 中可重用和可共享的单元。
例如,用于安装和配置 MySQL 的MySQL 模块,或用于管理 Jenkins 的 Jenkins 模块等。
Puppet 资源类型
通常,一个系统由文件、用户、服务、进程、软件包等组成。在 Puppet 中,这些被称为资源。资源是 Puppet 中的基本构建块
Puppet。所有在 puppet 代理上的操作都是通过 puppet 资源执行的。
Puppet 资源是用于在任何支持的平台上执行各种任务和操作的现成工具。我们可以使用单个 puppet 资源来执行特定任务,也可以使用多个 puppet 资源一起执行一些复杂的应用程序配置部署。
资源可以有不同的类型。Puppet 使用资源和资源类型来描述系统的配置。
有三种资源类型
- Puppet 核心或内置资源类型。
- Puppet 定义的资源类型。
- Puppet 自定义资源类型。
Puppet 核心或内置资源类型
核心或内置资源类型是随 puppet 软件一起提供的预构建 puppet 资源类型。所有核心或内置的 Puppet 资源类型都由 Puppet 团队编写和维护。
Puppet 定义的资源类型
定义的资源类型是使用现有资源类型组合在 Puppet 声明式语言中编写的轻量级资源类型。
Puppet 自定义资源类型
自定义资源类型是完全自定义的资源类型,用 Ruby 编写。
让我们来探索 puppet 资源类型……
在终端中,键入以下命令以显示 Puppet 相关子命令列表
Puppet --help
在我们的例子中,我们感兴趣的是“resource”子命令,我们将用它来查找有关内置 puppet 资源类型的信息。
在终端中,键入以下任何命令以显示与 puppet 子命令“resource”关联的操作列表
Puppet help resource Puppet resource --help
在这种情况下,我们有子命令resource,操作是–types。
Puppet 有 49 个内置核心资源类型。
在终端中,键入以下命令以显示可用内置 puppet 资源类型的列表
puppet resource –types
每种类型都支持一个属性列表。这些属性提供了 Puppet 用来管理资源的详细描述。
要查找与 puppet 资源类型关联的所有属性,请使用以下命令
puppet describe <resource type name>
Parameters 将列出该资源类型所有可用的属性。
puppet describe package
对于新人来说,理解和关联许多未管理的 puppet 代码文件是很困难的。这时我们就需要一些分组来将操作联系起来。目的是解决一个单一问题,例如配置服务器上的 ssh 或 ntp 服务,或者从零开始配置完整的 Web 服务器或数据库服务器所需的所有操作。
什么是 Puppet 类?
Puppet 类是将 puppet 资源捆绑在一起作为单个单元的集合。
Puppet 引入类是为了使结构可重用且有组织。
首先,我们需要使用 class 定义语法来定义一个类;类必须是唯一的,并且只能以相同的名称声明一次。
class <class-name> { <Resource declarations> }
示例
class ntpconfig { file { "/etc/ntp.conf": ensure=> "present", content=> "server 0.centos.pool.ntp.org iburst\n", } }
到目前为止,我们只定义了类,但我们还没有在任何地方使用它。这意味着我们编写的代码永远不会执行,除非我们在其他地方声明这个类。
类声明
要在代码中使用已定义的类,请使用 include 关键字。
class ntpconfig { file { "/etc/ntp.conf": ensure=> "present", content=> "server 0.centos.pool.ntp.org iburst\n", } } include ntpconfig
让我们通过一个真实的案例场景来理解这一点。
演示安装 NTP
首先,确保 NTP 包尚未在服务器上,如果服务器上不存在 telnet,则以下命令将返回空
rpm -qa | grep -i ntp
正如我们所见,NTP 包已存在于服务器上。让我们删除现有的 NTP 包
yum remove ntp
删除包后,确保 ntp.conf 文件不存在
ls -lrt /etc/ntp.conf
通过运行以下命令验证 ntp 服务不存在
systemctl status ntp
创建一个新的 .pp 文件来保存代码。从命令行
vi demontp.pp
通过按键盘上的 i 键进入插入模式。
键入以下代码以创建一个新文件
# Class Definition class ntpconfig { # Installing NTP Package package {"ntp": ensure=> "present", } # Configuring NTP configuration file file {"/etc/ntp.conf": ensure=> "present", content=> "server 0.centos.pool.ntp.org iburst\n", } # Starting NTP services service {"ntpd": ensure=> "running", } }
编辑完成后:按 esc
要保存文件,请按 :wq!
下一步是检查代码是否有任何语法错误。执行以下命令
puppet parser validate demontp.pp
确保您已切换到root用户,以便能够无错误地完成测试,执行命令
su root
测试是代码创建过程的下一步。执行以下命令执行烟雾测试
Puppet applies demontp.pp --noop
最后一步是在真实模式下运行 puppet 并验证输出。
puppet apply demontp.pp
Puppet 没有执行任何操作,因为 demo 类只是被定义了但没有被声明。
因此,在您声明 puppet 类之前,代码不会被应用。
让我们在同一代码中使用 include class name 声明 demo 类,放在代码末尾
# Class Definition class ntpconfig { # Installing NTP Package package {"ntp": ensure=> "present", } # Configuring NTP configuration file file {"/etc/ntp.conf": ensure=> "present", content=> "server 0.centos.pool.ntp.org iburst\n", } # Starting NTP services service {"ntpd": ensure=> "running", } } # Class Declaration include ntpconfig
再次检查代码是否有任何语法错误。执行以下命令
puppet parser validate demontp.pp
确保您已切换到root用户,以便能够无错误地完成测试,执行命令
su root
测试是代码创建过程的下一步。执行以下命令执行烟雾测试
Puppet apply demontp.pp --noop
最后一步是在真实模式下运行 puppet 并验证输出。
puppet apply demontp.pp
这次代码被应用了,因为类被定义然后又被声明了。
确保 ntp.conf 现在存在
ls -lrt /etc/ntp.conf
通过运行以下命令验证 ntp 服务已启动
systemctl status ntpd