Puppet 之 八大资源介绍
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Puppet 之 八大资源介绍相关的知识,希望对你有一定的参考价值。
1 概述资源是puppet最基本的元素,每个资源的定义都具有标题、类型以及一系列的属性。puppet的特性就是处理资源与资源之间的依赖关系。任何相同类型的资源都会具有一些相同的属性。
资源定义有如下的特性:
a.puppet使用title在编译时期区分每个资源,使用命名变量(namevar)在执行时区分资源。
b.在同一类资源中title和namevar都是唯一的。
c.每个类型都有部分属性有默认值
d.如果不指定namevar,则默认赋予其title的值。
在puppet 3.6.2版本中,通过命令puppet describe --list可以查看到目前有49种资源类型,本文将结合例子介绍puppet的8种核心资源类型,如下
group: 组
user:用户
packge:程序包
service:服务
file:文件
exec:执行自定义命令,要求幂等
cron:周期性任务计划
notify:通知
其他类型的解释见如下的文档
https://docs.puppet.com/puppet/5.2/cheatsheet_core_types.html#notify
2 八大核心资源
group:管理组
属性:
name:组名;
gid:GID;
system:是否为系统组,true OR false;
ensure:目标状态,present/absent;
members:成员用户;
例子,定义资源清单,最后一个逗号可以写也可以省略
vim group.pp group{'mygrp': ensure => present, name => mygrp66, system => true, }
测试资源情况
puppet apply -v --noop group.pp
如果测试通过,执行资源
puppet apply group.pp
注意:type必须使用小写字符;title是一个字符串,在同一类型中必须惟一;
user:管理用户
Manage users.
属性:
name:用户名;
uid: UID;
gid:基本组ID;
groups:附加组,不能包含基本组;
comment:注释;
expiry:过期时间 ;
home:家目录;
shell:默认shell类型;
system:是否为系统用户 ;
ensure:present/absent;
password:加密后的密码串;
例子
例子,创建一个用户,同时指定多个附加组,用列表实现,这里假设组testgrp不存在,执行会报错,所以可以定义依赖关系,用require来定义依赖关系,这里引用的是资源,所以对应的资源要存在,假设sunnygrp组已经存在,但是还是要定义mygrp这个资源
vim user.pp group{'testgrp': ensure => present, } user{'myuser': ensure => present, name => 'sunny66', uid => 3333, shell => '/sbin/nologin', groups => [sunnygrp,testgrp], require => [Group['sunnygrp'],Group['testgrp']], } group{'sunnygrp': ensure => present, system => true, name => 'sunnygrp', }
关系元参数:before/require
A before B: B依赖于A,定义在A资源中;
{ ... before => Type['B'], ... }
B require A: B依赖于A,定义在B资源中;
{ ... require => Type['A'], ... }
例子
依赖关系的第二种定义方法
vim user.pp group{'testgrp1': ensure => present, before => User['myuser1'], } user{'myuser1': ensure => present, name => 'sunny666', uid => 2222, shell => '/sbin/nologin', groups => [sunnygrp1,testgrp1], } group{'sunnygrp1': ensure => present, system => true, name => 'sunnygrp1', before => User['myuser1'], }
package:管理程序包
属性:
ensure:installed, present, latest, absent, any version string (implies present)
name:包名;注意,如果不指定name,name这个名字默认就是title的名称
source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg;不同操作系统的安装方法,一般不需要指定,因为会自动安装
例子,安装redis包
package{'redis': ensure => latest, }
service:管理运行服务
属性:
ensure:服务是否应该运行。 有效值为“stopped”(也称为“false”),“runnig”(也称为“true”)。
enable:是否应开机启用服务。 有效值为“true”,“false”,“manual”。
name:启动的服务名称
path:用于查找init脚本的搜索路径。 多个值应该用冒号分隔或作为数组提供..脚本的搜索路径,默认path为/etc/init.d/;
hasrestart:是否支持启动功能,如果是true,则直接restart,如果如false,就执行stop后执行start来重启,默认false
hasstatus:默认true
start:手动定义启动命令;
stop:停止服务
status:服务状态
restart:手动指定*restart*命令。 如果未指定,服务将被停止,然后启动。 通常用于定义reload操作;
binary:启动服务,启动程序的路径
path:启动服务脚本路径
例子
启动redis,有依赖关系,假设卸掉redis,但是测试还是正常,真正执行的时候却失败了,因此启动服务脚本中定义资源package
vim service.pp service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', require => Package['redis'], } package{'redis': ensure => latest, }
file:管理文件
管理文件其内容,所有权和权限。
ensure:文件是否应该存在,如果是,应该是什么类型的文件。 可能的值是“present”,“absent”,“file”,“directory”和“link”。
file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;
path:文件路径;
source:源文件;
content:文件内容;
target:符号链接的目标文件;
owner:属主
group:属组
mode:权限;
atime/ctime/mtime:时间戳;
例子
复制文件,先复制一份redis配置文件,并进行修改,然后通过puppet的file进行复制到对应主机
cp /etc/redis.conf /root、 vim file.pp file{'/etc/redis.conf': ensure => file, source => '/root/redis.conf', owner => 'redis', group => 'root', mode => '0644', }
例子
复制目录,注意,以下recurse对应的true是布尔值,不能加引号
vim file.pp file{'yumfile': ensure => directory, path => '/tmp/yum.repos.d/', source => '/etc/yum.repos.d/', recurse => true, }
复制文件到目录下,那么ensure为directory配置就不会生效,直接复制为一个文件,而不生成目录,即如下的例子中,只会在/tmp下生成一个名为test的文件,内容是/etc/issue的内容,而不会在/tmp/test这个目录下生成issue这个文件
file{'test': ensure => directory, path => '/tmp/test', source => '/etc/issue', }
如果有多个源文件,那么只会复制一个文件,如下例子,只会复制/etc/issue这个文件,新生成的文件名为/tmp/test
file{'test': ensure => directory, path => '/tmp/test', source => ['/etc/issue','/etc/group'], }
例子
创建链接
file{'redis.conf': ensure => link, path => '/tmp/redis.conf', target => '/etc/redis.conf', }
通知元参数:订阅或者通知关系
A notify B:B依赖于A,接受由A触发refresh;
B subscribe A:B依赖于A,接受由A触发refresh;B监控A资源的内容变化,一定A变化,B要跟着发送对应变化
在一资源中,notify和suscribe只需要二者选一个即可
通知关系:通知相关的其它资源进行“刷新”操作;
notify
A notify B:B依赖于A,且A发生改变后会通知B;
{ ... notify => Type['B'], ... }
subscribe
B subscribe A:B依赖于A,且B监控A资源的变化产生的事件;
{ ... subscribe => Type['A'], ... }
例子:
安装redis,并启动redis服务,当redis的配置文件更改时,重启服务,用通知链表示表示依赖关系
vim service.pp service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', subscribe => File['redis.conf'], } package{'redis': ensure => latest, } file{'redis.conf': path => '/etc/redis.conf', source => '/root/redis.conf', ensure => file, mode => '0644', owner => redis, group => root, # notify => Service['redis'], } Package['redis'] -> File['redis.conf'] ~> Service['redis']
以上例子,可以改成如下,->表示package先于file,~>表示file先于service,同时service订阅了file
#service with notify or subscribe package{'redis': ensure => latest, } -> file{'redis.conf': path => '/etc/redis.conf', source => '/root/redis.conf', ensure => file, mode => '0644', owner => redis, group => root, } ~> service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'systemctl restart redis', }
依赖关系:当某个条件执行后,才会执行
before
require
例子:
以下例子,File['test.symlink']依赖于File['test.txt'],只有当File['test.txt']资源执行,File['test.symlink']才会被执行
file{'test.txt': path => '/tmp/test.txt', ensure => file, source => '/etc/fstab', } file{'test.symlink': path => '/tmp/test.symlink', ensure => link, target => '/tmp/test.txt', require => File['test.txt'], }
以上例子可以调整如下,资源File['test.txt']执行后才会执行File['test.symlink']
file{'test.txt': path => '/tmp/test.txt', ensure => file, source => '/etc/fstab', before => File['test.symlink'], } file{'test.symlink': path => '/tmp/test.sysmlink', target => '/tmp/test.txt', ensure => link, }
exec:执行外部命令
exec资源中的任何命令必须能够运行多次而不会造成危害,即它必须是幂等的。
**command** (*namevar*):要运行的命令;
cwd:运行该命令的目录。
creates:文件路径,仅此路径表示的文件不存在时,command方才执行;
user/group:运行命令的用户身份;
path:用于命令执行的搜索路径。 如果没有指定路径,则命令必须是绝对路径。
onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;
refresh:重新执行当前command的替代命令;
refreshonly:仅接收到订阅的资源的通知时方才运行;
例子:
创建目录
mkdir不幂等,因此定义creates,只有/tmp/hi.dir/不存在时才执行command
vim exec.pp exec{'makedir': command => 'mkdir /tmp/hi.dir', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', creates => '/tmp/hi.dir', }
创建用户
其中,unless表示只有id sunny88失败,那么command命令才会执行,如果id sunny88成功了,那么command命令就不会执行,即只有sunny88用户不存在的时候才会执行command命令
exec{'createuser': command => 'useradd sunny88', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', unless => 'id sunny88', }
安装包
安装tree服务包,只有查找到sunny仓库时才会执行command
exec{'installpkg': command => 'yum -y install tree', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', onlyif => 'yum repolist | grep -i sunny', }
newaliases是一个命令,只有当/etc/aliases文件发送变化后才会执行newaliases
file{'/etc/aliases': path => '/etc/aliases', ensure => file, before => Exec['newaliases'], } exec{'newaliases': path => ["/usr/local/sbin","/usr/local/bin","/usr/local","/usr/bin"], subscribe => File["/etc/aliases"], refreshonly => true, }
例子
为redis服务器生成配置文件,当模板配置文件改变时,通知exec['backupfile'],并且将本次变化后的配置文件备份到指定路径下,这里有个问题是,第一次的配置文件将不会被备份,因此要手动备份第一次的配置文件
注意,以下的cp命令不幂等,因此复制的时候,建议将备份的文件新增名字后加上时间为后缀。为redis.conf-$(date +%F-%H-%M-%S),防止冲突
file{'/etc/redis.conf': source => '/root/redis.conf', ensure => file, } exec{'mkdir': command => 'mkdir /backups', path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', unless => 'ls /backups', before => Exec['backupfile'], } exec{'backupfile': command => "cp /etc/redis.conf /backups/redis.conf-$(date +%F-%H-%M-%S)", path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin', refreshonly => true, subscribe => File['/etc/redis.conf'], }
cron:安装和管理cron作业
每个由Puppet创建的cron资源都需要一个命令和至少一个周期性属性(小时,分钟,月份,月份,工作日或特殊)。
command:要执行的任务;
ensure:present/absent;
hour:
minute:
monthday:
month:
weekday:
user:以哪个用户的身份运行命令
target:添加为哪个用户的任务
name:cron job的名称;
示例:每隔三分钟执行一次计划任务
cron{'timesync': command => '/usr/sbin/ntpdate 172.18.50.61 &> /dev/null', ensure => present, minute => '*/3', user => 'root', }
notify:发送消息
将任意消息发送到代理运行时日志。
属性:
message:信息内容
name:信息名称;
例子
发出通知消息
notify{'hello': message => 'hello everyone,I am sunny', name => 'Say hello', }
到这里,8大核心资源的定义和使用介绍完成。
以上是关于Puppet 之 八大资源介绍的主要内容,如果未能解决你的问题,请参考以下文章