Puppet常用资源使用详解

一、关于Puppet

puppet是一个IT基础设施自动化管理工具,它能够帮助系统管理员管理基础设施的整个生命周期:供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting),基于puppet,可以实现自动化重复任务,快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模等。


puppet资源

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

通常来说,类属于同一种资源的属性是相近的,如文件都有其属主和属组,而用户账号则由用户名、UID、GID等组成。但,即便是同一种资源,其在不同OS上的实现方式却又可能各不相同,例如,在windows上和Linux上启动和停止服务的方式相去甚远。


因此,puppet从以下三个维度来对资源完成抽象:

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

将资源属性或状态的描述与其实现方式剥离开来,如仅说明安装一个程序包而不用关心其具体是通过yum、pkgadd、ports或是其它方式实现;

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

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


puppet资源解构

在为puppet定义一个资源时,这种语法被称作“资源申报(resource declaration)”,它是puppet语言的核心组成部分。上述的定义中,仅描述了资源的目标状态而没有提到为达成目标所需要采取的任何步骤。而资源定义的核心也可以抽象为type、title、attribute和value四个部分。


puppet有许多内置的资源类型,而通过安装插件还可以继续新增额外的类型。可以通过puppet官方的类型参考页面(http://docs.puppetlabs.com/references/latest/type.html)获取详细的信息。也可以使"puppet describe"命令来获取puppet当前所支持的类型列表及每种类型的详细信息,下面给出了一个简要的使用说明。

puppet describe -l:例如puppet支持的所有资源类型及其描述信息;

puppet describe -s <TYPE>:列出指定资源的简要说明;

puppet describe <TYPE>:显示指定资源的详细说明;


下面说一下,puppet几个常用的资源使用方法:

首先安装puppet

1
2
3
4
# 升级facter版本
[root@node1 ~]# rpm -Uvh facter-1.7.3-1.el6.x86_64.rpm
# 添加epel安装源,安装puppet
[root@node1 ~]# yum -y localinstall puppet-2.7.23-1.el6.noarch.rpm


package资源使用:

1
2
3
4
5
6
7
8
9
10
11
# 安装nginx
[root@node1 ~]# vi test.pp
package {'nginx':
    ensure => true,             #确保nginx是被安装的
}
# 执行test.pp
[root@node1 ~]# puppet apply test.pp
notice: /Stage[main]//Package[nginx]/ensure: ensure changed '1.0.15-5.el6' to 'true'
notice: Finished catalog run in 0.77 seconds
[root@node1 ~]# rpm -q nginx
nginx-1.0.15-5.el6.x86_64


service资源使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@node1 ~]# vi test.pp
package {'nginx':
        ensure => true,
}
service {'nginx':
        ensure => true,         #确保服务是被启动的
        require => Package['nginx'],    #确保是在安装nginx之后启动
}
[root@node1 ~]# puppet apply test.pp
notice: /Stage[main]//Package[nginx]/ensure: ensure changed '1.0.15-5.el6' to 'true'
notice: /Stage[main]//Service[nginx]/ensure: ensure changed 'stopped' to 'running'
notice: Finished catalog run in 1.02 seconds
[root@node1 ~]# ps aux | grep nginx
root      8562  0.0  0.0  94572  2024 ?        Ss   11:31   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     8563  0.0  0.0  94916  2580 ?        S    11:31   0:00 nginx: worker process             
root      8568  0.0  0.0   6384   656 pts/0    R+   11:31   0:00 grep nginx
# 发现nginx已经启动


group资源使用:

1
2
3
4
5
6
7
8
9
10
[root@node1 ~]# vi test2.pp
group {'hellopuppet':
        ensure => present,     #确保hellopuppet是被创建的
        gid => 1001,           # gid为1001
}
[root@node1 ~]# puppet apply test2.pp
notice: /Stage[main]//Group[hellopuppet]/ensure: created
notice: Finished catalog run in 0.08 seconds
[root@node1 ~]# cat /etc/group | grep hellopuppet
hellopuppet:x:1001:


