Puppet资源使用

 

 

一、什么是puppet

Puppet是一个IT基础设施自动化管理工具,它能够帮助系统管理员管理基础设施的整个生命周期:供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting

         puttet的工作模型

puppet通过声明性、基于模型的方法进行IT自动化管理

定义:通过puppet的声明性配置语言 定义基础设置的目标状态

模拟:强制应用改变配置之前先进行模拟性应用;dry-run

强制:自动、强制部署达成目标状态,纠正任何偏离的配置

报告:报告当下状态及目标状态的不同,以及达成目标状态所进行的任何强制性改变

         基于puppet,可以实现自动化重复任务,快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模等

         对于系统管理员是抽象的,只依赖于rubyfacter

         能管理多大40多种资源、例如;fileusergrouphostpackageservicecronexecyumrepo等,适合整个软件生命周期管理

         Puppet使用两种模型

1、 单机使用

Puppet apply

2、 master/agent(即C/S方式)

masterpuppetpuppet-server

agentpuppet

二、介绍puppet

PuppetC/S的工作原理

puppet的使用_第1张图片

 

1、 agent向主机请求catalog代码,在请求时要带上自己的主机名与factsfacts 包含了agent服务器自身的一些系统特征,比如操作系统是什么、是哪个版本、cpu是什么型号,内存有多大信息等

2、 master接受到agent的请求后开始查询此节点包含的清单,把这些资源找出后编译成calalog,再发送给agent

3、 agent接收到calalog后就开始应用代码,并把执行的状态结构生成报告返回给master

4、 master接收报告并记录日志

 

puppet的认证方式

 

1、 puppet有其自己的证书管理机制,agentmaster间的通信是需要得到master的认证,证书存放在/var/llib/puppet/ssl/

master/agent首次启用过程:

1、 master启动时会为自己生成key,并签署证书,让自己成为一个ca

2、 agent首次启动为自己生成key,生成证书签署请求,并将证书请求发送给master请求签署

3、 master收到agent的证书签署请求后,由管理员先验证请求是否合法,而后对认证书签署请求作出签署或不签署

puppet的三层模型

Configuration  Language     #配置语言

Transactional  Layer      #事务层

Resources Abstraction  Layer     #资源抽象层

三、Manifest清单

         Puppet的程序文件称作“manifest(清单)”,以.pp作为文件明名后缀

         如前所述,puppet语言的核心是:资源定义,而定义一个资源的核心就在于描述其目标状态

         manifest却还实现了常见的程序逻辑,如条件语句、资源集合及打印文件信息等功能

         简言之,也即resource定义在manifest文件中,或使用manifest文件定义resource

         Puppet apply 子命令能够将一个manifest中描述的目标状态强制实现,因此,它通常以manifest文件为参数

四、catlog文件

         Puppet通过manifest同步资源时,不会直接应用manifest文件,而是要经过预先的编译过程,这是因为manifest文件中可能会包含条件判断、变量、函数及其他的程序逻辑

         实际执行中,有可能会基于层次及包含关系存在多个manifest文件,这些文件会被编译进同一个称作“catalog”的文件

         编译完成后的catalog文件仅包含各个资源以及它们同步时的次序

puppet的使用_第2张图片

puppet资源抽象

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

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

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

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

