简介
在代理/主配置中设置Pupket之后,您可能需要一些帮助来编写Pupket清单和模块。为了有效地使用Pupket,您必须了解清单和模块是如何构造的。本教程介绍了Pupket代码基础知识,并将向您展示如何构造清单和模块,以帮助您开始使用Pupket来管理您的服务器环境。我们将展示在Ubuntu 14.04VPS上使用Puptet配置LAMP堆栈的三种不同方法。
前提条件
在开始本教程之前,您必须具有工作代理/主傀儡设置。如果您还没有,请按照以下教程操作:如何安装木偶来管理您的服务器Infrastructure.
您还需要能够创建至少一个新的VPS,作为Puppet master将管理的Puppet代理节点。
新建代理节点
创建一个名为),,并在PupputMaster上签署其证书请求。
木偶代码基础知识
在开始编写将配置我们的系统的Pupket代码之前,让我们回顾一下一些相关的Pupket术语和概念。
资源
木偶代码主要由_resource声明_组成。资源描述有关系统状态的内容,例如某个用户或文件应该存在,或者应该安装一个包。下面是一个用户资源声明的示例:
1user { 'mitchell':
2 ensure => present,
3 uid => '1000',
4 gid => '1000',
5 shell => '/bin/bash',
6 home => '/home/mitchell'
7}
资源声明的格式如下:
1resource_type { 'resource_name'
2 attribute => value
3 ...
4}
因此,前面的资源声明使用指定的属性描述了名为‘Mitchell’的用户资源。
要列出Puppet可用的所有默认资源类型,请输入以下命令:
1puppet resource --types
我们将在本教程中介绍更多的资源类型。
♪宣言
木偶节目被称为清单。清单由木偶代码组成,其文件名使用.pp
扩展名。APT安装的木偶中,默认的主清单为/etc/pluptet/Manifest/site.pp
。
如果您已经按照必备的木偶教程进行了学习,那么您已经编写了一个清单,该清单创建了一个文件并安装了Apache.在本教程中,我们还将编写更多内容。
类
在Pupet中,类是可以在其他地方的代码中调用的代码块。通过使用类,您可以重用傀儡代码,并可以更轻松地读取清单。
类定义
类定义是组成类的代码所在的位置。定义类使该类可在清单中使用,但实际上不计算任何内容。
以下是类定义 的格式:
1class example_class {
2 ...
3 code
4 ...
5}
上面定义了一个名为Example_CLASS
的类,Pupet代码位于花括号之间。
类声明
当在清单中调用类时,就会发生类声明。类声明告诉Pupket计算类中的代码。类声明有两种不同的风格:普通的和类似资源的。
当在Puppet代码中使用include
关键字时,会出现 普通类声明 ,如下所示:
1include example_class
这将导致Pupket计算_Example_CLASS_中的代码。
当类被像资源一样声明时,就会发生类资源声明 ,如下所示:
1class { 'example_class': }
使用类似资源的类声明允许您指定_CLASS PARAMETERS_,它覆盖类属性的默认值。如果您学习了必备教程,那么在使用PuppetLabs Apache模块在_Host2_上安装Apache时,您已经使用了类似资源的类声明():
1node 'host2' {
2 class { 'apache': } # use apache module
3 apache::vhost { 'example.com': # define vhost resource
4 port => '80',
5 docroot => '/var/www/html'
6 }
7}
既然您已经了解了资源、清单和类,您将希望了解模块。
模块
模块是清单和数据(如事实、文件和模板)的集合,它们具有特定的目录结构。模块对于组织Puppet代码很有用,因为它们允许您将代码拆分为多个清单。使用模块来组织几乎所有的Puppet清单被认为是最佳实践。
如果您需要添加一个模块到Puptet中,请将其放在/etc/pluptet/modes
目录下。
我们将介绍编写您自己的基本模块所需的细节。如果您想了解更多详细信息,请查看PuppetLabs模块Fundamentals参考指南]。
开发清单
为了演示如何编写Pupket清单、类和模块,我们将使用Pupppet在Ubuntu上设置LAMP堆栈(类似于This tutorial).]中的设置如果您以前从未设置过灯堆栈,则需要浏览链接的教程以熟悉如何手动设置它。
从LAMP堆栈教程中,我们知道我们需要一台具有以下资源的Ubuntu 14.04服务器:
- 安装了apache包(Apache2)
- 运行中的Apache2服务
- 安装MySQL服务器包(MySQL-SERVER)
- MySQL服务器服务(MySQL)正在运行
- 已安装PHP5包(Php5)
- 测试PHP脚本文件(info.php)
- 安装程序包前更新APT
以下三个小节将展示使用Pupppt来实现类似结果的不同方法,即一个工作的LAMP服务器。第一个示例将展示如何编写一个包含在一个文件中的基本清单。第二个示例将展示如何在第一个示例中开发的清单的基础上构建和使用类和模块。最后,第三个示例将展示如何使用预先存在的、公开可用的模块来快速、轻松地设置类似的LAMP堆栈。如果您想尝试所有这三个示例,出于学习目的,我们建议每次都从新的VPS开始(如先决条件中所述)。
示例1:安装单一清单的LAMP
如果您以前从未编写过PUPPET清单,则此示例是一个很好的起点。清单将在PUPET代理节点上开发,并通过`PUPPET APPLY‘执行,因此不需要代理/主控设置。
您将学习如何编写将使用以下类型的资源声明的清单:
- exec :执行命令,如
apt-get
- 程序包 :通过APT安装程序包
- 服务 :确保服务正在运行
- 文件 :确保某些文件存在
创建宣言
在Fresh_LAMP-1_VPS上,创建新清单:
1sudo vi /etc/puppet/manifests/lamp.pp
添加以下几行以声明我们刚刚确定需要的资源。内联注释详细说明了每个资源声明:
1# execute 'apt-get update'
2exec { 'apt-update': # exec resource named 'apt-update'
3 command => '/usr/bin/apt-get update' # command this resource will run
4}
5
6# install apache2 package
7package { 'apache2':
8 require => Exec['apt-update'], # require 'apt-update' before installing
9 ensure => installed,
10}
11
12# ensure apache2 service is running
13service { 'apache2':
14 ensure => running,
15}
16
17# install mysql-server package
18package { 'mysql-server':
19 require => Exec['apt-update'], # require 'apt-update' before installing
20 ensure => installed,
21}
22
23# ensure mysql service is running
24service { 'mysql':
25 ensure => running,
26}
27
28# install php5 package
29package { 'php5':
30 require => Exec['apt-update'], # require 'apt-update' before installing
31 ensure => installed,
32}
33
34# ensure info.php file exists
35file { '/var/www/html/info.php':
36 ensure => file,
37 content => '<?php phpinfo(); ?>', # phpinfo code
38 require => Package['apache2'], # require 'apache2' package before creating
39}
保存并退出。
应用宣言
现在,您将想要使用Pupppe Apply
命令来执行清单。ON_LAMP-1_,运行以下命令:
1sudo puppet apply --test
您将看到许多显示服务器状态如何更改的输出行,以与清单中的资源声明相匹配。如果没有错误,您应该能够访问公共IP地址(或域名,如果您设置了该地址),并查看PHP信息页面,该页面表明Apache和PHP正在工作。您还可以验证您的服务器上是否安装了MySQL(它尚未受到保护,但我们目前不会担心这一点)。恭喜你!你和木偶搭起了一组灯。
这个特定的设置并不太令人兴奋,因为我们没有利用我们的代理/主设置。该清单当前不可用于其他代理节点,并且Pupet不会持续(每隔30分钟)检查我们的服务器是否处于清单描述的状态。
现在,我们希望将我们刚刚开发的清单转换为一个模块,以便您的其他Puptle节点可以使用它。
示例2:新建模块安装LAMP
现在,让我们基于在示例1中开发的LAMP清单创建一个基本模块。这次我们将在Pupet_master_node上执行此操作。要创建模块,您必须在Pupppet的modes
目录下创建一个目录(名称与您的模块名称匹配),该目录必须包含一个名为marks
的目录,并且该目录必须包含一个init.pp
文件。init.pp
文件只能包含与模块名称匹配的Pupet类。
创建模块
在Pupet_master_上,为名为lamp
的模块创建目录结构:
1cd /etc/puppet/modules
2sudo mkdir -p lamp/manifests
现在创建并编辑模块的init.pp
文件:
1sudo vi lamp/manifests/init.pp
在该文件中,通过添加以下行,为名为LAMP
的类添加一个块:
1class lamp {
2
3}
复制您先前创建的LAMP清单的内容(或从上面的示例1中复制它),并将其粘贴到_LAMP_CLASS块中。在该文件中,您为LAMP
类创建了一个类定义。此时不会计算类IS中的代码,但可以声明它。此外,因为它遵守定义模块的Puptle约定,所以其他清单可以将此类作为模块进行访问。
保存并退出。
使用主清单中的模块
现在我们已经设置了一个基本的LAMP模块,让我们配置我们的主清单以使用它在_LAMP-1_上安装一个LAMP堆栈。
在PupteMASTER_上,编辑主清单:
1sudo vi /etc/puppet/manifests/site.pp
假设文件为空,添加以下节点块(将):
1node default { }
2
3node 'lamp-1' {
4
5}
节点块允许您指定仅应用于某些代理节点的PupPet代码。_DEFAULT_NODE适用于没有指定节点块的每个代理节点--我们将其保留为空。_LAMP-1_NODE块将应用于YOUR_LAMP-1_PUPPET代理节点。
在_LAMP-1_NODE块中,添加以下代码以使用我们刚刚创建的LAMP
模块:
1include lamp
现在保存并退出。
下一次当YOUR_LAMP-1_PUPPET代理节点从主代理节点获取其配置时,它将评估主清单并应用指定LAMP堆栈设置的模块。如果您想立即试用,请在_LAMP-1_AGENT节点上运行以下命令:
1sudo puppet agent --test
完成后,您将看到一个基本的LAMP堆栈已经建立,与示例1完全相同。要验证Apache和PHP是否正常工作,请在Web浏览器中转到_lamp-1_的公共IP地址:
1http://lamp_1_public_IP/info.php
您应该会看到有关您的PHP安装的信息页面。
请注意,您可以通过在其他节点块中声明您创建的LAMP
模块来重用它。使用模块是促进Pupket代码重用的最佳方式,并且对于以逻辑方式组织代码非常有用。
现在,我们将向您展示如何使用预先存在的模块来实现类似的设置。
示例3:安装已有模块的LAMP
在The Pupket Forge,)上有一个公共可用的模块存储库,在尝试开发您自己的基础设施时可能会很有用。木偶锻造模块可以通过内置的‘木偶模块’命令快速安装。碰巧,这里提供了用于安装和维护Apache和MySQL的模块。我们将演示如何使用它们来帮助我们设置灯堆。
安装APACHE和MySQL模块
在您的Pupppet_master_上,安装puppetLabs-apache
模块:
1sudo puppet module install puppetlabs-apache
您将看到以下输出,表明模块已正确安装:
1Notice: Preparing to install into /etc/puppetlabs/puppet/modules ...
2Notice: Downloading from https://forgeapi.puppetlabs.com ...
3Notice: Installing -- do not interrupt ...
4/etc/puppet/modules
5└─┬ puppetlabs-apache (v1.0.1)
6 ├── puppetlabs-concat (v1.0.0) [/etc/puppet/modules]
7 └── puppetlabs-stdlib (v3.2.0) [/etc/puppet/modules]
另外,安装puppetLabs-mysql
模块:
1sudo puppet module install puppetlabs-mysql
现在可以使用_apache_和_mySQL_模块了!
编辑主清单
现在,让我们编辑我们的主清单,以便它使用新模块来安装我们的LAMP堆栈。
在PupteMASTER_上,编辑主清单:
1sudo vi /etc/puppet/manifests/site.pp
假设文件为空,添加以下节点块(如果您遵循示例2,只需删除_LAMP-1_NODE块的内容):
1node default { }
2
3node 'lamp-1' {
4
5}
在_LAMP-1_NODE块中,使用类似资源的类声明来使用_APACHE_MODULE(行内注释解释每一行):
1class { 'apache': # use the "apache" module
2 default_vhost => false, # don't use the default vhost
3 default_mods => false, # don't load default mods
4 mpm_module => 'prefork', # use the "prefork" mpm_module
5 }
6 include apache::mod::php # include mod php
7 apache::vhost { 'example.com': # create a vhost called "example.com"
8 port => '80', # use port 80
9 docroot => '/var/www/html', # set the docroot to the /var/www/html
10 }
可以向_apache_模块传递覆盖模块默认行为的参数。我们传入了一些基本设置,以禁用模块创建的默认虚拟主机,并确保我们创建了一个可以使用PHP的虚拟主机。有关PuppetLabs-apache模块的完整文档,请查看其readme.
使用MySQL模块类似于使用Apache模块。我们将保持简单,因为我们实际上并没有使用数据库在这一点上。在节点块中添加以下行:
1class { 'mysql::server':
2 root_password => 'password',
3 }
与apache模块一样,可以通过传递参数来配置mySQL模块(完整文档here.
现在,让我们添加文件资源,以确保将info.php复制到正确的位置。这一次,我们将使用_SOURCE_参数来指定要复制的文件。在节点块中添加以下行:
1file { 'info.php': # file resource name
2 path => '/var/www/html/info.php', # destination path
3 ensure => file,
4 require => Class['apache'], # require apache class be used
5 source => 'puppet:///modules/apache/info.php', # specify location of file to be copied
6 }
此文件资源声明与以前略有不同。主要区别在于我们指定的是_SOURCE_PARAMETER而不是_CONTENT_PARAMETER。_SOURCE_告诉木偶复制文件,而不是简单地指定文件的内容。指定的源Pupppe:/MODULES/apache/info.php
会被Pupte解释为
/etc/plamet/MODULES/apache/Files/info.php`,所以我们必须创建源文件才能使该资源声明正常工作。
保存并退出site.pp
。
使用以下命令创建info.php
文件:
1sudo sh -c 'echo "<?php phpinfo(); ?>" > /etc/puppet/modules/apache/files/info.php'
下次您的_lamp-1_ Puppet代理节点从主节点提取其配置时,它将评估主清单并应用指定LAMP堆栈设置的模块。如果您想立即试用,请在_lamp-1_ agent节点上运行以下命令:
1sudo puppet agent --test
完成后,您将看到一个基本的LAMP堆栈已设置完毕,与示例1完全相同。要验证APACHE和PHP是否正常工作,请在Web浏览器中转到_LAMP-1_‘S公共IP地址:
1http://lamp_1_public_IP/info.php
您应该看到PHP安装的信息页面。
结论
祝贺你!您已经使用Puptet设置了一个Ubuntu 14.04灯堆。
既然您已经熟悉了Pupket代码的基础知识,并且能够编写基本的清单和模块,那么您应该尝试使用Pupket来配置您环境的其他方面。
一个好的起点是使用Pupket来管理您的系统用户和应用程序配置文件。请记住,如果您使用Pupet来管理资源,则必须对Pupet主服务器上的那些特定资源进行更改,否则它们将在代理节点下一次执行其定期目录拉入请求时被覆盖。
祝好运!