user资源使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@node1 ~]# vi test2.pp
group {'hellopuppet':
        ensure => present,
        gid => 1001,
}
user {'hellopuppet':
        ensure => present,         #确保用户被创建
        gid => 1001,               #指定基本组ID
        uid => 1001,               #指定uid
        home => '/home/hellopuppet',  #指定家目录
        managehome => true,           #创建家目录
        password => '$1$2b2a85db$liwf2K3dQzc2oaRq/RnUg/'#给用户创建密码,可以使用openssl passwd -1 -salt `openssl rand -hex 4`命令生成随机串,然后粘贴在这里
        require => Group['hellopuppet'],  #在创建hellopuppet组之后,创建用户
}
[root@node1 ~]# puppet apply test2.pp
notice: /Stage[main]//User[hellopuppet]/ensure: created
notice: Finished catalog run in 0.09 seconds
[root@node1 ~]# cat /etc/passwd | grep hellopuppet
hellopuppet:x:1001:1001::/home/hellopuppet:/bin/bash
[root@node1 ~]# cat /etc/shadow | grep hellopuppet
hellopuppet:$1$2b2a85db$liwf2K3dQzc2oaRq/RnUg/:16173:0:99999:7:::
# 发现用户已被创建,并且生成密码


cron资源使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@node1 ~]# vi test3.pp
cron {'ntpdate':
    command => "/usr/sbin/ntpdate 8.8.8.8",   #执行的命令
    user => root,                      #指定执行用户
    minute => '*/3',                   #指定每3分钟执行一次
    ensure => present,                 #确保被创建任务          
                                                                                                                                                                                             
}
[root@node1 ~]# puppet apply test3.pp
notice: /Stage[main]//Cron[ntpdate]/ensure: created
notice: Finished catalog run in 0.03 seconds
[root@node1 ~]# crontab -l
# Puppet Name: ntpdate
*/3 * * * * /usr/sbin/ntpdate 8.8.8.8
# 发现cron任务已经被创建

file资源使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@node1 ~]# cp /etc/nginx/nginx.conf /tmp/nginx.conf
[root@node1 ~]# mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
[root@node1 ~]# vi test4.pp
file {'/etc/nginx/nginx.conf':
        ensure => file,            #确保nginx.conf是一个文件
        mode => 0644,              #定义权限
        source => '/tmp/nginx.conf'#定义文件的源地址,如过没就从source复制
}
[root@node1 ~]# puppet apply test4.pp
notice: /Stage[main]//File[/etc/nginx/nginx.conf]/ensure: defined content as '{md5}d9dfc198c249bb4ac341198a752b9458'
notice: Finished catalog run in 0.02 seconds
[root@node1 ~]# ls /etc/nginx/nginx.conf
/etc/nginx/nginx.conf




资源间的应用次序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ~]# yum -y remove nginx
[root@node1 ~]# vi test.pp
service {'nginx':
        ensure => running,
        enable => true,
}
package {'nginx':
        ensure => true,
}
Package['nginx'] -> Service['nginx']
[root@node1 ~]# puppet apply test.pp
notice: /Stage[main]//Package[nginx]/ensure: created
notice: /Stage[main]//Service[nginx]/ensure: ensure changed 'stopped' to 'running'
notice: Finished catalog run in 2.27 seconds
[root@node1 ~]# ps aux | grep nginx
root     13589  0.0  0.0  94572  2028 ?        Ss   11:57   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    13590  0.0  0.0  94916  2576 ?        S    11:57   0:00 nginx: worker process             
root     13596  0.0  0.0   6384   652 pts/0    R+   11:57   0:00 grep nginx
# Package['nginx'] -> Service['nginx'] 表示先安装nginx,然后启动nginx


