设为首页 收藏本站
查看: 792|回复: 0

[经验分享] Puppet 之 八大资源介绍

[复制链接]

尚未签到

发表于 2018-8-1 12:27:10 | 显示全部楼层 |阅读模式
  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大核心资源的定义和使用介绍完成。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-544783-1-1.html 上篇帖子: Puppet 之 相关概念和命令介绍 下篇帖子: Puppet 之 tag 和 变量介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表