5t4we 发表于 2017-11-27 16:23:12

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

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


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




每个变量都有作用域,即作用范围

puppet的流程控制,如if语句、case语句、selector语句
下面结合示例,分析变量与流程控制的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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调用变量





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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 => ,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   忽略模式中的空白字符





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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都可调用

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

1
2
3
4
5
6
7
8
9
class NAME {
    ……puppet code……
}



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




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

1、使用include明确调用
2、如定义一个资源一样定义类完成调用

下面举例说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
示例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",
}




类的继承

子类继承父类的功能,同时可以在此基础上增加新的功能

调用子类会自动调用父类,所以没必要单独调用父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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 %>

下面举例说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
结合上述示例
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,说明模板复制成功







页: [1]
查看完整版本: Puppet---自动化运维工具(进阶)