exec资源使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@node1 ~]# vi test.pp
service {'nginx':
        ensure => running,
        enable => true,
}
package {'nginx':
        ensure => true,
}
exec {'chkconfig nginx':
        path => "/sbin",            #执行命令的,程序路径
        command => "chkconfig --add nginx; chkconfig nginx off",  #执行的命令
        user => root,    #执行用户
        group => root,
}
Package['nginx'] -> Service['nginx'] -> Exec['chkconfig nginx']
[root@node1 ~]# yum -y remove nginx
[root@node1 ~]# puppet apply test.pp
notice: /Stage[main]//Package[nginx]/ensure: created
notice: /Stage[main]//Service[nginx]/ensure: ensure changed 'stopped' to 'running'
notice: /Stage[main]//Exec[chkconfig nginx]/returns: executed successfully
notice: Finished catalog run in 2.05 seconds
[root@node1 ~]# chkconfig --list nginx
nginx           0:off   1:off   2:off   3:off   4:off   5:off   6:off

发现资源按照顺序依次执行


资源间通知的使用:

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
[root@node1 ~]# vi test4.pp
file {'/etc/nginx/nginx.conf':
        ensure => file,
        mode => 0644,
        source => '/tmp/nginx.conf',
}
service { 'nginx':
      ensure => running,
      enable => true,
}
File['/etc/nginx/nginx.conf'] ~> Service['nginx']
[root@node1 ~]# vi /tmp/nginx.conf
# 修改源文件中启动线程为4
worker_processes  4
[root@node1 ~]# puppet apply test4.pp
notice: /Stage[main]//File[/etc/nginx/nginx.conf]/content: content changed '{md5}d9dfc198c249bb4ac341198a752b9458' to '{md5}95f45f10386878664af2b7ccd1536ea4'
notice: /Stage[main]//Service[nginx]: Triggered 'refresh' from 1 events
notice: Finished catalog run in 0.50 seconds
[root@node1 ~]# ps aux | grep nginx
root     15452  0.0  0.0  94572  2024 ?        Ss   12:05   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    15453  0.0  0.0  94916  2612 ?        S    12:05   0:00 nginx: worker process            
nginx    15454  0.0  0.0  94916  2696 ?        S    12:05   0:00 nginx: worker process            
nginx    15456  0.0  0.0  94916  2696 ?        S    12:05   0:00 nginx: worker process            
nginx    15457  0.0  0.0  94916  2676 ?        S    12:05   0:00 nginx: worker process            
root     15463  0.0  0.0   6384   656 pts/0    R+   12:05   0:00 grep nginx
# 启动进程变为4个,
# File['/etc/nginx/nginx.conf'] ~> Service['nginx']表示当配置文件有修改时,重启nginx

正则表达式的使用

1
2
3
4
5
6
7
8
9
10
11
12
[root@node1 ~]# vi test5.pp
$webserver = $operatingsystem ? {
   /(?i-mx:ubuntu|debian)/        => 'apache2',
   /(?i-mx:centos|fedora|redhat)/ => 'httpd',
}
notify {"$webserver":
        message => "install $webserver",
}
[root@node1 ~]# puppet apply test5.pp
notice: install httpd
notice: /Stage[main]//Notify[httpd]/message: defined 'message' as 'install httpd'
notice: Finished catalog run in 0.02 seconds


首先定义一个webserver变量,$operatingsystem是pupppet中的*变量,表示当前系统的版本,可以随时调用"?"表示判断语句,然后后面是正则模式匹配,"i"表示忽略字符大小写,"-m"表示不把.当作换行符,"x"表示忽略模式中的空白字符和注释,然后通过notify资源输出,因为当前是centos系统,所以通知要安装httpd。


puppet资源使用,暂时先介绍这么多,以后会不断更新。





     本文转自ljl_19880709 51CTO博客,原文链接:http://blog.51cto.com/luojianlong/1394841,如需转载请自行联系原作者



上一篇:实战营第一期:从零到一上手玩转云服务器


下一篇:《Puppet实战手册》——2.6 使用内联模板