1. 程式人生 > >Puppet---自動化運維工具(進階)

Puppet---自動化運維工具(進階)

linux;puppet

puppet的部分變量由facter提供,是一個單獨的軟件包,在安裝puppet時就已經被依賴安裝了

facter -p
#變量名稱及變量值,可直接調用

每個變量都有作用域,即作用範圍

puppet的流程控制,如if語句、case語句、selector語句

下面結合示例,分析變量與流程控制的作用

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的類:

類是代碼塊,定義完成後可在全局使用,即在master定義在agent都可調用

定義類的語法格式有兩種:

class NAME {
    ……puppet code……
}

和

class NAME(parameter1,parameter2) {   #定義形參
    ……puppet code……
}

調用類的方式常見的有兩種:

1、使用include明確調用

2、如定義一個資源一樣定義類完成調用


下面舉例說明

示例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,說明模板復制成功



結束

Puppet---自動化運維工具(進階)