Puppet---自动化运维工具(进阶)

puppet的部分变量由facter提供,是一个单独的软件包,在安装puppet时就已经被依赖安装了
nginx

facter -p
#变量名称及变量值,可直接调用

每一个变量都有做用域,即做用范围
web

puppet的流程控制,如if语句、case语句、selector语句正则表达式

下面结合示例,分析变量与流程控制的做用redis

if语句示例:

cat if1.pp  
if $osfamily == 'Debian' {      #osfamily是内建变量
        $apachename = 'apache2' #apachename是用户自定义变量,都是用来临时存放字符串内容的
}else {
        $apachename = 'httpd'
}
#在流程控制中使用if/else条件控制语句,并为知足不一样条件的自定义变量赋值
#puppet变量,不管是定义仍是调用都要使用$符号
package{"$apachename":   #注意调用变量要使用双引号,表示弱引用
        ensure => latest,
}
#若是是Debian系统则安装apache2,其余系统则安装httpd软件包,package资源的title调用变量
case语句的示例:

cat case.pp  
case $osfamily {
        "RefHat": { $webserver='httpd' }    #匹配字符串
        /(?i-mx:debian)/: { $webserver='apache2'     #匹配正则表达式
        default: { $webserver='httpd' }    #默认选项
}
#首先判断系统类型,红帽和其余系统使用httpd服务,Debian则使用apache2
package{"$webserver":
        ensure => installed,
        before => [File['httpd.conf'],Service['httpd']],
}

file{'httpd.conf':
        path => '/etc/httpd/conf/httpd.conf',
        source => '/app/httpd.conf',
        ensure => file,
}

service{'httpd':
        ensure => running,
        enable => true,
        restart => 'service httpd restart',
        subscribe => File['httpd.conf'],
}
#本示例实现安装httpd服务

在使用case流程控制时,有一项是匹配模式即正则表达式,下面简要说明下
 /(?i-mx:debian)/
//    表示使用模式匹配,即知足正则表达式的格式要求
(? )  正则表达式使用小括号括起来
i     表示忽略大小写
-     不启用某项功能
m     把 . 看成换行符
x     忽略模式中的空白字符
selector语句示例:

selector与case很类似,可是case每个匹配项都拥有独立代码,而selector每个分支都是一个返回值
dselector用于多变量赋值

cat selector.pp  
$pkgname = $operatingsystem ? {
        /(?i-mx:(ubuntu|debian))/ => 'apache2',
        /(?i-mx:(redhat|fedora|centos))/ => 'httpd',
        default => 'httpd',
}
#自定义变量是pkgname,operatingsystem是内建变量其值是本机系统类型
#本段配置能够分两部分理解,第一步使用内建变量与每一个分支作比较,若是内建变量本身的值与分支模式的值一致,则执行第二步
#第二步,将匹配的分支定义的内容赋值给自定义变量pkgname
package{"$pkgname":
        ensure => installed,
}

下面使用selector再次演示一个例子
cat selector2.pp 
$webserver = $osfamily ? {
        "RedHat" => 'httpd',
        /(?i-mx:debian)/ => 'apache2',
        default => 'httpd',
}
#使用selector为自定义变量webserver赋值
package{"$webserver":
        ensure => present,
}

file{'httpd.conf':
        path => '/etc/httpd/conf/httpd.conf',
        source => '/app/httpd.conf',
        ensure => file,
        require => Package["$webserver"],
}

service{'httpd':
        ensure => running,
        enable => true,
        restart => 'systemctl restart httpd',
        subscribe => File['httpd.conf'],
}

puppet的类:
apache

类是代码块,定义完成后可在全局使用,即在master定义在agent均可调用
ubuntu

定义类的语法格式有两种:vim

class NAME {
    ……puppet code……
}

和

class NAME(parameter1,parameter2) {   #定义形参
    ……puppet code……
}

调用类的方式常见的有两种:
centos

一、使用include明确调用bash

二、如定义一个资源同样定义类完成调用app


下面举例说明

示例1:使用include调用类

cat class1.pp  
class apache {
        $webpkg = $operationsystem ? {
                /(?i-mx:(centos|redhat|fedora))/ => 'httpd',
                /(?i-mx:(ubuntu|debian))/ => 'apache2',
                default => 'httpd',
        }
        #类中使用流程控制selector,为自定义变量webpkg赋值
        package{"$webpkg":
                ensure => installed,
        }
        #类中使用package资源,安装软件包
        file{'httpd.conf':
                ensure => file,
                path => '/etc/httpd/conf/httpd.conf',
                source => '/app/httpd.conf',
                require => Package["$webpkg"],
        }
        #类中调用file资源,复制httod的配置文件,并且此资源依赖于package资源
        service{'httpd':
                ensure => running,
                enable => true,
                hasrestart => true,
                restart => 'service httpd restart',
                subscribe => File['httpd.conf'],
        }
        #类中调用service资源,启动httpd服务,并启动订阅功能在配置文件改变时重启服务
}
#到此都是class的范围,所谓的类就是将多个资源打包在一块儿,对外呈现为独立个体
include apache   #使用include调用类,不然咱们只是定义类,并不会执行

示例2:定义资源同样定义类

cat class2.pp  
class webserver($pkg,$srv) {
        package{"$pkg":
                ensure => latest,
        }

        service{"$srv":
                ensure => running,
        }
}

if $operatingsystem == "CentOS" or $operatingsystem == "RedHat" {
        case $operatingsystemmajrelease {
                '7': { $pkgname = 'httpd' $srvname = 'httpd' }
                default: { $pkgname = 'nginx' $srvname = 'nginx' }
        }
}

class{'webserver':
        pkg => "$pkgname",
        srv => "$srvname",
}

类的继承

子类继承父类的功能,同时能够在此基础上增长新的功能

调用子类会自动调用父类,因此不必单独调用父类

cat redis.pp  
class redis {
        package{'redis':
                ensure => latest,
        }

        service{'redis':
                ensure => running,
                enable => true,
                hasrestart => true,
                restart => 'service redis restart',
                require => Package['redis'],
        }
}
#以上定义父类
class redis::master inherits redis {   #子类名为master,彻底限定的子类名称即redis::master
        file{'redis.conf':
                ensure => file,
                path => '/etc/redis.conf',
                source => '/app/module.d/redis-master.conf',
                owner => redis,
                group => root,
                require => Package['redis']
        }
#子类中能够自定义资源
        Service['redis'] {
                restart => 'systemctl restart redis',  
                subscribe => File['redis.conf'],
        }
#子类调用父类的资源,注意格式
}

class redis::slave inherits redis {
        file{'redis.conf':
                ensure => file,
                path => '/etc/redis.conf',
                source => '/app/module.d/redis-slave.conf',
                owner => redis,
                group => root,
                require => Package['redis']
        }

        Service['redis'] {
                restart => 'systemctl restart redis',
                subscribe => File['redis.conf'],
        }
}

include redis::master   #使用时仅调用子类便可,由于子类会主动调用父类,本处是redis主节点的调用
#本示例实现reids主从的自动化部署,因此用到了master和slave的配置文件,
#从节点的调用是include redis::slave

puppet模板

模板语言使用erb

借助content实现文本文件中内嵌变量替换,如

<%= @VARIABLE_NAME %>

下面举例说明

结合上述示例
vim redis-slave.conf.erb 
slaveof <%= @masterip %> <%= @masterport %>
#以redis配置文件为模板,只修改从节点的信息

cat redis.pp 
class redis {
        package{'redis':
                ensure => latest,
        }

        service{'redis':
                ensure => running,
                enable => true,
                hasrestart => true,
                restart => 'service redis restart',
                require => Package['redis'],
        }
}

class redis::master inherits redis {
        file{'/etc/redis.conf':
                ensure => file,
                source => '/app/module.d/redis-master.conf',
                owner => redis,
                group => root,
                require => Package['redis']
        }

        Service['redis'] {
                restart => 'systemctl restart redis',
                subscribe => File['/etc/redis.conf'],
        }
}

class redis::slave($masterip,$masterport) inherits redis {   #子类继承父类同时定义变量
        file{'/etc/redis.conf':
                ensure => file,
                content => template('/app/module.d/redis-slave.conf.erb'),   #这步是关键,定义模板的路径,不用再指定source
                owner => redis,
                group => root,
                require => Package['redis']
        }

        Service['redis'] {
                restart => 'systemctl restart redis',
                subscribe => File['/etc/redis.conf'],
        }
}

class{'redis::slave':
        masterip => '192.168.1.106',
        masterport => '6379',
}
#定义类的资源,为slave子类变量赋值
#因为是从节点的配置,全部此处只对slave部分进行修改,master暂时无论

puppet apply -v redis.pp
#执行资源清单
#而后检查/etc/redis.conf文件中的 slaveof 192.168.1.106 6379,说明模板复制成功



结束

相关文章
相关标签/搜索