专栏首页使用Puppet模块创建LAMP堆栈

使用Puppet模块创建LAMP堆栈

在Puppet中,模块是服务器配置的构建块。模块安装和配置包,创建目录,并生成用户在模块中包含的任何其他服务器更改。Puppet模块旨在执行特定任务的所有部分,例如下载Apache包,配置所有文件,更改MPM数据以及设置虚拟主机。反过来,模块被分解为扩展名为.pp的类文件,这些文件旨在将模块简化为各种任务,并提高模块的可读性。

在本指南中,Apache和PHP模块将从头开始创建,MySQL模块将改编自Puppet Forge上的PuppetLab的MySQL模块。这些步骤将在您的服务器上创建一个完整的LAMP堆栈,并提供各种使用模块的方式的概述。

注意

本指南假设您使用的是Pbupet 设置指南中配置的Ubuntu 14.04 LTS Puppet master和CentOS 7和Ubuntu 14.04节点。如果使用不同的设置,请进行相应调整。

创建Apache模块

  • 从Puppet Master,导航到Puppet的模块目录并创建apache目录:
cd /etc/puppet/modules
sudo mkdir apache
  • 从内部apache目录,创建manifeststemplatesfiles,和examples目录:
cd apache
sudo mkdir {manifests,templates,files,examples}
  • 导航到manifests目录:
cd manifests

从这里开始,模块将根据特定代码段的目标分成几类。在这个例子中,将有一个init.pp类用于下载Apache包,一个params.pp用于定义任何变量和参数,config.pp文件用于管理Apache服务本身的任何配置文件,以及一个vhosts.pp用于定义虚拟主机的文件。该模块还将利用Hiera数据存储每个节点的变量。

创建Apache初始化类和参数

  • 在manifests目录中,init.pp需要创建一个类。这个类的名称应该和模块名称一致:

/etc/puppet/modules/apache/manifests/init.pp

class apache {

}

该文件将用于安装Apache包。但是,Ubuntu 14.04和CentOS 7下的Apache包名并不一样,因此,将使用变量进行处理:

/etc/puppet/modules/apache/manifests/init.pp

class apache {
    package { 'apache': 
        name    => $apachename, 
        ensure  => present,
    }
}

package资源允许管理包,用于添加,删除或确保包存在。在大多数情况下,资源的名称('apache',见上文)应为要管理的包的名称。但是,由于命名约定的不同,这个资源只是简单的命名为apache,而使用名称引用调用包的实际名称。在上面的实例中,.name调用尚未定义的变量$apachename,ensure引用则用来确保包存在。

  • 既然有变量需要定义,那么这个params.pp类就会发挥作用。虽然可以在init.pp代码中定义这些变量,但是因为有很多变量需要在资源类型本身之外使用,使用params.pp类可以在if块中定义变量并在多个类中使用。

创建并打开params.pp

/etc/puppet/modules/apache/manifests/params.pp

class apache::params { 

 }

在原始init.pp类之外,每个类名都应为apache分支。因此,这个类被称为apache::params。双冒号后面的名称应与文件名相同。

  • 现在应该定义参数。为此,我们将添加一个if块,从已经安装在Puppet master上的Facter提供的信息中提取。在本案中,Facter将用于下拉操作系统系列(osfamily),以识别它是基于Red Hat还是基于Debian。if块的骨架应类似于以下内容:

/etc/puppet/modules/apache/manifests/params.pp

class apache::params { 

      if $::osfamily == 'RedHat' { 

         } elseif $::osfamily == 'Debian' {  

         } else {  
            print "This is not a supported distro."  
       } 
}

一旦我们添加了已经引用的变量:

/etc/puppet/modules/apache/manifests/params.pp

class apache::params { 
       if $::osfamily == 'RedHat' {   
            $apachename     = 'httpd'   
       } elseif $::osfamily == 'Debian' { 
            $apachename     = 'apache2'   
       } else { 
            print "This is not a supported distro."  
       } 
}

注意