这三个也被称为puppet的资源抽象层(RAL

1RALtype(类型)和peovier(提供者,既不同OS上的特定实现)组成

五、资源使用

         Puppet的八种常用类型

         user   group    package   file   service   exec   cron    notify

         puppet的十二中次常用类型

         router  stage   schedule  computer host  augeas  mount  yumrepo  interface

tidy    sshkey  resources

1、 定义组的资源

puppet  describe  group    #可查看group的用法

vim  group.pp

group { 'mygrp':

    name       => 'group',

    ensure    => 'present',

    gid   => 2000, 

}


 puppet的使用_第3张图片

2、 定义(创建)用户资源

puppet  describe  user    #查看user的用法

vim  use.pp

user {'zy':

    ensure    =>  present,

    system    =>  false,

    comment        =>  'test user',

    shell         =>    '/bin/bash',

    home       =>    '/home/zy',

    groups  =>    'group',

    managehome         =>  true,

}

[root@node2 ~]# puppet apply -v  use.pp    #执行该命令


 puppet的使用_第4张图片

3、 定义beforerequire

group {'group':

    ensure  => present,

    gid     =>600,

    before   =>  user['zy'],

}

 

user{'zy':

    ensure  => present,

    gid     => 600,

    shell   => '/bin/bash',

    home    => '/home/zy',

}

#因为有上面的实验,所以报了个小错,不过不要紧,资源编写是没问题的

puppet的使用_第5张图片

 

4、定义package

puppet  describe  package   #查看语法

vim package.pp

package {'redis':

    ensure   =>  'latest',

    provider => 'yum',         

}

puppet apply -v --noop  package.pp     #--noop参数  可进行检查语法


 puppet的使用_第6张图片

4、 定义service

path    #定义脚本时的路径

ensure   running /stopped

enable

hasstatus: start   /   stop   /  status   /restart

 

vim service.pp

service {'redis':

    ensure  =>  running,

    enable  =>  true,

}

定义程序包的依赖关系,

package {'memcached':

    ensure  => installed,

     

}

service{'memcached':

    ensure  => running,

    enable  => false,

    require  => package['memcached'] 

}

puppet的使用_第7张图片

 

5、 定义file文件资源

简单的文件复制:

file {'/tmp/redis.conf':

    ensure  =>  file,

    source  =>  /etc/puppet/manifests/files.conf            #文件的来源

}

创建文件

reurse => true  #递归复制

file {'/tmp/text.txt':

    ensure  =>  file,|director

    content  =>  'how are  you ',   #文件内容

    owner  =>  'zy',                #文件属主

    group  =>   'group',            #文件属组

    mode  => '0400',

}

链接文件

file {'/tmp/test.txt.link'

    ensure   =>  link,

    target   =>  '/tmp/test.txt',    

}

 

2)定义fileservice、和package资源的结合

service {'httpd':

    ensure  => running,

    enable  => true,

    restart => 'systemctl restart httpd.service',

}

package {'httpd':

    ensure  => installed,

}

file {'httpd.conf':

    path => '/etc/httpd/httpd.conf',

    source  =>  '/root/httpd.conf',

    ensure  =>  file

    notify  => Service['httpd'],

}

 

Package['httpd'] -> File['httpd.conf'] -> Service['httpd']

 

2、 例子

#1|#2|#3 代表一种表示方法

