介绍
在代理/主配置中设置 Puppet 后,您可能需要一些帮助来编写 Puppet 清单和模块。 为了有效地使用 Puppet,您必须了解清单和模块是如何构造的。 本教程涵盖 Puppet 代码基础知识,并将向您展示如何构建清单和模块,以帮助您开始使用 Puppet 管理您的服务器环境。 我们将展示使用 Puppet 在 Ubuntu 14.04 VPS 上配置 LAMP 堆栈的三种不同方法。
先决条件
在开始本教程之前,您必须有一个工作代理/主 Puppet 设置。 如果您还没有这个,请按照本教程进行操作:如何安装 Puppet 来管理您的服务器基础架构。
您还需要能够创建至少一个新的 VPS 来充当 Puppet Master 将管理的 Puppet 代理节点。
创建一个新的代理节点
创建一个名为“lamp-1”的新Ubuntu 14.04 VPS,将其添加为Puppet代理节点,并在Puppet master上签署其证书请求。
木偶代码基础
在开始编写将配置我们的系统的 Puppet 代码之前,让我们退后一步,回顾一些相关的 Puppet 术语和概念。
资源
Puppet 代码主要由 资源声明 组成。 资源描述了有关系统状态的某些内容,例如应该存在某个用户或文件,或者应该安装一个包。 下面是一个用户资源声明的例子:
user { 'mitchell': ensure => present, uid => '1000', gid => '1000', shell => '/bin/bash', home => '/home/mitchell' }
资源声明的格式如下:
resource_type { 'resource_name' attribute => value ... }
因此,前面的资源声明描述了一个名为“mitchell”的用户资源,具有指定的属性。
要列出 Puppet 可用的所有默认资源类型,请输入以下命令:
puppet resource --types
我们将在本教程中介绍更多资源类型。
清单
Puppet 程序称为清单。 清单由 puppet 代码组成,它们的文件名使用 .pp
扩展名。 通过 apt 安装的 Puppet 中的默认主清单是 /etc/puppet/manifests/site.pp
。
如果您已遵循先决条件 Puppet 教程,则您已经编写了一个清单,该清单创建了一个文件并安装了 Apache。 我们还将在本教程中编写更多内容。
课程
在 Puppet 中,类是可以在其他地方的代码中调用的代码块。 使用类可以让您重用 Puppet 代码,并且可以更轻松地阅读清单。
类定义
类定义是组成类的代码所在的位置。 定义一个类使该类可用于清单中,但实际上并不评估任何东西。
以下是类 definition 的格式:
class example_class { ... code ... }
上面定义了一个名为“example_class”的类,Puppet 代码将放在花括号之间。
类声明
当在清单中调用类时会发生类声明。 类声明告诉 Puppet 评估类中的代码。 类声明有两种不同的风格:普通的和类似资源的。
当 Puppet 代码中使用 include
关键字时,会出现 普通类声明 ,如下所示:
include example_class
这将导致 Puppet 评估 example_class 中的代码。
当一个类被声明为资源时,会发生 类资源类声明 ,如下所示:
class { 'example_class': }
使用类似资源的类声明允许您指定 类参数 ,它会覆盖类属性的默认值。 如果您遵循了先决条件教程,那么当您使用 PuppetLabs Apache 模块在 host2 上安装 Apache 时,您已经使用了类似资源的类声明(“apache”类):
node 'host2' { class { 'apache': } # use apache module apache::vhost { 'example.com': # define vhost resource port => '80', docroot => '/var/www/html' } }
现在您已经了解了资源、清单和类,您将想要了解模块。
模块
模块是清单和数据(例如事实、文件和模板)的集合,它们具有特定的目录结构。 模块对于组织 Puppet 代码很有用,因为它们允许您将代码拆分为多个清单。 使用模块来组织几乎所有的 Puppet 清单被认为是最佳实践。
要将模块添加到 Puppet,请将其放在 /etc/puppet/modules
目录中。
我们将介绍编写您自己的基本模块所需的详细信息。 如果您想了解更多详细信息,请查看 PuppetLabs 模块基础知识 参考指南。
开发清单
为了演示如何编写 Puppet 清单、类和模块,我们将使用 Puppet 在 Ubuntu 上设置 LAMP 堆栈(类似于 本教程 中的设置)。 如果您以前从未设置过 LAMP 堆栈,则需要通过链接的教程来熟悉如何手动设置它。
从 LAMP 堆栈教程中,我们知道我们想要一个具有以下 资源 的 Ubuntu 14.04 服务器:
- 已安装 Apache 软件包 (apache2)
- Apache 服务 (apache2) 正在运行
- MySQL 服务器包 (mysql-server) 已安装
- MySQL 服务器服务 (mysql) 正在运行
- 已安装 PHP5 包 (php5)
- 一个测试 PHP 脚本文件 (info.php)
- 在安装软件包之前更新 apt
以下三个部分将展示使用 Puppet 实现类似结果的不同方法,一个工作的 LAMP 服务器。 第一个示例将展示如何编写一个全部在一个文件中的基本清单。 第二个示例将展示如何在第一个示例中开发的清单的基础上构建和使用类和模块。 最后,第三个示例将展示如何使用预先存在的、公开可用的模块来快速轻松地设置类似的 LAMP 堆栈。 如果您想尝试所有三个示例,出于学习目的,我们建议每次都从新的 VPS 开始(如 先决条件 中所述)。
示例 1:使用单个清单安装 LAMP
如果您以前从未编写过 Puppet 清单,那么这个示例是一个很好的起点。 清单将在 Puppet 代理节点上开发,并通过 puppet apply
执行,因此不需要代理/主设置。
您将学习如何编写将使用以下类型的资源声明的清单:
- exec:执行命令,如
apt-get
- package:通过apt安装包
- service:确保服务正在运行
- file:确保某些文件存在
创建清单
在新的 lamp-1 VPS 上,创建一个新清单:
sudo vi /etc/puppet/manifests/lamp.pp
添加以下行来声明我们刚刚确定需要的资源。 内联注释详细说明了每个资源声明:
# execute 'apt-get update' exec { 'apt-update': # exec resource named 'apt-update' command => '/usr/bin/apt-get update' # command this resource will run } # install apache2 package package { 'apache2': require => Exec['apt-update'], # require 'apt-update' before installing ensure => installed, } # ensure apache2 service is running service { 'apache2': ensure => running, } # install mysql-server package package { 'mysql-server': require => Exec['apt-update'], # require 'apt-update' before installing ensure => installed, } # ensure mysql service is running service { 'mysql': ensure => running, } # install php5 package package { 'php5': require => Exec['apt-update'], # require 'apt-update' before installing ensure => installed, } # ensure info.php file exists file { '/var/www/html/info.php': ensure => file, content => '<?php phpinfo(); ?>', # phpinfo code require => Package['apache2'], # require 'apache2' package before creating }
保存并退出。
应用清单
现在您需要使用 puppet apply
命令来执行清单。 在 lamp-1 上,运行:
sudo puppet apply --test
您将看到多行输出显示服务器状态如何变化,以匹配清单中的资源声明。 如果没有错误,您应该能够访问公共 IP 地址(或域名,如果您设置了它),并查看表明 Apache 和 PHP 正在运行的 PHP 信息页面。 您还可以验证 MySQL 是否已安装在您的服务器上(它尚未得到保护,但我们暂时不用担心)。 恭喜! 您使用 Puppet 设置了 LAMP 堆栈。
这个特定的设置并不太令人兴奋,因为我们没有利用我们的代理/主设置。 清单目前对其他代理节点不可用,并且 Puppet 不会持续检查(每 30 分钟)我们的服务器是否处于清单描述的状态。
现在我们要将我们刚刚开发的清单转换为一个模块,以便您的其他 Puppet 节点可以使用它。
示例 2:通过创建新模块安装 LAMP
现在让我们根据示例 1 中开发的 LAMP 清单创建一个基本模块。 这次我们将在 Puppet master 节点上执行此操作。 要创建模块,您必须在 Puppet 的 modules
目录中创建一个目录(其名称与您的模块名称匹配),并且该目录必须包含一个名为 manifests
的目录,并且该目录必须包含一个 [X204X ] 文件。 init.pp
文件必须只包含与模块名称匹配的 Puppet 类。
创建模块
在 Puppet master 上,为名为 lamp
的模块创建目录结构:
cd /etc/puppet/modules sudo mkdir -p lamp/manifests
现在创建并编辑模块的 init.pp
文件:
sudo vi lamp/manifests/init.pp
在此文件中,通过添加以下行为名为“lamp”的类添加一个块:
class lamp { }
复制您之前创建的 LAMP 清单的内容(或从上面的示例 1 复制它)并将其粘贴到 lamp 类块中。 在此文件中,您为“灯”类创建了类定义。 类中的代码此时不会被评估,但它可以被声明。 此外,由于它符合用于定义模块的 Puppet 约定,因此该类可以作为模块被其他清单访问。
保存并退出。
在主清单中使用模块
现在我们已经设置了一个基本的灯模块,让我们配置我们的主清单以使用它在 lamp-1 上安装 LAMP 堆栈。
在 Puppet master 上,编辑主清单:
sudo vi /etc/puppet/manifests/site.pp
假设文件为空,添加以下 node 块(将“lamp-1”替换为要安装 LAMP 的 Puppet 代理的主机名):
node default { } node 'lamp-1' { }
节点块允许您指定仅适用于某些代理节点的 Puppet 代码。 default 节点适用于没有指定节点块的每个代理节点——我们将其留空。 lamp-1 节点块将应用于您的 lamp-1 Puppet 代理节点。
在 lamp-1 节点块中,添加以下代码以使用我们刚刚创建的“灯”模块:
include lamp
现在保存并退出。
下次您的 lamp-1 Puppet 代理节点从主节点提取其配置时,它将评估主清单并应用指定 LAMP 堆栈设置的模块。 如果您想立即试用,请在 lamp-1 代理节点上运行以下命令:
sudo puppet agent --test
完成后,您将看到一个基本的 LAMP 堆栈已设置,与示例 1 完全相同。 要验证 Apache 和 PHP 是否正常工作,请在 Web 浏览器中转到 lamp-1 的公共 IP 地址:
http://lamp_1_public_IP/info.php
您应该会看到 PHP 安装的信息页面。
请注意,您可以通过在其他节点块中声明它来重用您创建的“灯”模块。 使用模块是促进 Puppet 代码重用的最佳方式,它对于以逻辑方式组织代码很有用。
现在我们将向您展示如何使用预先存在的模块来实现类似的设置。
示例 3:使用预先存在的模块安装 LAMP
在 the Puppet Forge 有一个公开可用的模块存储库,在尝试开发自己的基础架构时可能很有用。 Puppet Forge 模块可以通过内置的 puppet module
命令快速安装。 碰巧这里提供了用于安装和维护 Apache 和 MySQL 的模块。 我们将演示如何使用它们来帮助我们设置 LAMP 堆栈。
安装 Apache 和 MySQL 模块
在您的 Puppet master 上,安装 puppetlabs-apache
模块:
sudo puppet module install puppetlabs-apache
您将看到以下输出,表明模块安装正确:
Notice: Preparing to install into /etc/puppetlabs/puppet/modules ... Notice: Downloading from https://forgeapi.puppetlabs.com ... Notice: Installing -- do not interrupt ... /etc/puppet/modules └─┬ puppetlabs-apache (v1.0.1) ├── puppetlabs-concat (v1.0.0) [/etc/puppet/modules] └── puppetlabs-stdlib (v3.2.0) [/etc/puppet/modules]
另外,安装 puppetlabs-mysql
模块:
sudo puppet module install puppetlabs-mysql
现在 apache 和 mysql 模块可以使用了!
编辑主清单
现在让我们编辑我们的主清单,以便它使用新模块来安装我们的 LAMP 堆栈。
在 Puppet master 上,编辑主清单:
sudo vi /etc/puppet/manifests/site.pp
假设文件为空,添加以下节点块(如果您按照示例 2,只需删除 lamp-1 节点块的内容):
node default { } node 'lamp-1' { }
在 lamp-1 节点块中,使用类似资源的类声明来使用 apache 模块(行内注释解释每一行):
class { 'apache': # use the "apache" module default_vhost => false, # don't use the default vhost default_mods => false, # don't load default mods mpm_module => 'prefork', # use the "prefork" mpm_module } include apache::mod::php # include mod php apache::vhost { 'example.com': # create a vhost called "example.com" port => '80', # use port 80 docroot => '/var/www/html', # set the docroot to the /var/www/html }
apache 模块可以传递参数来覆盖模块的默认行为。 我们传入了一些基本设置来禁用模块创建的默认虚拟主机,并确保我们创建了一个可以使用 PHP 的虚拟主机。 有关 PuppetLabs-Apache 模块的完整文档,请查看其 自述文件 。
使用 MySQL 模块类似于使用 Apache 模块。 我们将保持简单,因为此时我们实际上并没有使用数据库。 在节点块中添加以下行:
class { 'mysql::server': root_password => 'password', }
与 Apache 模块一样,可以通过传递参数来配置 MySQL 模块(此处的完整文档.
现在让我们添加确保 info.php 被复制到正确位置的文件资源。 这一次,我们将使用 source 参数来指定要复制的文件。 在节点块中添加以下行:
file { 'info.php': # file resource name path => '/var/www/html/info.php', # destination path ensure => file, require => Class['apache'], # require apache class be used source => 'puppet:///modules/apache/info.php', # specify location of file to be copied }
此文件资源声明与之前略有不同。 主要区别在于我们指定的是 source 参数而不是 content 参数。 Source 告诉 puppet 复制一个文件,而不是简单地指定文件的内容。 指定的源 puppet:///modules/apache/info.php
被 Puppet 解释为 /etc/puppet/modules/apache/files/info.php
,因此我们必须创建源文件才能使此资源声明正常工作。
保存并退出site.pp
。
使用以下命令创建 info.php
文件:
sudo sh -c 'echo "<?php phpinfo(); ?>" > /etc/puppet/modules/apache/files/info.php'
下次您的 lamp-1 Puppet 代理节点从主节点提取其配置时,它将评估主清单并应用指定 LAMP 堆栈设置的模块。 如果您想立即试用,请在 lamp-1 代理节点上运行以下命令:
sudo puppet agent --test
完成后,您将看到一个基本的 LAMP 堆栈已设置,与示例 1 完全相同。 要验证 Apache 和 PHP 是否正常工作,请在 Web 浏览器中转到 lamp-1 的公共 IP 地址:
http://lamp_1_public_IP/info.php
您应该会看到 PHP 安装的信息页面。
结论
恭喜! 您已使用 Puppet 设置了 Ubuntu 14.04 LAMP 堆栈。
现在您已经熟悉了 Puppet 代码的基础知识,并且能够编写基本的清单和模块,您应该尝试使用 Puppet 来配置环境的其他方面。
一个好的起点是使用 Puppet 来管理您的系统用户和应用程序配置文件。 请记住,如果您使用 Puppet 管理资源,则必须对 Puppet 主服务器上的这些特定资源进行更改,否则它们将在下次代理节点执行其定期目录拉取请求时被覆盖。
祝你好运!