puppet 基础应用详解

运维自动化
html


   运维自动化是指将IT运维中平常的、大量的重复性工做自动化,把过去的手工执行转换为自动化操做,自动化是运维工做的生化,运维自动化不单纯是一个维护过程,更是一个管理的提高过程,是IT运维的最高层次,也是将来的发展趋势linux


   虽然没法作到彻底自动化运维,可是咱们应该努力尽可能的大部分的实现自动化运维;  nginx


自动化运维的层次结构web


   一、第一层-------引导层 Bootstrap正则表达式

   二、第二层-------配置层 Configurationshell

   三、第三层-------命令集控制层 Command and Control
apache


   如图所示:各层及其实现程序编程


wKioL1N3KgrzpQpKAAIrkuSIo0U246.jpg


Puppet简介ubuntu


    由上图可知,Puppet使用在自动化运维的第二层,也就是Configuration配置层。vim

    Puppet是一个IT基础设施自动化管理工具,它可以帮助管理员管理基础设施的整个生命周期:供应(provisioning)、配置(configration)、联动(orchestration)及报告(reporting)

经过使用puppet,能够实现自动化重复任务、快速部署关键性应用以及在本地或者云端完成主动管理变动和快速扩展架构规模等。

    Puppet基于ruby语言开发,它对于管理员来说是抽象的,只依赖于ruby与facter。其自己可以管理多达40多种资源,例如:file、user、group、package、service、host、cron、exec、yum repo等,适合整个生命周期;

    总结:Puppet 就是集中式的配置管理工具,经过自有配置语言对节点进行目标状态的定义,并可以基于网络实现目标状态的维护。


Mater/agent架构及工做流程


     Puppet是基于master/agent的架构

             master:中心配置库

             agent : 读取并应用配置的节点


     工做流程


wKioL1N3LXCgYepbAAEOKwFJBcw799.jpg


如上图:
agent节点发送本身的事实或者其状态的数据给master服务器;
master服务器根据agent的目标状态编译成Catalog伪代码,除此之外还将如何在节点上进行配置的相关数据和Catalog一并发送给angent端;
agent端,根据master发送的Catalog和配置数据,先于当前状态进行比较,而后进行状态的改变(或者单单进行模拟配置),并将改变结果数据发送给Master;
master端并将报告彻底无障碍的经过开放API,发送给第三方工具;



Puppet术语


一、 manifest(清单)


      puppet的程序文件称做“manifest(清单)”,以.pp做为文件名后缀;

      如前所述,puppet语言的核心是“资源定义”,而定义一个资源的核心就在于描述其目标状态,而nanifest文件就是用来定义resource资源的


      “puppet apply”子命令可以将一个manifest中描述的目标状态强制实现,所以它一般以manifest文件做为参数


二、catalog(伪代码)


      puppet经过manifest同步资源时,不会直接应用manifest文件,而是要通过预先的编译过程,这是由于manifest文件中可能会包含条件判断、变量、函数以及其余的程序逻辑,实际执行中,有可能会基于层次及包含关系存在多个manifest文件,这些文件会被编译仅同一个称做“catalog”的文件,编译完成后的catalog文件仅包含各个资源以及它们同步时的次序;


三、resource (资源)


      若是把OS的全部配置,如用户帐户、特定的文件、文件所属的目录、运行的服务、程序包以及cron任务等,看做是许多独立原子单元的集合的化,这些所谓的“单元”就是“资源”;不过这些资源在其大小、复杂程度以及生命周期的跨度上等多个维度上可能会各不相同

      一般来讲,类属于同一种资源的属性是相近的,如文件都有其属主和属组,而用户账号则由用户名、UID、GID等组成;不过即使是同一种资源,其在不一样OS 上的实现方式却又可能各不相同,例如在windows上和linux上启动和中止服务的方式相去甚远,,所以puppet必须对资源进行某种程度的抽象;

     资源抽象:puppet在如下三个维度来对资源完成抽象

     1)类似的资源被抽象成同一种资源“类型”,如程序包资源、用户资源及服务资源等;

     2)将资源属性或状态的描述与其实现方式玻璃开来,如仅说明安装一个程序包而不用关心其具体是经过yum、pkgadd、prots或是其余方式实现;

     3)仅描述资源的目标状态,也即指望其实现的结果,而不是其具体过程,如“肯定nginx运行起来”而不是具体描述为“运行nginx命令将其启动起来”;

    这三个也被称做puppet的资源抽象层(RAL),RAL由type(类型)和provider(提供者,即不一样OS上特定实现)组成