package{'redis':

   ensure  => installed,  

#2 ->

file{'/etc/redis.conf':

   source  => '/etc/manifests/files/redis.conf',

   ensure  => file,

   owner   => redis,

   group   => root,

   mode    => '0640',

   notify   => Service['redis'],    #依赖于Service

#2  ->

   # ~>   #表示notify之意

service{'redis':

   ensure  => running,

   enable  => true,

   subscribe  => File['/etc/redis.conf'],  #依赖于File

    #1       require  => ['Package["redis"]','File["/etc/redis.conf"]'],

}

#3 Package['redis'] -> File['/etc/redis.conf'] -> Service['redis']

  Package['redis'] -> File['/etc/redis.conf'] ~> Service['redis']

资源特殊属性(前后资源)

notify

A notify B  #B依赖于A,且A发生改变后会通知B

subscribe

B subscribe A  #B依赖于A,且B监控A资源的变化产生的事件

 

6、 定义exec资源

puppet  describe exec  #查看用法

vim  exec.pp

exec {'cmd':

    command  => '[ -e /tmp/testdir ] || mkdir /tmp/testdir',  #-e 判断

    path  => ['/bin/','/sbin/','/usr/bin/','/usr/sbin'],

    #creates  =>  '/tmp/testdir'   #目录不存在才执行command

}

puppet apply  exec.pp

 

创建用户

exec {'user':

    command  =>  'useradd zy',

    path  => '/bin:/sbin:/usr/bin:/usr/sbin',

    unless  => 'id zy',   #当执行失败时,才会执行command

}

redis的重启设置

7、定义cron

vim cron.pp

#同步时间

cron{'timesync':

    command  => '/usr/sbin/ntpdate 172.17.0.1 &> /dev/null ',

    ensure  => present,

    minute  => "*/5",

    target  => 'root',

}

puppet apply cron.pp

8、定义notify资源

send an arbitrary to the agent run-time log

#向代理运行时日志发送任意

 

notify{'sayhi':

    message  => 'hello word'

}

 

9、定义tag格式

vim service.pp

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'],

    tag => 'cpfile',

}

service{'redis':

    ensure => running,

    enable => true,

    hasrestart => true,

    restart => 'systemctl restart redis',

#   subscribe => File['redis.conf'],

    tag => "onlyrestart",

}

Package['redis'] -> File['redis.conf'] ~> Service['redis']

执行:

puppet apply --tags onlyrestart service.pp

puppet apply --tags cpfile service.pp

 

10、定义变量

#自定义变量

方法1

$pkgname = 'tree'

package{'installpkg':

    name => "$pkgname",

    ensure => latest,

}

方法2

$pkgname = 'tree'

package{"$pkgname":

    ensure => latest,

}

puppet的使用_第8张图片

 

内建变量:

master端变量:$servername  $serverip  $serverversion

agent端变量:$clientcert  $clientversion  $environment

parser变量:$module_name 内建的子系统

facter -p   #查看所有内建变量

#测试内建变量,可直接调用

notify{'os':

    message => "$operatingsystem $operatingsystemrelease",

}

puppet的使用_第9张图片

六、Scope区域的使用

Scope是一个特定的代码区域,用于同程序中的其他代码隔离开来

puppet中,scope可用于限定变量及资源默认属性的作用范围,但不能用于限定资源名称及资源引用的生效范围

 

puppet的使用_第10张图片

 

何给定的scope都可以访问它自己的内容,以及接收来自于其父scope、节点scopetop scope的内容

  top scope仅能访问自己变量和属性默认值;

  节点scope能访问自己的及top scope的变量和属性默认值

  example::parentexample::otherexample::four能访问自己的以及节点scopetop scope的变量和默认值

 

七、if  statement:的使用

单分支

if condition{

    statement

    ...

}

 

双分支:

if  condition {

    statement

    ...

}

  else{

    statement

    ...

}

 

多分支:

if condition {

    statement

    ...

}

elsif condition{

    statement

    ...

}

else{

    statement

    ...

}

例子

 

if $operatingsystemmajrelease  == '7' {

    $db_pkg='mariadb-server'

}else{

    $db_pkg='myslq-server'

}

 

package{"$db_pkg":

    ensure  => installed,

}

八、case statement的使用

case给定的方式:

1)直接字串

2)变量

3)有返回值的函数

4)正则表达式模式

5default

 

类似于if语句,case语句会从多个代码快中选择一个分支执行,这跟其他编程语言中的case语句功能一致

case语句会接受一个控制表达式和一组case代码块,并执行第一个匹配到控制表达式的块

格式:

case control_express{

    case1, ... {statement ...}

    case2,...{statement...}

    default : {statement...}

}

 

 

例子:

case $operatingsystem{

    'Solaris':  {notice("welcome to Solaris")}

    'Redhat''CentOS' : {notice("welcome to Rehat OSFamily")}

    /^(Debian|Ubunto)$/:{notice("say hello")}

    default: {notice("you  are  good")}

}

 

2、例子

if $osfamily == 'RedHat'{

    $webPkg='httpd'

}elsif $osfamily =="Debian"{

    $webPkg='apache2'

}else{

    $webPkg='apache'

}

 

case $osfamily{

    'Redhat':{ $webPkg='httpd'}

    /(?i-mx:debian)/:{$webPkg='apache2'}     #忽略大小写匹配

    default: {$webPkg='apache'}

}

package{"$webPkg":

    ensure => installed

}