Puppet - 直播项目

为了在Puppet节点上执行应用配置和清单的实时测试,我们将使用实时工作演示.这可以直接复制和粘贴,以测试配置的工作方式.如果用户希望使用相同的代码集,则需要具有与代码片段中所示相同的命名约定,如下所示.

让我们从创建新模块开始.

创建新模块

测试和应用httpd配置的第一步是创建模块.为此,用户需要将其工作目录更改为Puppet模块目录并创建基本模块结构.结构创建可以手动完成,也可以使用Puppet为模块创建样板.

# cd /etc/puppet/modules 
# puppet module generate Live-module

注意 :  Puppet模块生成命令要求模块名称采用[用户名]  -  [模块]的格式以符合Puppet伪造规范.

新模块包含一些基本文件,包括清单目录.该目录已包含名为init.pp的清单,该清单是模块主清单文件.这是模块的空类声明.

 
 class live-module {
}

该模块还包含一个包含名为 init.pp 的清单的测试目录.此测试清单包含对manifest/init.pp中的live-module类的引用:

 
 include live-module

Puppet将使用此测试模块来测试清单.现在我们准备将配置添加到模块中.

安装HTTP服务器

Puppet模块将安装运行http服务器所需的软件包.这需要一个定义httpd包配置的资源定义.

在模块的manifest目录中,创建一个名为httpd.pp的新清单文件

 
 #touch test-module/manifests/httpd.pp

此清单将包含我们模块的所有HTTP配置.出于分离目的,我们将httpd.pp文件与init.pp清单文件分开

我们需要将以下代码放在httpd.pp清单文件中.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
}

此代码定义了一个名为httpd的测试模块的子类,然后定义了一个包资源声明. httpd包.确保=>安装属性检查是否安装了所需的软件包.如果没有安装,Puppet使用yum实用程序来安装它.接下来,将此子类包含在我们的主清单文件中.我们需要编辑init.pp清单.

class test-module { 
   include test-module::httpd 
}

现在,是时候测试模块可以按如下方式完成

 
#puppet apply test-module/tests/init.pp --noop

puppet apply命令应用清单文件中的配置目标系统.这里,我们使用测试init.pp,它引用主init.pp. -noop执行配置的空运行,它只显示输出但实际上没有做任何事情.

以下是输出.

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.59 seconds 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 1 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.67 seconds

高亮线是ensure =>的结果安装属性.缺少current_value意味着Puppet已检测到已安装httpd包.如果没有-noop选项,Puppet将安装httpd包.

运行httpd服务器

安装httpd服务器后,我们需要启动使用其他资源减速的服务:服务

我们需要编辑httpd.pp清单文件并编辑以下内容.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
   service { 'httpd': 
      ensure => running, 
      enable => true, 
      require => Package["httpd"], 
   } 
}

以下是我们从上面的代码中获得的目标列表.

  • ensure => 运行状态检查服务是否正在运行,如果没有它启用了它.

  • enable => true属性设置在系统启动时运行的服务.

  • require => Package ["httpd"] 属性定义了一个资源减速与其他资源之间的排序关系.在上面的例子中,它确保httpd服务在安装http包后启动.这会在服务和相应的包之间创建依赖关系.

运行puppet apply命令再次测试更改.

# puppet apply test-module/tests/init.pp --noop 
Notice: Compiled catalog for puppet.example.com in environment 
production in 0.56 seconds 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 2 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.41 seconds

配置httpd服务器

完成上述步骤后,我们将安装并启用HTTP服务器.下一步是为服务器提供一些配置.默认情况下,httpd在/etc/httpd/conf/httpd.conf中提供了一些默认配置,它们提供了一个webhost端口80.我们将添加一些额外的主机,为web主机提供一些特定于用户的设施.

模板将用于提供额外的端口,因为它需要一个变量输入.我们将创建一个名为template的目录,并在新的director中添加一个名为test-server.config.erb的文件,并添加以下内容.

Listen <%= @httpd_port %> 
NameVirtualHost *:<% = @httpd_port %> 

<VirtualHost *:<% = @httpd_port %>> 
   DocumentRoot /var/www/testserver/ 
   ServerName <% = @fqdn %> 
   
   <Directory "/var/www/testserver/"> 
      Options All Indexes FollowSymLinks 
      Order allow,deny 
      Allow from all 
   </Directory> 
</VirtualHost>