四、resource declaration (资源申报)


      在为puppet定义一个资源时,须要为其指定所述的类型和资源标题,并同时配置一系列的属性和对应的值。puppet经过特有的语言来描述和管理资源

      这种语法被成为“资源申报(resource declaration)”,它是puppet语言的核心组成部分,在定义中,仅描述了资源的目标状态而没有提到为达到目标所须要采起的任何步骤

     type { 'title':

         attribute => value,

      }

     puppet有许多内置的资源类型,而经过安装插件还能够继续新增额外的类型

     能够经过官网参考页面http://docs.puppetlabs.com/references/latest.html获取详情,也可使用“puppet describe”命令来获取puppet当前所能支持的类型列表及每种类型的详细信息;






puppet安装


     puppet的安装有三种方式

        一、gem安装(相似于perl中的cpan)

        二、源包下载 http://yum.puppetlabs.com/el/

https://yum.puppetlabs.com/el/6.5/products/x86_64/

         三、yum安装,须要配置好epel源


puppet资源介绍



# yum  -y install puppet 使用yum的方式安装puppet,版本为2.7

      puppet describe -l  列出全部资源


      其中咱们重点学习notify、package、user、group、file、exec、cron、service


一、package

         puppet支持使用的软件包管理器:yum,rpm,apt,ports,gem,msi,dpkg,pkg。。。

         package的经常使用参数

            ensure:程序包的目标状态;

            name  :资源的名称,即软件包的名称

            provider:软件包管理器

            source  :指定程序包文件路径

           install_option :安装选项,最经常使用的是经过IINSTALLDIR来指定安装目录          


# rpm -q nginx
package nginx is not installed
# vim nginx.pp
  package {'nginx':
       ensure => present,
 }
# puppet apply nginx.pp
# rpm -q nginx
nginx-1.0.15-5.el6.x86_64



二、service

     经常使用参数

         ensure:服务的目标状态,true(running)和false(stoppd)

         enbale:是否开机自动启动,true和false

         name  :服务名称

         path  :服务脚本路径

         start :启动命令

         stop  :关闭命令

         restart:重启命令

         status :状态命令


# vim  test.pp
service {'httpd':
        ensure => true,
        enable => true,
        name   => 'httpd',
}
# puppet apply test.pp
notice: /Stage[main]//Service[httpd]/ensure: ensure changed 'stopped' to 'running'
notice: Finished catalog run in 0.74 seconds
# service httpd status
httpd (pid  18326) 正在运行...
# chkconfig --list httpd
0:off   1:off   2:on    3:on    4:on    5:on    6:off


三、user :管理用户


        经常使用属性

           ensure:目标状态 present或absent

           name  :用户名

           uid   : 用户ID

           system: 系统用户

           home  : 指定家目录

           shell : 默认shell

           gid   : 基本组ID

           password:用户密码

           managehome:是否建立家目录,默认为false



# vim  test.pp
user {'zxj':
  ensure => present,
  gid    => 1001,
  uid    => 1001,
  home   => '/home/zxj',
  shell  => '/bin/tcsh',
  managehome => true,
  password => 123456,
}
# puppet apply test.pp
# tail /etc/passwd | grep zxj
zxj:x:1001:500::/home/zxj:/bin/tcsh


     ###注意password最好使用openssl passwd -1 -salt `openssl rand -hex 4`生成密码串


