Puppet
puppt的配置语言将资源抽象化,所以我们不必担心底层如何实现,而资源与资源必然是会存在依赖先后关系的,并且puppet更加有oop(面向对象的编程)的设计,存在类,模版,模块,变量等多种概念。
Metaparameters
这个属性属于资源的特殊属性,可以通过这个属性的定义资源间的依赖的关系,或者资源间的通知关系。
before && require && -> 依赖关系
example:
1 | ~]# cat test.pp |
2 | package {'nginx': |
3 | name => 'nginx', |
4 | ensure => latest, |
5 | } -> |
6 | file {'config': |
7 | source => "/root/manifest/conf/nginx.conf", |
8 | path => "/etc/nginx/nginx.conf", |
9 | backup => ".puppet.bak", |
10 | ensure => file, |
11 | before => Service['nginx'] |
12 | } |
13 | service {'nginx': |
14 | name => 'nginx', |
15 | ensure => running, |
16 | hasstatus => true, |
17 | hasrestart => true, |
18 | restart => "systemctl reload nginx", |
19 | path => ["/usr/sbin","/usr/bin"], |
20 | require => [Package['nginx'],File['config']] |
21 | } |
22 | ~]# puppet apply -v test.pp |
23 | Notice: Compiled catalog for init.localdomain in environment production in 0.61 seconds |
24 | Info: Applying configuration version '1505126957' |
25 | Notice: /Stage[main]/Main/Package[nginx]/ensure: created |
26 | Notice: /Stage[main]/Main/File[config]/content: content changed '{md5}93bc8e01bfd45e7e18b23acc178ae25b' to '{md5}f73950c032695ad66a259bca4039afba' |
27 | Notice: /Stage[main]/Main/Service[nginx]/ensure: ensure changed 'stopped' to 'running' |
28 | Info: /Stage[main]/Main/Service[nginx]: Unscheduling refresh on Service[nginx] |
29 | Notice: Finished catalog run in 140.62 seconds |
注意:资源引用必须type的首字母大写,Type['title']。
以上例子共用了三种资源依赖关系的表示方法:
- 被依赖的资源中使用:before
- 依赖其他资源中使用:require
- 脸是依赖:->
notify && subscribe && ~> 通知关系
example:
1 | ~]# cat test1.pp |
2 | package {'nginx': |
3 | name => 'nginx', |
4 | ensure => latest |
5 | } ~> |
6 | exec {'log': |
7 | command => "echo 'package nginx install ok' > /tmp/test.log", |
8 | path => ['/usr/bin','/usr/sbin'], |
9 | refreshonly => true |
10 | } |
11 | file {'config': |
12 | source => "/root/manifest/conf/nginx.conf", |
13 | path => "/etc/nginx/nginx.conf", |
14 | backup => ".puppet.bak", |
15 | ensure => file, |
16 | notify => Service['nginx'] |
17 | } ~> |
18 | exec {'log1': |
19 | command => "echo 'nginx conf replace ok' >> /tmp/test.log", |
20 | refreshonly => true, |
21 | path => ['/usr/bin','/usr/sbin'] |
22 | } |
23 | service {'nginx': |
24 | name => 'nginx', |
25 | ensure => running, |
26 | hasstatus => true, |
27 | hasrestart => true, |
28 | restart => "systemctl reload nginx", |
29 | path => ["/usr/sbin","/usr/bin"], |
30 | require => [Package['nginx'],File['config']], |
31 | subscribe => File['config'] |
32 | } |
33 | ~]# puppet apply -v test1.pp |
34 | Notice: Compiled catalog for init.localdomain in environment production in 0.66 seconds |
35 | Info: Applying configuration version '1505128794' |
36 | Notice: /Stage[main]/Main/Package[nginx]/ensure: created |
37 | Info: /Stage[main]/Main/Package[nginx]: Scheduling refresh of Exec[log] |
38 | Notice: /Stage[main]/Main/Exec[log]: Triggered 'refresh' from 1 events |
39 | Info: /Stage[main]/Main/File[config]: Removing old backup of type file |
40 | Notice: /Stage[main]/Main/File[config]/content: content changed '{md5}93bc8e01bfd45e7e18b23acc178ae25b' to '{md5}f73950c032695ad66a259bca4039afba' |
41 | Info: /Stage[main]/Main/File[config]: Scheduling refresh of Service[nginx] |
42 | Info: /Stage[main]/Main/File[config]: Scheduling refresh of Service[nginx] |
43 | Info: /Stage[main]/Main/File[config]: Scheduling refresh of Exec[log1] |
44 | Notice: /Stage[main]/Main/Exec[log1]: Triggered 'refresh' from 1 events |
45 | Notice: /Stage[main]/Main/Service[nginx]/ensure: ensure changed 'stopped' to 'running' |
46 | Info: /Stage[main]/Main/Service[nginx]: Unscheduling refresh on Service[nginx] |
47 | Notice: Finished catalog run in 17.30 seconds |
48 | ~]# cat /tmp/test.log |
49 | package nginx install ok |
50 | nginx conf replace ok |
通知信息,就是向你想要的通知的资源发送refresh信号,常用的就是在更改配置信息后重新启动服务等之类的通知。
以上例子共用了三种资源通知资源的表示方法:
- 被依赖的资源主动使用:notify
- 监听其他资源的资源:subscribe
- 链式通知: ~>
变量,数据类型,正则表达式
变量
变量是以$开头,赋值符号=;任何非正则表达式类型的数据均可赋值的变量。
作用域:定义代码的生效范围,以实现代码间隔离
- 仅能隔离:变量,资源的默认属性
- 不能隔离:资源的名称及引用
每个变量两种引用路径:
- 相对路径
- 绝对路径:$::scope::scopr::variable
变量的赋值符号:
- =
- +=:追加赋值
puppet中的变量种类:
- 自定义变量
- facter变量,可以通过facter -p 查看
- 内置变量
数据类型
- 布尔型:true|false
- undef:未申明
- 字符型:可以不用引号,支持单引号(强引号),双引号(弱引用)
- 数值型:整数和浮点型
- 数组: [item1,item2,item3,…]元素可为任意可用的数据类型,包括数组和hash;索引从0开始,还可以使用负数
- hash:{key => value,key => value,…},键为字符串,而值可以是任意数据类型
正则表达式
非标准的数据类型,不能赋值给变量。
语法结构:
(?<ENABLED OPTION>:<SUBPATTERN>)
(?-<DISABLED OPTION>:<SUBPATTERN>)
OPTION:
- i:忽略大小写
- m:把.当换行符
- x:忽略模式中的空白的注释
条件判断
if语句
语法格式:
1 | if CONDITION { |
2 | ... |
3 | } elseif { |
4 | ... |
5 | } else { |
6 | ... |
7 | } |
COMDITION的用法:
- 比较表达式
- 变量引用
- 有返回值的函数调用
example:
1 | ~]# cat if.pp |
2 | if $operatingsystem =~ /^(?i-mx:(centos|redhat))/ { |
3 | notice ("welcome to $1 linux server!") |
4 | } |
5 | ~]# puppet apply -v if.pp |
6 | Notice: Scope(Class[main]): welcome to CentOS linux server! |
7 | Notice: Compiled catalog for init.localdomain in environment production in 0.01 seconds |
8 | Info: Applying configuration version '1505130702' |
9 | Notice: Finished catalog run in 0.01 seconds |
case语句
语法格式:
1 | case CONTROL_EXPRESS { |
2 | case1,case2,...:{statement...} |
3 | case3,case4,...:{statement...} |
4 | .... |
5 | default:{statemnet...} |
6 | } |
case:字符串,变量,有返回值函数,模式,default
example:
1 | ~]# cat case.pp |
2 | case $operatingsystem { |
3 | /^(?i-mx:(centos|redhat))/:{notice("welcome to $1 linux server")} |
4 | ubuntu:{notice("welcome to ubuntu server")} |
5 | default:{notice("welcome to jusene server")} |
6 | } |
7 | ~]# puppet apply -v case.pp |
8 | Notice: Scope(Class[main]): welcome to CentOS linux server |
9 | Notice: Compiled catalog for init.localdomain in environment production in 0.01 seconds |
10 | Info: Applying configuration version '1505131147' |
11 | Notice: Finished catalog run in 0.01 seconds |
case语句中,statement是可执行的代码块。
selector语句
只能用于期望出现直接值(plain value)的地方,这包括变量赋值、资源属性、函数参数、资源标题、其他selector的值及其表达式,直接返回一个值,而不执行代码块。
语法格式:
1 | CONTROL_VARIABLE ? { |
2 | case1 => value1, |
3 | case2 => value2, |
4 | ... |
5 | default => valueN |
6 | } |
example:
1 | ~]# cat selector.pp |
2 | $webserver = $operatingsystem ? { |
3 | /^(?i-mx:centos|redhat|fedore)/ => 'httpd', |
4 | /^(?i-mx:debian|ubuntu)/ => 'apache2', |
5 | default => 'webserver' |
6 | } |
7 | if $webserver { |
8 | notice("webserver is $webserver!") |
9 | } |
10 | ~]# puppet apply -v selector.pp |
11 | Notice: Scope(Class[main]): webserver is httpd! |
12 | Notice: Compiled catalog for init.localdomain in environment production in 0.01 seconds |
13 | Info: Applying configuration version '1505131896' |
14 | Notice: Finished catalog run in 0.02 seconds |
类
类(class)用于公共目的的一组资源,是命名代码块:创建后可在puppet全局调用,类可被继承。
语法格式:
1 | class class_name { |
2 | ...puppet code... |
3 | } |
注意:类名只能包含小写字母、数字和下划线,且必须以小写字母开头
example:
1 | ~]# cat class.pp |
2 | class nginx { |
3 | package {'nginx': |
4 | name => 'nginx', |
5 | ensure => latest, |
6 | } -> |
7 | file {'config': |
8 | source => "/root/manifest/conf/nginx.conf", |
9 | path => "/etc/nginx/nginx.conf", |
10 | backup => ".puppet.bak", |
11 | ensure => file, |
12 | before => Service['nginx'] |
13 | } |
14 | service {'nginx': |
15 | name => 'nginx', |
16 | ensure => running, |
17 | hasstatus => true, |
18 | hasrestart => true, |
19 | restart => "systemctl reload nginx", |
20 | path => ["/usr/sbin","/usr/bin"], |
21 | require => [Package['nginx'],File['config']] |
22 | } |
23 | } |
24 | |
25 | include nginx 声明类,相当于类的实例化 |
26 | ~]# puppet apply -v class.pp |
27 | Notice: Compiled catalog for init.localdomain in environment production in 0.76 seconds |
28 | Info: Applying configuration version '1505132362' |
29 | Notice: /Stage[main]/Nginx/Package[nginx]/ensure: created |
30 | Info: /Stage[main]/Nginx/File[config]: Removing old backup of type file |
31 | Notice: /Stage[main]/Nginx/File[config]/content: content changed '{md5}93bc8e01bfd45e7e18b23acc178ae25b' to '{md5}f73950c032695ad66a259bca4039afba' |
32 | Notice: /Stage[main]/Nginx/Service[nginx]/ensure: ensure changed 'stopped' to 'running' |
33 | Info: /Stage[main]/Nginx/Service[nginx]: Unscheduling refresh on Service[nginx] |
34 | Notice: Finished catalog run in 17.51 seconds |
- 定义能接受参数的类:
example:
1 | ~]# cat class1.pp |
2 | class webserver($server='nginx') { |
3 | package {'webserver': |
4 | name => $server, |
5 | ensure => latest, |
6 | } -> |
7 | service {'webserver': |
8 | name => $server, |
9 | ensure => running, |
10 | hasstatus => true, |
11 | hasrestart => true, |
12 | restart => "systemctl reload $server", |
13 | path => ["/usr/sbin","/usr/bin"], |
14 | } |
15 | } |
16 | |
17 | class {'webserver': |
18 | server => httpd, |
19 | } |
20 | ~]# puppet apply -v class1.pp |
21 | Notice: Compiled catalog for init.localdomain in environment production in 0.61 seconds |
22 | Info: Applying configuration version '1505132897' |
23 | Notice: /Stage[main]/Webserver/Package[webserver]/ensure: created |
24 | Notice: /Stage[main]/Webserver/Service[webserver]/ensure: ensure changed 'stopped' to 'running' |
25 | Info: /Stage[main]/Webserver/Service[webserver]: Unscheduling refresh on Service[webserver] |
26 | Notice: Finished catalog run in 4.11 seconds |
27 | ~}# ps aux | grep httpd |
28 | root 8279 0.1 0.2 226212 5140 ? Ss 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
29 | apache 8280 0.0 0.1 226212 3004 ? S 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
30 | apache 8281 0.0 0.1 226212 3004 ? S 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
31 | apache 8282 0.0 0.1 226212 3004 ? S 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
32 | apache 8283 0.0 0.1 226212 3004 ? S 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
33 | apache 8284 0.0 0.1 226212 3004 ? S 08:28 0:00 /usr/sbin/httpd -DFOREGROUND |
34 | root 8286 0.0 0.0 112644 952 pts/0 S+ 08:28 0:00 grep --color=auto httpd |
- 类继承
定义方式:
1 | class base_class { |
2 | ...puppet_class... |
3 | } |
4 | |
5 | class base_class::class_name inherits base_class { |
6 | ...puppet code... |
7 | } |
example:
1 | ~]# cat base.pp |
2 | class webserver($server='nginx') { |
3 | package {'webserver': |
4 | name => $server, |
5 | ensure => latest |
6 | } |
7 | } |
8 | |
9 | class webserver::httpd inherits webserver { |
10 | Package['webserver'] { |
11 | name => httpd, |
12 | } |
13 | file {"config": |
14 | source => "/root/manifest/conf/httpd.conf", |
15 | path => "/etc/httpd/conf/httpd.conf", |
16 | backup => ".puppet.bak", |
17 | ensure => file, |
18 | before => Service['httpd'] |
19 | } |
20 | service {"httpd": |
21 | name => httpd, |
22 | ensure => running, |
23 | hasstatus => true, |
24 | hasrestart => true, |
25 | restart => "systemctl reload httpd", |
26 | path => ["/usr/sbin","/usr/bin"], |
27 | } |
28 | } |
29 | |
30 | include webserver::httpd |
31 | ~]# puppet apply -v class.pp |
32 | Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults |
33 | Notice: Compiled catalog for init.localdomain in environment production in 0.74 seconds |
34 | Info: Applying configuration version '1505133760' |
35 | Notice: /Stage[main]/Webserver/Package[webserver]/ensure: created |
36 | Notice: /Stage[main]/Webserver::Httpd/File[config]/content: content changed '{md5}f5e7449c0f17bc856e86011cb5d152ba' to '{md5}f8a8d510316c2d584a407f0aa2139a2d' |
37 | Notice: /Stage[main]/Webserver::Httpd/Service[httpd]/ensure: ensure changed 'stopped' to 'running' |
38 | Info: /Stage[main]/Webserver::Httpd/Service[httpd]: Unscheduling refresh on Service[httpd] |
39 | Notice: Finished catalog run in 3.31 seconds |
40 | |
41 | ~]# ps aux | grep httpd |
42 | root 8765 0.0 0.2 226212 5140 ? Ss 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
43 | apache 8766 0.0 0.1 226212 3004 ? S 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
44 | apache 8767 0.0 0.1 226212 3004 ? S 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
45 | apache 8768 0.0 0.1 226212 3004 ? S 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
46 | apache 8769 0.0 0.1 226212 3004 ? S 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
47 | apache 8770 0.0 0.1 226212 3004 ? S 08:42 0:00 /usr/sbin/httpd -DFOREGROUND |
48 | root 8777 0.0 0.0 112644 952 pts/0 S+ 08:43 0:00 grep --color=auto httpd |
类的继承时:
- 声明子类时,其基类会被自动首先声明
- 基类成为子类的父类,基类的变量的属性默认值会被子类复制一份
- 子类可以覆盖父类中同一资源的相同属性的值
- 继承一个已有的类,并实现覆盖资源的属性,或向资源属性追加额外值:=>,+>
模版
基于ERB模版语言,在静态文件中使用变量等编程元素生成适合与多种不同的环境的文本文件(配置文件):Embedded Ruby,用于实现在文本文件中嵌入ruby代码,原来的文本信息不会被改变,但ruby代码会被执行,执行的结果将直接替换原来的代码。
- <%= Ruby Expression %>: 替换为表达式的值
- <% Ruby code %>: 仅执行代码,而不替换
- <%# comment %>: 注释
- <%% or %%>等同于<% or %>:分别进行
- <%- 等同于<%: 闭合标签,控制代码前输出大量空格
- -%> 等同于%>: 闭合标签,控制代码后大量输出空格
- <%= @Ruby var %> 也可以写成<%= Ruby var %>
变量引用:当前范围内的变量都可以作为ruby的变量,用@符号引用
1 | ~]# cat conf/test.erb |
2 | cpuconut = <%= @processorcount %> |
3 | ~]# cat temp.pp |
4 | file {'test': |
5 | content => template('/root/manifest/conf/test.erb'), |
6 | path => '/tmp/test.conf', |
7 | owner => 'jusene', |
8 | group => 'jusene' |
9 | } |
10 | ~]# puppet apply -v temp.pp |
11 | Notice: Compiled catalog for init.localdomain in environment production in 0.14 seconds |
12 | Info: Applying configuration version '1505136413' |
13 | Notice: /Stage[main]/Main/File[test]/ensure: defined content as '{md5}0f30fa861c205656ebb195564c77c3e6' |
14 | Notice: Finished catalog run in 0.04 seconds |
15 | ~]# cat /tmp/test.conf |
16 | cpucount = 2 |
测试变量:
1
~]# cat conf/test.erb
2
<% if @webserver %>
3
webserver = <%= @webserver %>
4
<% else %>
5
webserver = httpd
6
<% end %>
7
~]# cat temp.conf
8
$webserver='nginx'
9
file {'test':
10
content => template('/root/manifest/conf/test.erb'),
11
path => '/tmp/test.conf',
12
owner => 'jusene',
13
group => 'jusene'
14
}
15
~]# cat /tmp/test.conf
16
webserver = nginx
获取当前作用域的所有变量名
1
~]# cat conf/test.erb
2
<%scope.to_hash.keys.each do | k | -%>
3
<%= k %>
4
<% end -%>
模版结合
1
多个模版,可以使用逗号结合。
2
content => template(’mumodule/template1.erb‘, ’mumodule/template2.erb‘)
数组迭代
1
$values = [var1,var2,var3]
2
<% values.each do | val |-%>
3
value = <%= val %>
4
<% end %>
模版语法检查:
1 | ~]# erb -P -x -T '-' mytemplate.erb | ruby -c |
模块
1 | /etc/puppet/modules/ |
2 | modules_name/ |
3 | manifests/ |
4 | init.pp: 至少应该包含一个与当前模块名称同命令 |
5 | files: 静态文件:puppet://modules/module_name/file_name |
6 | templates: 模版文件目录:template("module_name/template_file_name"): |
7 | lib: 插件目录 |
8 | tests: 当前模块的使用帮助文件及示例文件 |
9 | spec: 类事与tests目录,存储lib目录下定义的插件的使用帮助及示例文件 |
模块管理命令:puppet module <action> [--environment production ] [--modulepath $basemodulepath ]
- build Build a module release package.
- changes Show modified files of an installed module.
- generate Generate boilerplate for a new module.
- install Install a module from the Puppet Forge or a release archive.
- list List installed modules
- search Search the Puppet Forge for a module.
- uninstall Uninstall a puppet module.
- upgrade Upgrade a puppet module.
mkdir -pv /etc/puppet/modules/nginx/{manifests,files,templates,tests,lib,spec}
模块是按照一定的目录结构组合,可以理解这个与ansible的roles的相似。