在本指南的持续时间内,当需要将某些内容添加到参数列表中时,将提供Red Hat和Debian所需的变量,但不会显示扩展代码。可在此处查看params.pp的完整副本。

  • 随着参数的定义完成,我们需要将params.pp文件和参数引入到init.pp。要做到这一点,需要在类名之后、花括号({)之前添加参数:

/etc/puppet/modules/apache/manifests/init.pp

class apache (
    $apachename   = $::apache::params::apachename, 
    ) inherits ::apache::params {

值字符串$::apache::params::value告诉Puppet从apache模块的params类中提取值,然后是参数名称。该片段inherits ::apache::params允许init.pp继承这些值。

管理配置文件

Apache有两个不同的配置文件,取决于您是在使用基于Red Hat还是基于Debian的系统。这些文件可以从服务器中拉取,或者在这里查看:httpd.conf(Red Hat)apache2.conf(Debian)

  • httpd.confapache2.conf文件复制到files目录。位于/etc/puppet/modules/apache/files/
  • 需要编辑这两个文件将KeepAlive设置设置为Off。需要在httpd.conf文件中添加此设置,否则,应将以下注释添加到每个文件的顶部:

/etc/puppet/modules/apache/files/httpd.conf

# This file is managed by Puppet
  • 现在需要将这些文件添加到init.pp文件中,使Puppet知道它们在主服务器和代理节点上的位置。为此,使用file资源:

/etc/puppet/modules/apache/manifests/init.pp

file { 'configuration-file':
    path    => $conffile, 
    ensure  => file,  
    source  => $confsource, 
    }

由于配置文件位于两个不同的位置,因此将为资源指定通用名称configuration-file,并将文件路径定义为具有该path属性的参数。ensure确保它是一个文件。source是另一个参数,它将调用上面创建的主文件位于Puppet master上的位置。

  • 打开params.pp文件。$conffile$confsource变量需要在if语句块中定义:

/etc/puppet/modules/apache/manifests/params.pp

if $::osfamily == 'RedHat' { 

     ...   

        $conffile     = '/etc/httpd/conf/httpd.conf' 
        $confsource   = 'puppet:///modules/apache/httpd.conf' 
    } elsif $::osfamily == 'Debian' {
          
    ...

        $conffile     = '/etc/apache2/apache2.conf'   
        $confsource   = 'puppet:///modules/apache/apache2.conf' 
    } else {

        ...

根据附加参数的示例,还需要将这些参数添加到init.pp文件中。init.pp文件的完整副本可在此处查看

  • 更改配置文件后,Apache需要重新启动。要自动执行此操作,可以结合notify属性使用service资源,只要配置文件发生更改,就会调用该资源:

/etc/puppet/modules/apache/manifests/init.pp

file { 'configuration-file':   
    path    => $conffile,   
    ensure  => file,   
    source  => $confsource,   
    notify  => Service['apache-service'], 
    }  
service { 'apache-service':   
    name          => $apachename,   
    hasrestart    => true, 
    }

service资源使用已创建的参数,该参数在Red Hat和Debian系统上定义了Apache名称。hasrestart属性将触发已定义服务的重新启动。

创建虚拟主机文件

虚拟主机文件将以不同方式进行管理,具体取决于服务器是基于Red Hat还是Debian发行版。因此,虚拟主机的代码将被包含在if语句块中,类似于params.pp类中使用的语句,但包含实际的Puppet资源。下面将提供在Puppet代码中使用if语句块的示例。

  • apache/manifests/目录中,创建并打开vhosts.pp文件。
  • 创建if语句块的框架:

/etc/puppet/modules/apache/manifests/vhosts.pp

class apache::vhosts {
    if $::osfamily == 'RedHat' {

     } elsif $::osfamily == 'Debian' {    

     } else {    

     }  

}
  • 在CentOS 7服务器上的虚拟主机文件的位置是/etc/httpd/conf.d/vhost.conf。此文件需要在Puppet master上创建为模板。对于Ubuntu服务器,需要做同样的事情,该文件位于/etc/apache2/sites-available/example.com.conf,使用服务器的FQDN替换example.com。还需要在Puppet主服务器上创建此文件的模板。导航到apache模块中的templates文件夹,然后为虚拟主机创建两个文件:

对于Red Hat系统:

/etc/puppet/modules/apache/templates/vhosts-rh.conf.erb

<VirtualHost \*:80>     
    ServerAdmin	<%= @adminemail %>     
    ServerName <%= @servername %>     
    ServerAlias www.<%= @servername %>     
    DocumentRoot /var/www/<%= @servername -%>/public\_html/     
    ErrorLog /var/www/<%- @servername -%>/logs/error.log     
    CustomLog /var/www/<%= @servername -%>/logs/access.log combined 
</Virtual Host>

对于Debian系统:

/etc/puppet/modules/apache/templates/vhosts-deb.conf.erb

<VirtualHost *:80>
    ServerAdmin	<%= @adminemail %>
    ServerName <%= @servername %>
    ServerAlias www.<%= @servername %>
    DocumentRoot /var/www/html/<%= @servername -%>/public_html/
    ErrorLog /var/www/html/<%- @servername -%>/logs/error.log
    CustomLog /var/www/html/<%= @servername -%>/logs/access.log combined
    <Directory /var/www/html/<%= @servername -%>/public_html>
        Require all granted
    </Directory>
</Virtual Host>

在这些文件中使用了两个变量:adminemailservername。这些变量将在每个节点的site.pp文件中进行定义。

  • 回到vhosts.pp文件,现在可以在代码中引用创建的模板: /etc/puppet/modules/apache/manifests/vhosts.pp
class apache::vhosts {

  if $::osfamily == 'RedHat' {
    file { '/etc/httpd/conf.d/vhost.conf':
      ensure    => file,
      content   => template('apache/vhosts-rh.conf.erb'),
    }
  } elsif $::osfamily == 'Debian' {
    file { "/etc/apache2/sites-available/$servername.conf":
      ensure  => file,
      content  => template('apache/vhosts-deb.conf.erb'),
    }
  } else {
    print "This is not a supported distro."
  }

}

两个分发系列都调用file资源并在相应的分发上获取虚拟主机位置的标题。对于Debian,这再次意味着引用$servername值。content属性调用相应的模板。

注意

变量(例如上面的Debian文件资源的名称)需要用双引号括起来(")。单引号(')中的任何变量都完全按照写入进行解析,不会引入变量。

  • 默认情况下,两个虚拟主机文件都引用两个不在分发中的目录。这些目录可以通过使用file资源创建,每个资源都位于if语句块中。完整的vhosts.conf文件应该类似于: /etc/puppet/modules/apache/manifests/vhosts.pp
class apache::vhosts {

  if $::osfamily == 'RedHat' {
    file { '/etc/httpd/conf.d/vhost.conf':
      ensure    => file,
      content   => template('apache/vhosts-rh.conf.erb'),
    }
    file { "/var/www/$servername":
      ensure    => directory,
    }
    file { "/var/www/$servername/public_html":
      ensure    => directory,
    }
    file { "/var/www/$servername/log":
    ensure    => directory,
    }

  } elsif $::osfamily == 'Debian' {
    file { "/etc/apache2/sites-available/$servername.conf":
      ensure  => file,
      content  => template('apache/vhosts-deb.conf.erb'),
    }
    file { "/var/www/$servername":
      ensure    => directory,
    }
    file { "/var/www/html/$servername/public_html":
      ensure    => directory,
    }
    file { "/var/www/html/$servername/logs":
      ensure    => directory,
    }
  } else {
    print "This is not a supported distro."
  }

}

测试和运行模块

  • 定位到apache/manifests/目录,运行puppet parser验证所有文件,以确保Puppet编码正确:
sudo puppet parser validate init.pp params.pp vhosts.pp

返回结果应该为空,除非出现任何问题。

  • 导航到apache模块中的examples目录。创建一个init.pp文件并包含创建的类。为servername和提供变量adminemail/etc/puppet/modules/apache/examples/init.pp
$serveremail = 'webmaster@example.com'
$servername = 'example.com'

include apache
include apache::vhosts
  • 执行puppet apply并附加--noop标记来测试模块:
sudo puppet apply --noop init.pp

它应该不返回任何错误,并且会响应事件更新输出。如果需要在Puppet主服务器上安装和配置apache,可以不带--noop标签再次运行puppet apply

  • 导航回Puppet主目录,然后导航到manifests文件夹(不是位于Apache模块中的文件夹)。如果您从Puppet设置指南继续本指南,则应该已经创建了一个名为site.pp的文件。如果没有,请立即创建一个。node 'ubuntuhost.example.com' { $adminemail = 'webmaster@example.com' $servername = 'hostname.example.com' include accounts include apache include apache::vhosts resources { 'firewall': purge => true, } Firewall { before => Class['firewall::post'], require => Class['firewall::pre'], } class { ['firewall::pre', 'firewall::post']: } } node 'centoshost.example.com' { $adminemail = 'webmaster@example.com' $servername = 'hostname.example.com' include accounts include apache include apache::vhosts resources { 'firewall': purge => true, } Firewall { before => Class['firewall::post'], require => Class['firewall::pre'], } class { ['firewall::pre', 'firewall::post']: } }
  • 打开site.pp并为每个代理节点添加Apache模块。并输入adminemailservername参数的变量。如果您遵循Puppet设置指南,其中的单个节点配置site.pp将类似于以下内容: /etc/puppet/manifests/site.pp
  • 要在代理节点上运行新模块,请登录节点并运行:
sudo puppet agent -t

使用MySQL模块

许多运行服务器所需的模块已经存在于Puppet Lab的Puppet Forge中。这使得你可以像创建的模块一样进行广泛地配置这些组件,并且可以节省时间,因为无需从头开始创建模块。

通过PuppetLabs 安装Puppet Forge的MySQL模块

sudo puppet module install puppetlabs-mysql

这也将安装任何必备模块。

使用Hiera创建数据库

在开始为MySQL模块创建配置文件之前,考虑到您可能不希望在所有代理节点上使用相同的值,使用Hiera,Pupper支持为每个节点提供正确的数据。在本实例中,您将为每个节点提供不同的root密码,从而创建不同的MySQL数据库。

  • 导航到主目录/etc/puppet并创建Hiera的配置文件:hiera.yamlpuppet

/etc/puppet/hiera.yaml

:backends:
  - yaml
:yaml:
  :datadir: /etc/puppet/hieradata
:hierarchy:
  - "nodes/%{::fqdn}"
  - common

:backends:下面的值定义您正在YAML中写入数据,而:datadir:调用Hiera存储数据的目录。:hierarchy:部分表示您的数据将保存在node目录下的文件中,文件以节点的FQDN命名。一个common文件将包含默认的变量。

  • 确保在/etc/puppet/目录中,为hieradatanodes创建目录:
sudo mkdir -p hieradata/nodes
  • 导航到nodes目录:
cd hieradata/nodes
  • 使用该puppet cert命令列出可用的节点,然后使用FQDN作为文件名称为每个节点创建YAML文件:
sudo puppet cert list --all 
sudo touch {ubuntuhost.example.com.yaml,centoshost.example.com.yaml}
  • 打开第一个节点的配置文件以定义第一个数据库。在此示例中,数据库名为webdata1,自定义usernamepassword。该grant值授予用户对webdata1数据库的所有访问权限: /etc/puppet/hieradata/nodes/ubuntuhost.example.com.yaml
databases:
  webdata1:
   user: 'username'
   password: 'password'
   grant: 'ALL'

重复第二个服务器。在此示例中,数据库名为webdata2

/etc/puppet/hieradata/nodes/centoshost.example.com.yaml

databases:
  webdata2:
   user: 'username'
   password: 'password'
   grant: 'ALL'

保存并关闭文件。

  • 返回hieradata目录并创建文件common.yaml。它将用于定义root用户的默认密码: /etc/puppet/hieradata/common.yamlmysql::server::root\_password: 'password'如果未在其他位置定义变量,则使用common.yaml文件。这意味着所有服务器将共享相同的MySQL root密码。这些密码也可以进行哈希处理以提高安全性。class mysql::database { include mysql::server create_resources('mysql::db', hiera_hash('databases')) }
  • Puppet现在需要知道使用Hiera中的信息输入来创建定义的数据库。移动到mysql模块目录并在manifests目录创建database.pp文件。在这里,您将定义一个将mysql::db资源链接到Hiera数据的类。它也会调用mysql::server类,因此不必在以后包含它: /etc/puppet/modules/mysql/manifests/database.pp
  • 在您的site.pp文件中两个节点包含include mysql::database

创建PHP模块

  • 创建php目录modules路径,随后创建filesmanifeststemplates,和examples子文件夹:
sudo mkdir php 
cd php 
sudo mkdir {files,manifests,examples,templates}
  • 创建并打开init.pp。因为所有要做的就是PHP服务正确安装,并且能够在启动时启动,所有代码都将包含在此文件中。class php { package { 'php': name: $phpname, ensure: present, } package { 'php-pear': ensure: present, } }因为php程序包在Ubuntu和CentOS上具有不同的名称,所以它将再次需要使用参数进行定义。但是,因为这是我们需要的唯一参数,所以它将直接添加到init.pp文件中: /etc/puppet/modules/php/manifests/init.pp
  • 将安装两个软件包:PHP软件包和PHP扩展和应用程序库。使用此package资源: /etc/puppet/modules/php/manifests/init.pp
class php {

  $phpname = $osfamily ? {
    'Debian'    => 'php5',
    'RedHat'    => 'php',
    default     => warning('This distribution is not supported by the PHP module'),
  }

  package { 'php':
    name    => $phpname,
    ensure  => present,
  }

  package { 'php-pear':
    ensure  => present,
  }

}
  • 使用该service资源确保PHP已启用并设置为开机启动: /etc/puppet/modules/php/manifests/init.ppclass php { $phpname = $osfamily ? { 'Debian' => 'php5', 'RedHat' => 'php', default => warning('This distribution is not supported by the PHP module'), } package { 'php': name => $phpname, ensure => present, } package { 'php-pear': ensure => present, } service { 'php-service': name => $phpname, ensure => running, enable => true, } }
  • 添加include phpsites.pp文件中的主机中,并在代理节点上运行puppet agent -t,以便对服务器进行任何更改。

本文的版权归 用户1196457 所有,如需转载请联系作者。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在Ubuntu 16.04上安装Odoo 11堆栈

    Odoo(以前称为OpenERP)是一个由10,000多个开源应用程序组成的自托管套件,可满足各种业务需求,包括CRM,电子商务,会计,库存,销售点和项目管理。...

    用户1196457
  • 一些比非常不安全的密码认证更安全的认证方式

    密码是全球用户认证的最常见方式,其使用率在过去的十多年来一直在缓慢下降。比尔盖茨在2004年的RSA会议上声称,“毫无疑问,随着时间的推移,人们对密码的依赖会越...

    用户1196457
  • 在CentOS 7上使用WildFly进行Java开发

    JBoss AS(重命名为WildFly)已被使用多年,是最有名的高效和免费的Java社区应用服务器之一。当Red Hat开始为其企业版JBoss EAP的对内...

    用户1196457
  • C++读取配置文件

    https://github.com/gongluck/Code-snippet/tree/master/cpp/config

    gongluck
  • Linux 抓取网页实例(shell+awk)

    上一篇博客讲了Linux抓取网页的方式,有curl和wget两种方式,这篇将重点讲Linux抓取网页的实例——抓取google play全球12国的游戏TOP排...

    阳光岛主
  • 4.网络编程

    六月的雨
  • 【CV中的特征金字塔】一,工程价值极大的ASFF

    今天为大家介绍一下2019年的一篇论文 《Learning Spatial Fusion for Single-Shot Object Detection》,这...

    BBuf
  • H5录制视频、音频(WebRTC)

    使用Navigator.getUserMedia可以做到在主流浏览器中获取用户摄像头数据,麦克风数据,我研究了一下,发现在ios、安卓微信浏览器中都不行。而在安...

    黒之染
  • Dart In Action -Dart快速入门(五)

    本文基本上是将dart官网部分内容进行翻译,没兴趣的请出门左转至Dart的官网,有兴趣的同志请继续阅读本文。

    JarvanMo
  • Dart In Action -Dart快速入门(五)

    本文基本上是将dart官网部分内容进行翻译,没兴趣的请出门左转至Dart的官网,有兴趣的同志请继续阅读本文。 Flutter教程在这里

    JarvanMo

扫码关注云+社区

领取腾讯云代金券