四、 cron

         管理定义周期性任务

         经常使用属性:

            ensure:目标状态  present,absent

            command:命令或脚本

            environment:运行时的环境变量

            hour       :时

            minute     :分

            month      :月

            monthday   :日

            weekday    :周

            name       :名称

            user       :用户



# vim  test1.pp
cron {'ntpdate':
     ensure => present,
     command => '/usr/sbin/ntpdate time.windows.com &> /dev/null',
     minute => '*/3',
}
# puppet apply test1.pp
# crontab -l
*/3 * * * * /usr/sbin/ntpdate time.windows.com &> /dev/null


五、group

      管理系统上的组

      经常使用参数

      ensure:目标状态,present,absent

      name  :组名

      gid   : GID

      system :系统组


# vim  test2.pp
group { 'zxj':
     ensure => present,
     name   => zxj,
     gid    => 1001,
}
# puppet apply test2.pp
# tail /etc/group | grep zxj
zxj:x:1001:


六、exec

       执行命令,一般在不得不用时才使用,慎用,一般用于完成puppet自身没法完成的功能

       经常使用参数

       command:要执行的命令,一般为命令的完整路径

       path : 命令搜索路径

       group:执行命令的组

       user : 执行命令的用户

       onlyif:0,表示仅在命令的状态返回值为0时才执行此命令

       refresh:定义接受的其余资源的通知时,则须要从新执行此命令

       refreshonly:仅当被依赖的额资源发生改变时才被触发

       tries:尝试次数,默认为1

       try_sleep :屡次尝试之间的时间间隔


# vim  test3.pp
exec {'mkdir':
     command =>'mkdir /tmp/test',
     path    =>'/bin:/sbin:/usr/bin:/usr/sbin',
}
# puppet apply test3.pp
# ls -l /tmp/
total 4
drwxr-xr-x 2 root root 4096 Apr  7 06:56 test


七、file

        管理文件、目录、软连接;生成文件内容;管理文件权限属性;也能够经过source属性到指定位置下载文件;经过recurse属性来获取目录。

        经常使用参数

        backup:经过filebacket资源来备份文件,值一般为filebacket资源的名称

        content:文件内容,生成方式有三种(content,source,target)三者彼此互斥

        source :经过指定的ur下载文件至本地,获取文件格式为

                puppet:///modules/MODULE_NAME/file_names

        target : 为符号连接指定目标

        links  :文件为符号连接,值为“follow”,“manage”

        path  :文件路径,必须使用双引号

        mode  :定义权限,一般为8进制数字

        owner :定义文件的属主

        group :定义文件的属组

        force :强制执行删除文件、连接或目录,仅用于ensure为absent时

        purge :清除指定目录存在的,但未在资源中定义的文件

        resurce:目录递归,值为true,false,inf,remote

        replace:替换,本地存在的文件与资源中指定的文件内容不一样时是否执行替换,默认为否


# vim  test4.pp
file {'fstab.link':
     ensure => present,
     target => '/etc/fstab',
     links  => 'follow',
     path   => "/tmp/fstab.link"
}
# puppet apply test4.pp
notice: /Stage[main]//File[fstab.link]/ensure: created
notice: Finished catalog run in 0.02 seconds
# ls -l /tmp
-rw-r--r-- 1 root root    0 Apr  7 07:07 fstab.link


八、notify

     调试输出

     经常使用参数

       message: 信息

       name   : 信息名称


资源引用


     Type['title]


         例如 Package['nginx']

     注意:资源类型首字母必定要大写


元参数metaparams

      用于定义资源间的依赖关系,及应用次序;通知机制    

      特殊属性

1)require (须要依赖于某资源)



service {'nginx':
        ensure  =>true,
        enable  =>true,
        name    =>name,
        require =>Package['nginx'],
}
package {'nginx':
         ensure =>present,
         name   =>nginx,
}
###nginx服务,依赖于nginx安装包先安装完毕。


2)before  (在哪一个资源以前)


service {'nginx':
        ensure  =>true,
        enable  =>true,
        name    =>nginx,
}
package {'nginx':
        ensure  =>present,
        name    =>nginx,
        before  =>Service['nginx'],
}
####nginx的安装包在nginx服务启动以前安装


