一、puppet简介

        puppet是基于ruby语言开发的一款开源的软件自动化配置和部署工具,它使用简单且功能强大,可以C/S模式或独立运行。

二、puppet工作模式与流程

 ①puppet的工作模式

       定义:使用puppet配置语言定义基础配置信息;master要指明agent相关配置

          模拟: 模拟测试运行,不真正执行

          强制:强制当前agent与定义的目标状态保持一致;执行所有配置

          报告:通过puppet api将执行结果发送给接受者; 执行完成agent向master报告

 

 ②Master/Agent的工作流程   

    

三、puppet基本用法

3.1、 puppet的核心组件是资源,下面讲解一下几个常用资源的使用方法:     

# puppet describe --list         //查看puppet的资源列表# puppet describe 资源名称      //查看该资源的使用方法#  puppet apply *.pp                //应用定义的资源清单

①group -- 组管理

常用属性:    name               //组名,NameVar    gid                 //GID    system {true|false}    //是否为系统组    ensure {present |absent}   //创建,删除    members             //定义组内成员
例子: test1.ppgroup {"redhat":                    //组名    ensure => present,            //创建    gid  => 950,                  //组id    system => true,               //为系统组,因为使用的是centos7,1~1000都是系统组id}
[root@node1 puppet]# puppet apply -v test1.pp       //在本地应用Notice: Compiled catalog for node1 in environment production in 0.22 secondsInfo: Applying configuration version '1446996520'Notice: /Stage[main]/Main/Group[redhat]/ensure: createdNotice: Finished catalog run in 0.08 seconds[root@node1 puppet]# tail -1 /etc/group       //查看结果redhat:x:950:

② user  -- 用户管理 

常用属性:    comment                //注释信息    ensure {present |absent}      //创建,删除    expiry                //过期期限    gid                 //基本组id    groups               //附加组    home                //家目录    shell               // 默认shell    name               //用户名,NameVar    system {true | false}      //是否为系统用户    uid              //用户的UID                    password           //用户的密码
例子:test2.ppuser {"centos":    comment => "this is a centos user",            //注释    ensure  => present,                             //创建用户    gid     => 950,                                  //组id    uid     => 950,                                   //用户id    home    => "/home/centos",                         //家目录    shell   => "/bin/bash",                            //默认shell    system  => true,                                    //系统用户    password => '$1$b1010cc9$V0WJdVPoXCVBI70nse5/H.',      //定义密码}[root@node1 ~]# openssl passwd -1 -salt `openssl rand -hex 4`   //生成密码的方法Password: $1$b1010cc9$V0WJdVPoXCVBI70nse5/H.
[root@node1 puppet]# puppet apply -v test2.pp Notice: Compiled catalog for node1 in environment production in 0.30 secondsInfo: Applying configuration version '1446997336'Notice: /Stage[main]/Main/User[centos]/ensure: createdNotice: Finished catalog run in 0.09 seconds[root@node1 puppet]# tail -1 /etc/shadow              //查看密码文件centos:$1$b1010cc9$V0WJdVPoXCVBI70nse5/H.:16747:::::: [root@node1 puppet]# tail -1 /etc/passwd             //查看用户文件 centos:x:950:950:this is a centos user:/home/centos:/bin/bash

③ cron -- 计划任务

常用属性:ensure {present |absent}            //创建,删除command                     //要运行的jobhour                       //时,0-23minute                     //分,0-59month                      //月,1-12monthday                    //日,即每月的第几天,1-31weekday                     //周,0-7name                       //定义计划任务名称user                       //运行的用户
例子:test3.ppcron {"sync time":    ensure    => present,                         //创建计划任务    command   => '/usr/sbin/ntpdate ntp.sjtu.edu.cn &> /dev/null',  //使用绝对路径命令    minute    => '*/5',                       //每5分钟同步一次时间}
[root@node1 puppet]# puppet apply -v test3.ppNotice: Compiled catalog for node1 in environment production in 0.07 secondsInfo: Applying configuration version '1446998027'Notice: /Stage[main]/Main/Cron[sync time]/ensure: createdNotice: Finished catalog run in 0.26 seconds[root@node1 puppet]# crontab -l                    //查看结果# HEADER: This file was autogenerated at 2015-11-08 23:53:48 +0800 by puppet.# HEADER: While it can still be managed manually, it is definitely not recommended.# HEADER: Note particularly that the comments starting with 'Puppet Name' should# HEADER: not be deleted, as doing so could cause duplicate cron jobs.# Puppet Name: sync time*/5 * * * * /usr/sbin/ntpdate ntp.sjtu.edu.cn &> /dev/null

④ notify -- 消息

常用属性:    message          //要发送的消息的内容;NameVar
例子:test4.ppnotify {"hi":        message => "hello world",          //输出消息信息为 hello world}
[root@node1 puppet]# puppet apply -v test4.ppNotice: Compiled catalog for node1 in environment production in 0.05 secondsInfo: Applying configuration version '1448117125'Notice: hello world                         //应用的结果Notice: /Stage[main]/Main/Notify[hi]/message: defined 'message' as 'hello world'Notice: Finished catalog run in 0.04 seconds

⑤ file --文件管理

指明文件内容来源:    content      //直接给出文件内容,支持\n, \t ===要用双引号;    source       //从指定位置下载文件    ensure {file|directory|link|present|absent}  //文件,目录,链接,创建,删除常用属性:    force              //强制运行,可用值yes, no, true, false    group             //文件的属组    owner            //文件的属主    mode            //指定权限,支持八进制格式权限,以及u,g,o的赋权方式    path           //目标路径; 必须为绝对路径    source        //源文件路径;可以是本地文件路径(单机模型),也可以使用puppet:///modules/module_name/file_name;    target   //当ensure为“link”时,target表示path指向的文件是一个符号链接文件,其目标为此target属性所指向的路径;此时content及source属性自动失效;
例子:test5.ppfile {"/tmp/hello":   ensure => directory,              //在/tmp目录下,创建hello目录   owner => "centos",                //属主centos   group => "redhat",               //属组redhat   mode => "400",            //权限为400,但为目录,必然会有x权限,故创建后权限为500}file {"/tmp/test1":           //创建文件test1   ensure => file,   owner => "centos",         //属主为centos}file {"/tmp/link":   ensure => link,                //创建test1的链接文件为link    target => "/tmp/test1",}
[root@node1 puppet]# puppet apply -v test5.pp Notice: Compiled catalog for node1 in environment production in 0.15 secondsInfo: Applying configuration version '1448117739'Notice: /Stage[main]/Main/File[/tmp/test1]/ensure: createdNotice: /Stage[main]/Main/File[/tmp/hello]/ensure: createdNotice: /Stage[main]/Main/File[/tmp/link]/ensure: createdNotice: Finished catalog run in 0.05 seconds[root@node1 puppet]# ll /tmp/             //查看结果total 4dr-x------ 2 centos redhat 4096 Nov 21 22:55 hellolrwxrwxrwx 1 root   root     10 Nov 21 22:55 link -> /tmp/test1-rw-r--r-- 1 centos root      0 Nov 21 22:55 test1

⑥ exec -- 命令管理

常用选项:    command            //运行的命令;NameVar;    creates            //此属性指定的文件不存在时才执行此命令;	    cwd                //在此属性指定的路径下运行命令;    user               //以指定的用户身份运行命令;    group              //指定组;    onlyif             //给定一个测试命令;仅在此命令执行成功(返回状态码为0)时才运行command指定的命令;    unless             //给定一个测试命令;仅在此命令执行失败(返回状态码不为0)时才运行command指定的命令;    refresh      //接受到其它资源发来的refresh通知时,默认是重新执行exec定义的command,             //refresh属性可改变这种行为,即可指定仅在refresh时运行的命令;    refreshonly      //仅在收到refresh通知,才运行此资源;    returns        //期望的状态返回值,返回非此值时表示命令执行失败;    tries          //尝试执行的次数;    timeout        //超时时长;    path           //指明命令搜索路径,其功能类型PATH环境变量;其值通常为列表['path1', 'path2', ...];如果不定义此属性,则必须给定命令的绝对路径;
例子:test6.ppexec {"/bin/echo hello > /tmp/hello.txt":     user => root,     group => root,     unless => "/usr/bin/test -e /tmp/hello.txt",     //文件不存在的时候执行echo命令}
[root@node1 puppet]# puppet apply -v test6.pp Notice: Compiled catalog for node1 in environment production in 0.04 secondsInfo: Applying configuration version '1448121368'Notice: /Stage[main]/Main/Exec[/bin/echo hello > /tmp/hello.txt]/returns: executed successfullyNotice: Finished catalog run in 0.11 seconds[root@node1 puppet]# cat /tmp/hello.txt       //查看应用结果hello

注: creates后面直接跟文件,不存在的时候运行命令;

        onlyif或unless后面必须跟判断语句;

        onlyif执行成功运行命令,unless执行不成功运行命令;

⑦ package -- 软件包管理

常用选项:     name             //软件包名     ensure {present,installed| latest| absent}   //安装,安装最新的,卸载
例子: test7.pppackage {"httpd":   ensure  => present,   allow_virtual => false,}
[root@node1 puppet]# rpm -q httpdpackage httpd is not installed

⑧ service -- 服务管理

常用选项:     ensure {running 运行状态 | stopped 停止状态}   //指定服务的目标状态          enable {true | false }    //指定服务是否开机自启动,并非对所有均有效     name                     //服务名,默认与title相同
例子:  test8.ppservice {"httpd":    ensure => running,    enable => true,}
[root@node1 puppet]# puppet apply -v test8.pp Notice: Compiled catalog for node1 in environment production in 0.48 secondsInfo: Applying configuration version '1448119012'Notice: /Stage[main]/Main/Service[httpd]/ensure: ensure changed 'stopped' to 'running'Info: /Stage[main]/Main/Service[httpd]: Unscheduling refresh on Service[httpd]Notice: Finished catalog run in 0.84 seconds[root@node1 puppet]# ss -tanl           //查看应用结果 State       Recv-Q Send-Q             Local Address:Port          Peer Address:Port   LISTEN      0      128                    :::80                        :::*   [root@node1 puppet]# systemctl list-unit-files --type service | grep httpdhttpd.service                               enabled

3.2、puppet的资源引用

①资源引用格式: Type['title'] 资源类型首字母要大写,例Group|Package|File等

②关系的定义

定义依赖关系 :即资源定义有先后顺序

    被依赖的资源中使用:before 

            例:创建用户之前,所定义gid所对应的组应该事先存在,在group中使用

    依赖其它资源的资源:require

            例:依赖对应gid的组,在user中使用 

     ->:链式依赖

定义通知关系:

    被依赖的资源中使用:notify(通知)

          例:配置文件使用,当发生改变的时候,通知相应服务进行reload或restart

    监听其它资源的资源:subscribe (订阅)

          例:服务中使用,可订阅对应服务的配置文件

    ~>:链式通知

3.3、puppet的数据类型

<1> 字符型:

   ①非结构化文本字符串,可使用引号也可不用;

   ②单引号强引用,双引号弱引用;

   ③支持转义符

<2> 数值型:

   整数和浮点数,只有在执行数值计算或比较的时候才会当做数值型,默认为字符型

<3> 数组:

  ①[]中括号以逗号分隔的元素

  ②数组中的元素可以是任意数据类型

  ③ 数组的索引从0开始,也可以是负数索引 

<4> 布尔型: 

   true或false,不能加引号

<5> undef:

   未被声明的变量值的类型

<6> hash:类似集合

  ①键值数据类型,key=>value,定义在{}大括号中,以逗号分隔

  ②key必须为字符型,value可以是任意数据类型

  ③访问hash类型的数据元素要使用key当索引 

<7> 正则表达式:

 非标准数据类型,不能赋值给变量,只接受=~和!~匹配操作符的位置

 使用方法:/正则表达式/,正则表达式格式

(?<ENABLED  OPTION>:<SUBPATTERN>) ;(?<DISABLED  OPTION>:<SUBPATTERN>)

  例:  =~  /^(?i-mx(centos|fedora))/

    常用的选项: 

        i:忽略字符大小写

        m:把点当换行符

        x:忽略空白字符和注释 

3.4、puppet的变量

    puppet的变量名称必须以“$”开头,赋值操作符为“=”

    facter变量:可直接引用

                 查看puppet支持的各facts   

                                # facter -p   

      内置变量 

                客户端内置: $clientcert ; $clientversion 

                服务器端内置 : $servername ; $serverip; $serverversion ; $module_name

3.5、puppet的类

  用于公共目的的一组资源,是命名的代码块,创建后可在puppet全局进行调用,类可以继承。

3.5.1、类的定义

        ①不带参数的类   class class_name {

                                            ...puppet code...

                                    }

        ②带参数的类  calss class_name (param1='value1',param2='value2') {

                                        ...puppet code...

                                  } 

  注意:类名只能包含小写字母、数字和下载线,且必须以小写字母开头 ;类需要声明后才可以执行 

3.5.2、类的声明,常用方式:

 ① 类声明的方式 1 :

                include class_name1,class_name2, .... 

 ②类声明的方式2 : 

                class { 'class_name': 

                                ...puppet code...

                           }

       

3.5.3、类的继承:继承一个已有的类,并实现覆盖资源属性,或向资源属性追加额外值 (=> , +> )

       定义方式: base_class为基类,也称为父类

                    class base_class {

                            ... puppet code .....

                    } 

                    class base_class::class_name inherits base_class {

                            ... puppet code .....

                    }

3.6、puppet的条件语句语法格式

①if语句

单分支:

         if CONDITION {

                statement

                 ...

          }

双分支:

       if CONDITION {

             statement

             ...

       }

     else {

            statement

           ...

      }         

多分支:  

         if CONDITION {

                statement

                 ...

         }

          elif CONDITION {

                statement

                 ...

         }

         else {

               statement

               ...

         }    

CONDITION 的用法:

       1、比较表达式

       2、变量引用

       3、有返回值的函数调用

②case语句

    case语句会从多个代码块中选择第一个与控制表达式匹配的块进行执行

      case CONTROL_EXPRESS {

                    case1,...: { statement }

                     case2,...: { statement }

                      ......

                    default:{ statement }

           }

③selector语句

   selector只能用于期望出现的位置,不能用于一个已经嵌套了selector的case中,也不能用于一个已经嵌套了case的case语句中;如果给出的case都不匹配控制变量,那么必须定义default case,否则会报错。

          CONTROL_VARIABLE ? {

                 case1 => value1 ,

                 case2 => value2 ,

                 ......

                 default => valueN

             }   

3.7、puppet的模板

puppet模板: 基于ERB模板语言,在静态文件中使用变量等编程元素生成适用于多种不同的环境的文本文件(配置文件);

Embedded RuBy,用于实现在文本文件中嵌入ruby代码,原来的文本信息不会被改变,但ruby代码会被执行,执行结果将直接替换原来代码

常用代码:  <%= Ruby Expression %>  ==== 替换为表达式的值

                    //一般结合facter获取系统的信息,修改服务的配置文件使用

  

3.8、puppet模块

    puppet的模块定义方法,类似于ansible的roles;定义模块有助于以结构化、层次化的方式使用puppet。

①模块定义的目录层次如下:默认存放在/etc/puppet/modules中,也可在配置文件中修改路径。

 module_name/   :模块名称         manifests/  :资源清单                           init.pp : 至少应该包含一个与当前模块名称同名的类                 files/     :静态文件; puppet:///modules/module_name/file_name    templates/  :模板文件目录; template('module_name/template_file_name')       lib/        : 插件目录                 tests/      :当前模块的使用帮助文件及示例文件                spec/       : 类似于tests目录,存储lib目录下定义的插件的使用帮助及示例文件

②模块管理命令

USAGE: puppet module 
 [--environment production ][--modulepath $basemodulepath ]                //模块的使用方法 动作 使用环境:生产环境  模块的路径 ACTIONS:  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.          //升级模块

四、安装配置puppet的Master/Agent 

4.1、配置文件 /etc/puppet/puppet.conf

 显示或设置配置参数:     # puppet config print          //显示所有参数      # puppet config set            //设置参数的值

 

4.2、 获取puppet文档: 

  # puppet doc --list       // 列出所有的reference参考手册    # puppet doc -r reference_name   // 查看某个reference参考手册

4.3、配置puppet  --- Master/Agent 

准备工作: node1:172.16.116.231     //master,安装puppet-server,facternode2:172.16.116.232     //agent,安装puppet,facter # vim /etc/hosts 172.16.116.231 node1172.16.116.232 node2
#关键步骤:要让master和各agent基于ssh主机互信         #ssh-keygen -t rsa -P '' #ssh-copy-id ############特别强调,不能少~~否则出现下列问题##############Error: Could not request certificate: Connection refused - connect(2)

1、配置Master:

启动:首次启动先查看是否存在问题,如果没有再使用-D选项(守护进程);       自动生成的ca证书 /var/lib/puppet/ssl 目录中  [root@node1 ~]# puppet master -v --no-daemonize      //查看相关信息 Info: Creating a new SSL key for caInfo: Creating a new SSL certificate request for caInfo: Certificate Request fingerprint (SHA256): 5D:2F:58:58:37:C3:E5:A5:35:82:D0:3B:8F:36:7A:10:B7:93:C9:3E:CB:E2:EC:13:34:23:50:7A:C6:58:9C:87Notice: Signed certificate request for caInfo: Creating a new certificate revocation listInfo: Creating a new SSL key for node1Info: csr_attributes file loading from /etc/puppet/csr_attributes.yamlInfo: Creating a new SSL certificate request for node1Info: Certificate Request fingerprint (SHA256): 6A:C8:00:C7:EB:CE:7A:1C:07:6B:8A:44:1C:35:B3:2B:28:7A:DE:5B:64:BE:53:BD:72:AF:8D:4F:D8:2F:9E:E6Notice: node1 has a waiting certificate requestNotice: Signed certificate request for node1Notice: Removing file Puppet::SSL::CertificateRequest node1 at '/var/lib/puppet/ssl/ca/requests/node1.pem'Notice: Removing file Puppet::SSL::CertificateRequest node1 at '/var/lib/puppet/ssl/certificate_requests/node1.pem'Notice: Starting Puppet master version 3.6.2

2、配置Agent:

[root@node2 ~]# puppet agent --server=node1 -v --no-daemonize --test --noopInfo: Creating a new SSL key for node2Info: Caching certificate for caInfo: csr_attributes file loading from /etc/puppet/csr_attributes.yamlInfo: Creating a new SSL certificate request for node2Info: Certificate Request fingerprint (SHA256): 4B:92:71:6A:48:48:37:36:C1:12:84:63:C1:C1:57:40:7E:58:5C:29:ED:D9:57:F4:B0:79:8D:AE:25:C4:AF:E1Info: Caching certificate for ca                    //等待ca颁发证书Exiting; no certificate found and waitforcert is disabled     //在node1上显示如下的信息,说明已收到node2的证书申请Notice: node2 has a waiting certificate request

         

3、 crt 证书相关操作: 

 puppet cert sign AGENT_HOSTNAME      //给某个agent签证      list                           //列出所有的待签署证书      sign                           //签署       --all                          //签署所有,存在隐患,慎用~~~       clean                         //清理指定agent证书
[root@node1 ~]# puppet cert list       //查看所有待签证书 "node2" (SHA256) 4B:92:71:6A:48:48:37:36:C1:12:84:63:C1:C1:57:40:7E:58:5C:29:ED:D9:57:F4:B0:79:8D:AE:25:C4:AF:E1 [root@node1 ~]# puppet cert sign node2   //给node2签证 Notice: Signed certificate request for node2Notice: Removing file Puppet::SSL::CertificateRequest node2 at '/var/lib/puppet/ssl/ca/requests/node2.pem'

4、测试

[root@node2 ~]# puppet agent --server=node1 -v --no-daemonize  //在agent上查看 Info: Caching certificate for node2Info: Caching certificate_revocation_list for caInfo: Caching certificate for node2Notice: Starting Puppet client version 3.6.2Info: Retrieving pluginfactsInfo: Retrieving pluginInfo: Caching catalog for node2Info: Applying configuration version '1448189086'Info: Creating state file /var/lib/puppet/state/state.yamlNotice: Finished catalog run in 0.02 seconds[root@node1 ~]# puppet master -v --no-daemonize     //在master上查看的结果Notice: Starting Puppet master version 3.6.2Info: access[^/catalog/([^/]+)$]: allowing 'method' findInfo: access[^/catalog/([^/]+)$]: allowing $1 accessInfo: access[^/node/([^/]+)$]: allowing 'method' findInfo: access[^/node/([^/]+)$]: allowing $1 accessInfo: access[/certificate_revocation_list/ca]: allowing 'method' findInfo: access[/certificate_revocation_list/ca]: allowing * accessInfo: access[^/report/([^/]+)$]: allowing 'method' saveInfo: access[^/report/([^/]+)$]: allowing $1 accessInfo: access[/file]: allowing * accessInfo: access[/certificate/ca]: adding authentication anyInfo: access[/certificate/ca]: allowing 'method' findInfo: access[/certificate/ca]: allowing * accessInfo: access[/certificate/]: adding authentication anyInfo: access[/certificate/]: allowing 'method' findInfo: access[/certificate/]: allowing * accessInfo: access[/certificate_request]: adding authentication anyInfo: access[/certificate_request]: allowing 'method' findInfo: access[/certificate_request]: allowing 'method' saveInfo: access[/certificate_request]: allowing * accessInfo: access[/v2.0/environments]: allowing 'method' findInfo: access[/v2.0/environments]: allowing * accessInfo: access[/]: adding authentication anyInfo: Inserting default '/status' (auth true) ACLInfo: Caching node for node2Info: Caching node for node2Notice: Compiled catalog for node2 in environment production in 0.02 seconds

5、定义该agnet的站点清单;在master端:

        (1)安装所有要用到的模块:

    # puppet module install module_name

      

     (2) 定义 site mainfest ;各agent的站点清单

  # vim /etc/puppet/mainfests/site.pp      node 'NODE_NAME' {     ... puppet code ...  (类声明,也可以定义资源或变量等)     }        例如 :          node "node2" {        include httpd::web ,         }

至此~puppet的相关介绍及Master/Agent搭建完成~~O(∩_∩)O~~