以上模板遵循标准的apache-tomcat服务器配置格式.唯一的区别是使用Ruby转义字符从模块中注入变量.我们有FQDN,它存储系统的完全限定域名.这被称为系统事实.

在生成每个系统的木偶目录之前,系统事实是从每个系统收集的. Puppet使用facter命令获取此信息,并且可以使用facter获取有关系统的其他详细信息.我们需要在httpd.pp清单文件中添加高亮线.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
   service { 'httpd': 
      ensure => running, 
      enable => true, 
      require => Package["httpd"], 
   } 
   file {'/etc/httpd/conf.d/testserver.conf': 
      notify => Service["httpd"], 
      ensure => file, 
      require => Package["httpd"], 
      content => template("test-module/testserver.conf.erb"), 
   } 
   file { "/var/www/myserver": 
      ensure => "directory", 
   } 
}

这有助于实现以下目的 :

  • 这会为服务器配置文件添加文件资源声明(/etc/httpd/conf.d/test-server.conf).此文件的内容是先前创建的test-serverconf.erb模板.我们还会在添加此文件之前检查已安装的httpd包.

  • 这会添加第二个文件资源声明,该声明会创建一个目录(/var/www/test-server )对于Web服务器.

  • 接下来,我们使用 notify =>添加配置文件和https服务之间的关系.服务[ "的httpd"]的属性的.这将检查是否有任何配置文件更改.如果有,则Puppet重新启动该服务.

接下来是将httpd_port包含在主清单文件中.为此,我们需要结束主init.pp清单文件并包含以下内容.

class test-module ( 
   $http_port = 80 
) { 
   include test-module::httpd 
}

这将httpd端口设置为默认值为80.接下来是运行Puppet apply命令.

以下将是输出.

# puppet apply test-module/tests/init.pp --noop 
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.84 seconds 

Notice: /Stage[main]/test-module::Httpd/File[/var/www/myserver]/ensure: 
current_value absent, should be directory (noop) 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: 
/Stage[main]/test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensure: 
current_value absent, should be file (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 4 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.51 seconds

配置防火墙

为了与服务器通信,需要一个开放端口.这里的问题是不同类型的操作系统使用不同的控制防火墙的方法.对于Linux,6以下版本使用iptables,版本7使用firewalld.

使用适当服务的决定在某种程度上由Puppet使用系统事实及其逻辑来处理.为此,我们首先需要检查操作系统,然后运行相应的防火墙命令.

为了实现这一点,我们需要在testmodule :: http类中添加以下代码片段.

if $operatingsystemmajrelease <= 6 { 
   exec { 'iptables': 
      command => "iptables -I INPUT 1 -p tcp -m multiport --ports 
      ${httpd_port} -m comment --comment 'Custom HTTP Web Host' -j ACCEPT && 
      iptables-save > /etc/sysconfig/iptables", 
      path => "/sbin", 
      refreshonly => true, 
      subscribe => Package['httpd'], 
   } 
   service { 'iptables': 
      ensure => running, 
      enable => true, 
      hasrestart => true, 
      subscribe => Exec['iptables'], 
   } 
}  elsif $operatingsystemmajrelease == 7 { 
   exec { 'firewall-cmd': 
      command => "firewall-cmd --zone=public --addport = $ { 
      httpd_port}/tcp --permanent", 
      path => "/usr/bin/", 
      refreshonly => true, 
      subscribe => Package['httpd'], 
   } 
   service { 'firewalld': 
      ensure => running, 
      enable => true, 
      hasrestart => true, 
      subscribe => Exec['firewall-cmd'], 
   } 
}

上述代码执行以下 :

  • 使用 operatingsystemmajrelease 确定使用的操作系统是版本6还是7.

  • 如果版本是6,那么它会运行所有必需的配置命令来配置Linux 6版本.

  • 如果操作系统版本为7,则它会运行配置防火墙所需的所有必需命令.

  • 操作系统的代码片段包含一个确保配置仅在安装http软件包后运行.

最后,运行Puppet apply命令.

# puppet apply test-module/tests/init.pp --noop 
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.82 seconds 

Notice: /Stage[main]/test-module::Httpd/Exec[iptables]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[iptables]: Would have 
triggered 'refresh' from 1 events

配置SELinux