3)notify (通知某资源)



file {'/tmp/test1.txt':
      ensure  =>file,
      content =>"hello puppet",
      notify  => Exec['monitor'],
}
exec {'monitor':
       command =>'echo "/tmp/test1.txt changed." >> /tmp/monitor.txt',
       refreshonly =>true,
       path    => '/bin:/sbin:/usr/bin:/usr/sbin',
}


4)subscribe 订阅 (订阅某资源,即在某资源存在或者改变后再订阅)



service  {'nginx':
         ensure   =>true,
         enable   =>true,
         name     =>nginx,
         subscribe =>Package['nginx'],
}
package  {'nginx':
         ensure   =>present,
         name     =>nginx,
}


5)当资源出现链状关系时如何处理


package {'nginx',
         ensure =>present,
} ->
service {'nginx',
         ensure => ture,
         enable => ture,
}
->表示后边的资源依赖于当前的资源


   其中还有一个~> 表示前资源发生改变后通知后边的资源


puppet的变量


   puppet的变量名称以"$"开头,赋值操做符为"=",应合变量值为"" ,或者什么都不写


   一、puppet的变量能够接受的数据类型

        ###puppet语言支持多种数据类型以及用于变量和属性的值,以及函数的参数

      1)字符型

         非结构化的文本字符串,可使用引号,也能够不用;

         单引号中的变量不会替换,而双引号中的可以进行变量替换;

         字符型值也支持使用转衣符;

      2)数值型

         可为整数或浮点数,不过puppet只有在数值上下文才把数值当数值型对待

         其余状况下一概以字符型处理


      3)数组

         数组值为中括号"[]"中的逗号分隔的项目列表,最后一个项目后边能够有逗号;

         数组中的元素能够为任意可用数据类型,包括hash或其余数组;

         数组索引为从0开始的证书,也可使用负数索引;


      4)布尔型

         true和false ,不能加引号;

         if语句的测试条件和比较表达式都会返回布尔型值;

         另外,其余数据类型也能够自动转换为布尔型,如空字符串为false等;


      5)undef

          从未被生命的变量的值类型即为undef;

          也可手动为某变量赋予undef值,即直接使用不加引号的undef字符串;


      6)hash

       即为外键值数据类型,键和值之间使用"=>"分隔,键值对儿定义在"{}",彼此间以逗号分隔;

       其键为字符型数据,而值能够为puppet 支持的任意数据类型;

       访问hash类型的数据元素要使用"键"看成索引进行


    二、puppet的变量类型

       1)自定义变量

       2)facter变量

        #facter -p 能够列出全部的faceter变量

       3)内置变量


         agent: $environment,$clientcert,$clinetversion

         master:$serverip, $servername,$serverversion

    三、正则表达式

       属于puppet的非标准数据类型,不能赋值给变量,仅能用于有限的几个接受正则表达式的地方,即接受使用"=~" 及"!~"匹配操做符的位置,一般包括case语句中的selector,以及节点名称匹配的位置;它们不能传递给函数或用于资源属性的定义;


      puppet中的正则表达式支持使用(?<ENABLED OPTION>:<SUBPATTERN>)和(?-《DISABLED OPTION>:<SUBPATTERN>)两个特殊的符号


      例以下面的示例表示作正则表达式匹配时启用选项"i"(忽略字符大小写),但不支持使用"m"(把.看成换行符)和"x"(忽略模式中的空白字符和注释)



$package = $opratingsystem ? {
    /(?i-mx:ubuntu|debian)/    => 'apache2',
    /(?i-mx:centos|fedora|redhat)/ => 'httpd',
}




puppet表达式



Comparison Oprators
   == (equality)
   != (non-equality)
   <  (less than)
   >  (greater than)
   <= (less than or equal to)
   >= (greater than or equal to)
   =~  (regex match)
   !~  (regex non-match)
   in
Boolean Operators
   and
   or
   !(not)
Arithmetic Operators
   + (addintion)
   - (subtraction)
   / (division)
   *  (multiplication)
   << (left shift)
   >> (right shift )





puppet条件判断


一、if


if  statement  ----if  语句
单分支:
    if CONDITION {
        statment
        ...
     }
双分支
    if CONDITION  {
       statment
       ...
    }
    else {
       statment
       ...
    }
多分支
    if  CONDITION  {
       statment
       ...
    }
    elsif CONDITION {
       statment
       ...
    }
    else {
       statment
       ...
    }


    例1


if  $opratingsystem =~ /^(?i-mx:(centos|redhat|fedora))/ {
     notice ("Welcome to $1 linux")
}

    例2


if $operatingsystem  == 'centos' {
       notify {'centos':message => "Welcome to CentOS linux",}
}elsif $operatingsystem == 'RedHat' {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
       notify {'redhat': message=> "Welcome to RedHat linux",}
}elsif $operatingsystem == 'Fedora' {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
       notify {'fedora': message=> "Welcome to Fedora linux",}
}else {
       notify {'unknown': message => "Unknown Opreating System",}
}


二、case语句



case $operatingsystem {
 'Solaris':   {notice("Welcome to Solaris")}
 'RedHat','CentOS': {notice ("Welcome to RedHat OSFamily")}
  default:     {notice("Welcome,alien*_*")}
}


三、selectors语句



语法格式
CONTROL_VARIABLE ? {
  case1 => value1
  case2 => value2
  ...
  default => valueN
}


   例


$webserver = $operatingsystem ? {
    /^(?i-mx:centos|fedora|redhat)/ => 'httpd/,
    /^(?i-mx:ubuntu|debian)/        => 'apache2',
}
$webprovider = $operatingsystem ? {
    /^(?i-mx:cenotos|fedora|redhat)/ => 'yum',
    /^(?i-mx:ubuntu|debian)/         => 'apt',
}
package {"$webserver":
        ensure => present,
        provider => $webprovider,
}


puppet中的类


   Classl是用于通用目标或目的一组资源,所以它是命令的代码块,在某位置建立以后能够在puppet全局使用。相似于其余编程语言中的类的功能,puppet的类可继承,也能够包含子类,定义类的语法

   class my_class {

         ...puppet code ...

   }


   例如:定义一个名叫nginx的类,其中包含两个类资源,一个是package类型的nginx,一个是service的nginx

   class nginx {

   package {'nginx':

         ensure   => present,

          name    => nginx,

   }

   service {'nginx':

         ensure    =>true,

         enable    =>true,

         subscribe =>Package['nginx'],

   }

   }

   注意:类的名称只能以小写字母开头,能够包含小写字母,数字和下划线。


类的声明

    在manifest文件中定义的类不会直接被执行 ,他们须要事先声明后才能 被执行。

    要声明一个类须要借助include函数,也能够像声明一个资源同样声明类class {'class_name'}

    例如:


# vim  test.pp
class nginx {
    package {'nginx':
          ensure   => present,
           name    => nginx,
    }
    service {'nginx':
          ensure    =>true,
          enable    =>true,
          subscribe =>Package['nginx'],
    }
}
include nginx


# puppet apply test.pp 应用一个类便可



带参数的类

   在定义带参数的类时,须要将参数声明在类名后的小括号"()"中,建议参数有默认值,若是使用多个参数,须要使用逗号分隔。

   在类传递参数时,其方式相似于定义资源的属性

   class {'class_name':

         params1 => value1,

         params2 => value2,

   }


类的继承调用


   类能够基于父类调用,调用时,应该指定经过inherits调用父类



class nginx {
package {'nginx':
       ensure => present,
       name   => nginx,
}
}
class nginx::web inherits nginx {
service {'nginx':
       ensure  =>true,
       enable  =>true,
}
}
include nginx::web

    =>  在子类中覆盖父类中的资源

    +>  在子类中为父类中的资源新增额外的属性


PS:总结也许不全面,不足之处请之处!

相关文章
相关标签/搜索