由于我们正在开发版本为7及更高版本的Linux机器,因此我们需要对其进行配置以进行http通信.默认情况下,SELinux限制对HTTP服务器的非标准访问.如果我们定义一个自定义端口,那么我们需要配置SELinux以提供对该端口的访问.

Puppet包含一些资源类型来管理SELinux功能,例如布尔值和模块.在这里,我们需要执行semanage命令来管理端口设置.此工具是policycoreutils-python包的一部分,默认情况下,它不安装在red-hat服务器上.为了实现上述目标,我们需要在test-module :: http类中添加以下代码.

exec { 'semanage-port': 
   command => "semanage port -a -t http_port_t -p tcp ${httpd_port}", 
   path => "/usr/sbin", 
   require => Package['policycoreutils-python'], 
   before => Service ['httpd'], 
   subscribe => Package['httpd'], 
   refreshonly => true, 
} 

package { 'policycoreutils-python': 
   ensure => installed, 
}

以上代码执行以下 :

  • 要求=> Package ['policycoreutils-python']确保我们安装了所需的python模块.

  • Puppet使用semanage打开端口,使用httpd_port作为veriable.

  • 之前=> service确保在httpd服务启动之前执行此命令.如果HTTPD在SELinux命令之前启动,则SELinux服务请求和服务请求失败.

最后,运行Puppet apply命令

# puppet apply test-module/tests/init.pp --noop 
... 
Notice: /Stage[main]/test-module::Httpd/Package[policycoreutilspython]/ 
ensure: current_value absent, should be present (noop) 
...
Notice: /Stage[main]/test-module::Httpd/Exec[semanage-port]/returns: 
current_value notrun, should be 0 (noop) 
... 
Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop)

Puppet首先安装python模块然后配置端口访问,最后启动httpd服务.

在Web主机中复制HTML文件

通过上述步骤,我们完成了http服务器组态.现在,我们有一个平台可以安装基于Web的应用程序,Puppet也可以配置它.为了测试,我们将一些示例html索引网页复制到服务器.

在files目录中创建一个index.html文件.

<html> 
   <head> 
      <title>Congratulations</title> 
   <head> 
   
   <body> 
      <h1>Congratulations</h1> 
      <p>Your puppet module has correctly applied your configuration.</p> 
   </body> 
</html>

在清单目录中创建清单app.pp并添加以下内容.

class test-module::app { 
   file { "/var/www/test-server/index.html": 
      ensure => file, 
      mode => 755, 
      owner => root, 
      group => root, 
      source => "puppet:///modules/test-module/index.html", 
      require => Class["test-module::httpd"], 
   } 
}

这个新类包含单个资源减速.这会将文件从模块的文件目录复制到Web服务器并设置其权限. required元素确保test-module :: http类在应用test-module :: app之前成功完成配置.

最后,我们需要在主init中包含一个新的清单.pp manifest.

class test-module ( 
   $http_port = 80 
) { 
   include test-module::httpd 
   include test-module::app 
}

现在,运行apply命令实际测试是什么发生.以下是输出.

# puppet apply test-module/tests/init.pp --noopWarning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for brcelprod001.brcle.com in environment 
production in 0.66 seconds 

Notice: /Stage[main]/Test-module::Httpd/Exec[iptables]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/Test-module::Httpd/Package[policycoreutilspython]/ 
ensure: current_value absent, should be present (noop) 

Notice: /Stage[main]/Test-module::Httpd/Service[iptables]: Would have 
triggered 'refresh' from 1 events 

Notice: /Stage[main]/Test-module::Httpd/File[/var/www/myserver]/ensure: 
current_value absent, should be directory (noop) 

Notice: /Stage[main]/Test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: 
/Stage[main]/Test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensur 
e: current_value absent, should be file (noop) 

Notice: /Stage[main]/Test-module::Httpd/Exec[semanage-port]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/Test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 8 
Notice: 
/Stage[main]/test-module::App/File[/var/www/myserver/index.html]/ensur: 
current_value absent, should be file (noop) 

Notice: Class[test-module::App]: Would have triggered 'refresh' from 1 
Notice: Stage[main]: Would have triggered 'refresh' from 2 events Notice: 
Finished catalog run in 0.74 seconds

突出显示的行显示将index.html文件复制到Web主机的结果.

完成模块

通过以上所有步骤,我们创建的新模块即可使用.如果我们想要创建模块的存档,可以使用以下命令完成.

#puppet module build test-module