Puppet

1、Puppet:简介

OS Provision:
    bare metal:pxe, cobbler
    virtual machine:image file template 
Configuration:
    ansible(agentless)
    puppet(master/agent) (ruby)
    saltstack (python)
command and control:
    ansible
    fabric
    func
    ...
    https://puppet.com/products/open-source-projects

https://yum.puppet.com/ 
    ruby语言研发

2、puppet工作模型:

单机模型(standalone):手动应用清单(定义相关配置,又叫做资源,清单文件以.pp结尾)
                                        puppet apply
master/agent:由agent周期性的向Master请求清单并自动应用与本地
                                master:puppet master
                                        agent:     puppet agent
单机模型:
          程序环境:
                        配置文件:/etc/puppet
                                            puppet.conf
                        主程序:/usr/bin/puppet

3、 puppet程序:

 puppet  <subcommand子命令> [options] <action> [options]
                help              Display Puppet help.  查看子命令
                apply             Apply Puppet manifests locally
                    facts             Retrieve and store facts.
                module            Creates, installs and searches for modules on the Puppet Forge.  
                man               Display Puppet manual pages.
                describe          Display help about resource types 定义核心资源怎么使用
                      # puppet describe --list
        
        puppet help <subcommand>
                    # puppet help resource
            # puppet help resource-type
        puppet help <subcommand> <action>
        
puppet apply:
        
        Applies a standalone (单机模式)Puppet manifest to the local system.
        
        puppet apply  [-v|--verbose]  [-d|--debug]  [--noop]  [--execute]   <manifest_file>

4、puppet资源:

资源抽象的纬度(RAL是如何抽象资源的?):
            类型:具有类似属性的组件,例如user, group, package等;
            将资源的属性或状态主与其实现方式分离
            仅描述资源的目标状态,也即期望其实现的结果,而不是具体过程;
            
        RAL由“类型”和提供者(Provider);

   puppet   describe:
              Prints help about Puppet resource types,providers, and metaparameters
                     
              puppet  describe   [  -h | --help ]  [ -s | --short ]  [ -p | --providers ]  [ -l | --list ]  [ -m | --meta ] [ type ]
                 -l:列出所有资源的类型;
                            -s:显示指定类型的简要帮助信息;
                           -m:显示指定类型的元参数,一般与-s一同使用;
          资源定义:向资源类型的属性赋值来实现,可称为资源类型实例化
                         定义了资源实例的文件即清单,manifest;
        资源定义的文件叫“清单”,资源定义的语法:
            type {'title':
                attribute1  =>  value1,
                                    attribute2  =>  value2,
                                     ......
            }
            
            注意:type必须使用小写字符;title标识的名字,是一个字符串,在同一类型必须惟一;
                             如果是group tom,user tom是可以的,但是不可以有两个组或者用户同时为一个名字;
            
        获取puppet支持所有资源类型及其说明:
            puppet describe -l
            
        获取特定类型的简要参数列表信息:
            puppet describe -s <type>
            
        获取特定类型的参数列表详细信息:
            puppet describe  <type>
        
        获取特定类型的简要元参数列表信息:
            puppet describe -s -m <type>

5、资源的三类特殊属性:

        名称/名称变量:
            Namevar,可简称为name,可由title表示;
            ensure:
                     定义资源的目标状态; 
                                          present(创建)/absent(删除)
                            Provider:指明资源的管理接口,可以不用特意在指定
                                              aix,directoryservice,groupadd,ldap(目录服务中),pw,
                                              windows_adsi(Windows接口)
            元参数:
                依赖关系:
                    before
                    require 
                通知关系:
                    notify
                    subscribe
                    
            次序链:->
            通知链:~>
            system:是否为系统组
                                             true/flase/yes/no      
    资源引用:
            Type['title'],title可以直接默认为namevar值
                 属性的次序不重要

6、常用类型:

    核心类型:
        group: 组
        user:用户
        packge:程序包 
        service:服务
        file:文件
        exec:执行自定义命令,要求幂等
        cron:周期性任务计划
        notify:通知
     notify:
        Sends an arbitrary message to the agent run-time log.
                     向终端终端发送一个自定义信息,在我们自己某些条件触发时放在日志文件中来提醒用户
        message:要发送的通知消息内容;
        name:消息名称;
                
 group:
            Manage groups.
                
        name:组名;
        gid: GID;不添加则以最大ID号加一
        ensure:目标状态present/absent;  
                system:是否为系统组;true,false,yes,no 布尔型值不能加引号
                
        group{'distros':
            gid     => 2001,
            ensure  => present,
            system  => false,
            }   
clipboard.png

clipboard1.png

6、user:

    Manage users.
                
    name:用户名;
    uid:UID;有默认值
    gid:基本组ID; 
    groups:附加组,不能包含基本组;
    comment:注释; 
    expiry:过期时间;
    home:家目录路径;有目录名
    password:加密后的密码串;
    password_min_age:
    shell:用户默认的shell;有默认值
    system:是否为系统用户; 
    managehome: Whether to manage the home directory when managing the user.
    ensure:present/absent;
             managehome:是否创建家目录,true,false
             keys:秘钥信息 
    资源引用:
                                    type{'title'
                                          attribute => value,
                                          ...
                                     }
                Type['title']  引用
                                              before,require
                
                类型的首字母必须大写;
                                        
                     
            关系元参数:before/require
                A before B: B依赖于A,定义在A资源中;
                    {
                        ...
                        before  => Type['B'],
                        ...
                    }
                B require A: B依赖于A,定义在B资源中;
                    {
                        ...
                        require => Type['A'],
                        ...
                    }
clipboard2.png

7、cron:

           Installs and manages cron jobs.
                
            command:要执行的任务;
            ensure:present, absent;
            hour:            
    minute:
        monthday:
        month:
        weekday:
        user:添加至哪个用户;
                name:cron job的名称;
                                    示例:
            cron{'timesync':
                command => '/usr/sbin/ntpdate 172.16.0.1 &> /dev/null',
                ensure  => present,
                minute  => '*/3',
                user    => 'root',
            }

8、package:

    Manage packages.
                
    name:The package name.
    ensure:installed, present, latest, absent
    source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg
             provider:指明安装方式;

9、service:

    Manage running services.
                
    enable:true, false, manual
    ensure:确定服务的相关状态. running, true; stopped, false;
    hasrestart:是否支持重启,true/false,默认为false,尽量为true
            hasstatus:判定目标服务状态
    name:启动服务的名字
    path:init scripts搜索路径;默认为/etc/rc.d/init.d/
            start:手动定义启动命令
    restart:用户手动指定的restart操作,通常用于定义reload操作;
clipboard3.png

10、file:

Manages files, including their content, ownership, and permissions.
                
                ensure:present,absent, file, directory, link 
                                       present:存在
                                           absent:删除
                   file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
                    link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
                    directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制![clipboard.png](http://upload-images.jianshu.io/upload_images/6854899-1882803f5702863a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
clipboard1.png
clipboard2.png
clipboard3.png

[图片上传中...(clipboard4.png-726a1-1512046880260-4)]

clipboard5.png


recurselimit递归复制的深度;
content:直接给定的文件内容;
path:文件路径;可使用puppet url来实现远程复制;
source:源文件;
target:符号链接的目标文件的;
owner:属主;
group:属组;
mode:权限;
atime/ctime/mtime:时间戳
replace:如果文件存在并且与定义的目录不一样,是否要替换
资源有特殊属性:
名称变量(namevar):
name可省略,此时将由title表示;
ensure:
定义资源的目标状态;
元参数:metaparameters
依赖关系:
before
require
通知关系:通知相关的其它资源进行“刷新”操作;
notify
A notify B:B依赖于A,且A发生改变后会通知B;B会刷新
{
...
notify => Type['B'],
...
}
subscribe
B subscribe A:B依赖于A,且B监控A资源的变化产生的事件;通知关系
{
...
subscribe => Type['A'],
...
}

            示例1:
                    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.dir':
                        path    => '/tmp/test.dir',
                        ensure  => directory,
                        source  => '/etc/yum.repos.d/',
                        recurse => true,
                    }
                
        示例2:
            service{'httpd':
                ensure  => running,
                enable  => true,
                restart => 'systemctl restart httpd.service',
            #       subscribe       => File['httpd.conf'],
            }

            package{'httpd':
                ensure  => installed,
            }

            file{'httpd.conf':
                path    => '/etc/httpd/conf/httpd.conf',
                source  => '/root/manifests/httpd.conf',
                ensure  => file,
                notify  => Service['httpd'],
            }

            Package['httpd'] -> File['httpd.conf'] -> Service['httpd']      
clipboard.png
clipboard1.png
clipboard2.png
clipboard3.png
clipboard4.png
clipboard5.png

exec:
执行外部命令,必须保证命令是幂等的并且没有伤害性
类似于Ansible中的command和shell

    command:namevar,要运行的命令;
        cwd:运行命令的工作目录; 
    user/group:运行命令的用户身份;
    onlyif:此处指定的命令运行成功方会运行command指明的命令;
    path:命令的搜索路径;The search path used for command execution. Commands must be 
                                                                                   fully qualified if no path is specified.
              refresh:重新执行当前command的替代命令;
    refreshonly:仅接收到订阅的资源通知时方才运行;
            **creates**:文件路径,仅此路径表示的文件不存在时,command方才执行;
        onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
    unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;

clipboard.png

4、应用资源清单
puppet apply [option] file
-h help;
-V --version
-d 输出调试详细信息
-v 输出详细信息
-e 执行此处所直接给出的命令
-l 记录在日志文件中
--noop 干跑模式
# puppet appl -l /tmp/mainfest.log mainfest.pp
# puppet apply --modulepath=/root/dev/modules -e "include ntpd::server"
# puppet apply --catalog catalog.json
clipboard.png

5、puppet variable:
$variable_name=value
puppet中的变量不管是定义还是引用都要加$符号
数据类型:
字符型:引号可有可无;但单引号为强引用,双引号为弱引用;
数值型:默认均识别为字符串,仅在数值上下文才以数值对待;
数组:[]中以逗号分隔元素列表;
布尔型值:true, false;
hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;{ 'mon' => 'Monday', 'tue' => 'Tuesday', };
undef:未定义 ;

    正则表达式:
        (?<ENABLED OPTION>:<PATTERN>)  启用这个属性
        (?-<DISABLED OPTION>:<PATTERN>)  禁用这个属性
        
            OPTIONS:
                i:忽略字符大小写;
                m:把.当换行符;
                x:忽略<PATTERN>中的空白字符
                
            (?i-mx :PATTERN) 
                
        不能赋值给变量 ,仅能用在接受=~或!~操作符的位置;
        
    puppet的变量种类:
        
        facts:
            由facter提供;top scope;
                              #facter  -p  如果主机已经被puppet获取,可以显示出它的內建变量      
        内建变量:
            master端变量
                                     $servername, $serverip, $serverversion
            agent端变量 
                                     $clientcert, $clientversion, $environment
            parser变量
                                     $module_name
        用户自定义变量:  
            
        
        变量有作用域,称为Scope;
            top scope:   $::var_name   ::代表从根开始
            node scope
            class scope
clipboard.png

6、puppet流程控制语句:
if语句:
if CONDITION {
...
} else {
...
}

          CONDITION的给定方式:
            (1) 变量
            (2) 比较表达式 
            (3) 有返回值的函数
clipboard1.png

if $osfamily =~ /(?i-mx:debian)/ { 模式左右要加/,内部模式要用小括号括起来,以问号开头
$webserver = 'apache2'
} else {
$webserver = 'httpd'
}

        package{"$webserver":
                 ensure  => installed,
             before  => [ File['httpd.conf'], Service['httpd'] ],
           }

        file{'httpd.conf':
            path    => '/etc/httpd/conf/httpd.conf',
            source  => '/root/manifests/httpd.conf',
            ensure  => file,
            }

        service{'httpd':
            ensure  => running,
            enable  => true,
            restart => 'systemctl restart httpd.service',
            subscribe => File['httpd.conf'],
             }          
            
        $osfamily == 'RedHat'
        $osfamily == $myos
    ![clipboard2.png](http://upload-images.jianshu.io/upload_images/6854899-01757c692278e095.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

case语句:
case CONTROL_EXPRESSION {
case1: { ... }
case2: { ... }
case3: { ... }
...
default: { ... }
}

             CONTROL_EXPRESSION:
                (1) 变量
                (2) 表达式 
                (3) 有返回值的函数
                
            各case的给定方式:
                (1) 直接字串;
                (2) 变量 
                (3) 有返回值的函数
                (4) 正则表达式模式;
                (5) default 

                case $osfamily {
                    "RedHat": { $webserver='httpd' }   精确匹配RedHat
                    /(?i-mx:debian)/: { $webserver='apache2' }
                    default: { $webserver='httpd' }
                        }

                package{"$webserver":
                    ensure  => installed,
                    before  => [ File['httpd.conf'], Service['httpd'] ],
                         }

                file{'httpd.conf':
                    path    => '/etc/httpd/conf/httpd.conf',
                    source  => '/root/manifests/httpd.conf',
                    ensure  => file,
                        }

                service{'httpd':
                    ensure  => running,
                    enable  => true,
                    restart => 'systemctl restart httpd.service',
                    subscribe => File['httpd.conf'],
                        }                   
clipboard1.png

selector语句:
CONTROL_VARIABLE ? {
case1 => value1,
case2 => value2,
...
default => valueN,
}
Selectors 做多条件赋值
selector只能用于期望出现纸介质的地方,这包括变量赋值、资源属性、函数参数、资源标题、其他selector的值以及表达式
selector不能用于一个已经嵌套于selector的case中,也不能用于一个已经嵌套于case的case语句中
CONTROL_VARIABLE的给定方法:
(1) 变量
(2) 有返回值的函数

    各case的给定方式:
        (1) 直接字串;
        (2) 变量 
        (3) 有返回值的函数
        (4) 正则表达式模式;
        (5) default 
                
    注意:不能使用列表格式;但可以是其它的selecor;
          示例1:      
        $pkgname = $operatingsystem ? {     如果$pkgname匹配到第一个则返回apache2,匹配到第二个则返回httpd
        /(?i-mx:(ubuntu|debian))/       => 'apache2',
        /(?i-mx:(redhat|fedora|centos))/        => 'httpd',
        default => 'httpd',
        }

        package{"$pkgname":
        ensure  => installed,
        }           

    示例2:
        $webserver = $osfamily ? {
               "Redhat" => 'httpd',
                /(?i-mx:debian)/ => 'apache2',
                default => 'httpd',
               }


        package{"$webserver":
                  ensure  => installed,
              before  => [ File['httpd.conf'], Service['httpd'] ],
            }

        file{'httpd.conf':
            path    => '/etc/httpd/conf/httpd.conf',
            source  => '/root/manifests/httpd.conf',
            ensure  => file,
            }

                service{'httpd':
                    ensure  => running,
                    enable  => true,
                    restart => 'systemctl restart httpd.service',
                    subscribe => File['httpd.conf'],
                }                   

7、puppet的类:
类:puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;
类可以被继承,也可以包含子类;

       类的名称只能以小写字母开头,可以包含小写字母、数字和下划线
        每个类都会引入一个新的变量scpoe,这意味着在任何时候访问类中的变量时都得使得其完全限定名称
            不过,在本地scope可以重新为top scope中的变量赋予一个新值           

    语法格式:
        class NAME {
            ...puppet code...
        }
        
        class NAME(parameter1, parameter2) {
            ...puppet code...
        }
    调用类
    类代码只有声明后才会执行,调用方式:
        (1) include CLASS_NAME1, CLASS_NAME2, ...
        (2) class{'CLASS_NAME':
                attribute => value,
             }
          
        示例1:
            class apache2 {
                $webpkg = $operatingsystem ? {
                    /(?i-mx:(centos|redhat|fedora))/        => 'httpd',
                    /(?i-mx:(ubuntu|debian))/       => 'apache2',
                    default => 'httpd',
                }

                package{"$webpkg":
                    ensure  => installed,
                }

                file{'/etc/httpd/conf/httpd.conf':
                    ensure  => file,
                    owner   => root,
                    group   => root,
                    source  => '/tmp/httpd.conf',
                    require => Package["$webpkg"],
                    notify  => Service['httpd'],
                }

                service{'httpd':
                    ensure  => running,
                    enable  => true,
                }
            }

            include apache2     调用class apache2
            
        示例2:(形参)
            class dbserver($pkg,$srv) {
                    package{"$pkg":
                            ensure  => latest,
                    }

                    service{"$srv":
                            ensure  => running,
                    }
            }

            if $operatingsystem == "CentOS" or $operatingsystem == "RedHat" {
                    case $operatingsystemmajrelease {
                            '7': { $pkgname = 'mariadb-server'  $srvname='mariadb' }
                            default: { $pkgname = 'mysql-server'  $srvname='mysqld' }
                    }
            }

            class{'dbserver':
                    pkg     => "$pkgname",  形式参数调用,pkg不加$符号,调用的参数加上$符号
                    srv     => "$srvname",
            }

类的继承:
class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {
...puppet code...
}

            示例:
            class nginx {
                package{'nginx':
                    ensure  => installed,
                }

                service{'nginx':
                    ensure  => running,
                    enable  => true,
                    restart => '/usr/sbin/nginx -s reload',
                }
            }

            class nginx::web inherits nginx {   nginx是父类,web是子类 ,nginx::web完全限定格式的名称
                Service['nginx'] {   引用父类的资源
                    subscribe => File['ngx-web.conf'],  子类的资源
                }

                file{'ngx-web.conf':
                    path    => '/etc/nginx/conf.d/ngx-web.conf',
                    ensure  => file,
                    source  => '/root/manifests/ngx-web.conf',
                }
            }

            class nginx::proxy inherits nginx {
                Service['nginx'] {
                    subscribe => File['ngx-proxy.conf'],
                }

                file{'ngx-proxy.conf':
                    path    => '/etc/nginx/conf.d/ngx-proxy.conf',
                    ensure  => file,
                    source  => '/root/manifests/ngx-proxy.conf',
                }
            }
        
        示例2:
            class redis {
                    package{'redis':
                            ensure  => latest,
                    } ->

                    service{'redis':
                            ensure  => running,
                            enable  => true,
                    }
            }

            class redis::master inherits redis {
                    file{'/etc/redis.conf':
                            ensure  => file,
                            source  => '/root/manifests/redis-master.conf',
                            owner   => redis,
                            group   => root,
                    }

                    Service['redis'] {
                            subscribe => File['/etc/redis.conf'],
                    }
            }

            class redis::slave inherits redis {
                    file{'/etc/redis.conf':
                            ensure  => file,
                            source  => '/root/manifests/redis-slave.conf',
                            owner   => redis,
                            group   => root,
                    }

                    Service['redis'] {
                            subscribe => File['/etc/redis.conf'],
                    }
            }               
            
            
            
            
        在子类中为父类的资源新增属性或覆盖指定的属性的值:
            Type['title'] {
                attribute1 => value,
                ...
            }
            
        在子类中为父类的资源的某属性增加新值:
            Type['title'] {
                attribute1 +> value,
                ...
            }           

8、puppet模板:
模块就是一个按约定的、预定义的层级结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范;
puppet会在配置的路径下查找所需要的模块;

        模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main"和"settings“;
         MODULES_NAME: 
            manifests/
                init.pp:必须一个类定义,类名称必须与模块名称相同;
            files/:静态文件;
                puppet URL: 
                    puppet:///modules(关键词)/MODULE_NAME/FILE_NAME
            templates/:
                tempate('MOD_NAME/TEMPLATE_FILE_NAME')
            lib/:插件目录,常用于存储自定义的facts以及自定义类型;
            spec/:类似于tests目录,存储lib/目录下插件的使用帮助和范例;
            tests/:当前模块的使用帮助或使用范例文件;
            
        注意:
            1、puppet 3.8及以后的版本中,资源清单文件的文件名要与文件子类名保持一致,例如某子类名
                                 为“base_class::child_class”,其文件名应该为child_class.pp;子类名.pp
                                     
                                  redis/
                                       mainfests/
                                                  init.pp:  class  redis  {}
                                                   master.pp:class  redis::master   inherits   redis  {}
                                                   slave.pp:class  redis::slave  inherits  redis  {}                 
            2、无需在资源清单文件中使用import语句;
            3、manifests目录下可存在多个清单文件,每个清单文件包含一个类,其文件名同类名;
            

    erb:模板语言,embedded ruby;
    
    puppet兼容的erb语法:
        https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html
        
    file{'title':
        ensure  => file,
        path     => 
        content => template('/PATH/TO/ERB_FILE'), 模板文件的路径
    }
    
    文本文件中内嵌变量替换机制:
        <%= @VARIABLE_NAME %>
        
    示例:
                 #mv nginx.conf  nginx.conf.erb
                 #vim  nginx.conf.erb
                    在worker_processes后面改为<%= @processorcount  %>;
        class nginx {
            package{'nginx':
                ensure  => installed,
            }

            service{'nginx':
                ensure  => running,
                enable  => true,
                require => Package['nginx'],
            }
        }

        class nginx::web inherits nginx {
            file{'ngx-web.conf':
                path    => '/etc/nginx/conf.d/ngx-web.conf',
                ensure  => file,
                require => Package['nginx'],
                source  => '/root/manifests/nginx/ngx-web.conf',
            }

            file{'nginx.conf':
                path    => '/etc/nginx/nginx.conf',
                ensure  => file,
                content => template('/root/manifests/nginx.conf.erb'),
                require => Package['nginx'],
            }

            Service['nginx'] {
                subscribe => [ File['ngx-web.conf'], File['nginx.conf'] ],
            }
        }

        include nginx::web      
        
        
课外练习:
    1、用standalone的模式,在多主机本地运行清单,实现对keepalived高可用的nginx服务;

9、puppet config命令:
# puppet help config
print 显示
set 设定
获取或设定puppet配置参数;
# puppet config print 显示所有配置参数
# puppet config print [argument] 显示配置参数

    puppet查找模块文件的路径:modulepath
            
mariadb模块中的清单文件示例:
    class mariadb($datadir='/var/lib/mysql') {
        package{'mariadb-server':
        ensure  => installed,
        }

    file{"$datadir":
        ensure  => directory,
        owner   => mysql,
        group   => mysql,
        require => [ Package['mariadb-server'], Exec['createdir'], ],
        }

    exec{'createdir':
        command => "mkdir -pv $datadir",
        require => Package['mariadb-server'],
        path => '/bin:/sbin:/usr/bin:/usr/sbin',
        creates => “$datadir",
        }

    file{'my.cnf':
        path    => '/etc/my.cnf',
        content => template('mariadb/my.cnf.erb'),
        require => Package['mariadb-server'],
        notify  => Service['mariadb'],
        }

    service{'mariadb':
        ensure  => running,
        enable  => true,
        require => [ Exec['createdir'], File["$datadir"], ],
                }
            }

10、standalone:puppet apply
master/agent:agent每隔30分钟到master端请求与自己相关的catalog
master: site manifest
node 'node_name' {
...puppet code...
}

    node_name
    
    程序包下载路径:
        https://yum.puppetlabs.com/
        
    官方文档:
        https://docs.puppet.com/puppet/3/reference/
        
    内建函数:
        https://docs.puppet.com/puppet/3/reference/function.html
        
    配置参数列表:
        https://docs.puppet.com/puppet/3/reference/configuration.html

部署master:
安装程序包:facter, puppet, puppet-server

    初始化master:
        puppet master --no-daemonize --verbose 
        
    生成一个完整的配置参数列表:
        puppet master --genconfig 
        puppet agent --genconfig 
        ...
        
    打印基于默认配置生效的各配置参数列表:
        puppet config <action> [--section SECTION_NAME]
        
        puppet  config  print 
        
    基于命令行设定某参数的值:
        puppet config set 

master端管理证书签署:
puppet cert <action> [--all|-a] [<host>]
action:
list
sign
revoke
clean:吊销指定的客户端的证书,并删除与其相关的所有文件;

站点清单的定义:
主机名定义:
主机名(主机角色)#-机架-机房-运营商-区域.域名
www1-rack1-yz-unicom-bj.magedu.com

    /etc/puppet/manifests/site.pp
        node 'base' {
            include ntp 
        }
    
        node 'HOSTNAME' {
            ...puppet code...
        }
        
        node /PATTERN/ {
            ...puppet code...
        }
        
            node /node[0-9]+\.magedu\.com/
        
        节点定义的继承:
            node NODE inherits PAR_NODE_DEF {
                ...puppet code...
            }
            
            nodes/
        
        清单配置信息可模块化组织:
            databases.d/
            tomcatservers.d/
            nodes.d/:可通过多个pp文件分别定义各类站点的清单;而后统一导入site.pp,方法如下:
            
            site.pp文件使用中如下配置:   
                import 'nodes/*.pp'

多环境配置:
默认环境是production;

    environmentpath =
    
    puppet 3.4 之前的版本配置多环境的方法: 
        
        各环境配置:
            /etc/puppet/environments/{production,development,testing}
            
        master支持多环境:puppet.conf
            [master]
            # modulepath=
            # manifest=
            environments = production, development, testing
            
            [production]
            modulepath=/etc/puppet/environments/production/modules/
            manifest=/etc/puppet/environments/production/manifests/site.pp
            
            [development]
            modulepath=/etc/puppet/environments/development/modules/
            manifest=/etc/puppet/environments/development/manifests/site.pp 
            
            [testing]
            modulepath=/etc/puppet/environments/testing/modules/
            manifest=/etc/puppet/environments/testing/manifests/site.pp 
            
    puppet 3.6之后的版本配置多环境的方法:
        master支持多环境:
            (1) 配置文件puppet.conf
            [master]
            environmentpath = $confdir/environments
            
            (2) 在多环境配置目录下为每个环境准备一个子目录
            ENVIRONMENT_NAME/
                manifests/
                    site.pp
                modules/
                                            
    agent端:
        [agent]
        environment = { production|development | testing }
        
额外配置文件:
    文件系统:fileserver.conf
    认证(URL):auth.conf
    
puppet kick:
    agent:
        puppet.conf
        [agent]
        listen = true
        
        auth.conf文件中添加如下内容:
        path /run
        method save 
        auth any 
        allow master.magedu.com 
        
        path /
        auth any
        
    master端:
        puppet kick 
            puppet kick [--host <HOST>] [--all]
            
GUI:
    dashboard
    foreman
    
项目实践:
    haproxy(keepalived)
        cache --> varnish
        imgs--> nginx server
        app --> httpd+tomcat
            --> mariadb-server
            
        zabbix -->
            zabbix-server 
            zabbix-agent
            
    
    
    
    生产环境案例:haproxy.pp

    class haproxy {
      # init haproxy
      class init {
        file { '/etc/init.d/haproxy': 
          ensure        => present,
          source        => "puppet:///modules/haproxy/haproxy/init.d/haproxy.init",
          group         => "root",
          owner         => "root",
          mode          => "0755",
        }
        exec { 'init_haproxy_service':
          subscribe     => File['/etc/init.d/haproxy'],
          refreshonly   => true, 
          command       => "/sbin/chkconfig --add haproxy; /sbin/chkconfig --level 235 haproxy off;",
        }
        service { 'haproxy':
          ensure      => running,
          enable      => true, 
          hasrestart  => true, 
          hasstatus   => true, 
    #       restart     => true,
        }
      }

      # init haproxy.cfg
      class conf {
    #     file { '/usr/local/haproxy','/usr/local/haproxy/etc': 
        file { ['/usr/local/haproxy','/usr/local/haproxy/etc']: 
          ensure        => directory,
          before        => File['/usr/local/haproxy/etc/haproxy.cfg'],
          group         => "root",
          owner         => "root",
          mode          => "0755",
        }

        class piccenter {
          file { '/usr/local/haproxy/etc/haproxy.cfg': 
            ensure        => present,
            source        => "puppet:///modules/haproxy/haproxy/conf/haproxy_piccenter.cfg",
            group         => "root",
            owner         => "root",
            mode          => "0644",
          }
        }
      }
    }




    keepalived.pp

    class keepalived {
      # init haproxy
      class init {
        file { '/etc/init.d/keepalived': 
          ensure        => present,
          source        => "puppet:///modules/haproxy/keepalived/init.d/keepalived.init",
          group         => "root",
          owner         => "root",
          mode          => "0755",
        }
        exec { 'init_keepalived_service':
          subscribe     => File['/etc/init.d/keepalived'],
          refreshonly   => true, 
          command       => "/sbin/chkconfig --add keepalived; /sbin/chkconfig --level 235 keepalived off;",
        }
        service { 'keepalived':
          ensure      => running,
          enable      => true, 
          hasrestart  => true, 
          hasstatus   => true, 
          restart     => true,
        }
      }
    }

总结:
puppet核心资源类型:group, user, file, package, service, exec, cron, notify
puppet describe [-l] [type]

资源清单:manifests, *.pp
    type{'title':
        attribute => value,
        ...
    }
    
    引用:Type['title']
    
    元参数:
        依赖:before/require
        依赖和通知:notify/subscribe
    
    数据类型:字符串、数值、布尔型、数组、hash、undef
    
    正则表达式:(?<enable_flag>-<disable_flag>:<PATTERN>)
        flag: i, m, x
        
变量:$variable,
    facter, 内建变量,自定义变量
    
    FQN:    $::scope1::scope2::variable
                 $variable
    
编程元素:
    流程控制:
        if, case, selector, unless
        
    类:
        class class_name[($parameter1[=value1], $parameter2)] {
            ...puppet code...
        }
        
        class sub_class_name inherits class_name {
            ... puppet code ...
        }
        
            sub_class_name:
                base_class::sub_class_name
        
        子类中引用父类的资源:
            Type['title'] {
                attribute => value,
                atrribute +> value,
            }
            
        声明类:
            include class_name
            class{'class_name':
                attribute => value,
                ...
            }
            
模板:
    erb:Embedded RuBy
        <%= erb code %>
        <% erb code %>
        <%# erb code %>
        
    file类型的资源
        content => template('/PATH/TO/ERB_FILE')
        path     => 
模块:
    modulepath配置参数指定的目录路径下(puppet config print modulepath);
        manifests/
            init.pp (至少得存在一个与模块名同名的类)
            sub_class_name.pp
        files/
            puppet:///modules/MOD_NAME/FILE_NAME
        templates/
            template('MOD_NAME/ERB_FILE')
        lib/
        tests/
        spec/
        
    standalone: 
        puppet  apply -e 'include CLASS_NAME'
            ... puppet code ...
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Puppet理论定义: Puppet 是一个跨平台的集中化配置管理系统,它使用自有的描述语言,可管理配置文件、用户...
    属于你的世界阅读 951评论 0 2
  • 一.puppet介绍 (1)什么是puppetpuppet是一种重量级自动化运维工具,实现自动化运维以及能够帮助系...
    楠人帮阅读 1,045评论 0 3
  • puppet简介 puppet是一套IT基础设施自动化管理工具,可以管理其整个生命周期,其官方网站:www.pup...
    魏镇坪阅读 3,893评论 0 5
  • 1.puppet 是什么 puppet是一个开源的软件自动化配置和部署工具,很多大型IT公司均在使用puppet对...
    milo_e1ce阅读 4,836评论 0 4
  • 就这样轻松愉快中过完了十一的假期,休假后的第一天上班,还没有进入状态的样子!想着不上班的日子过得着实太快,让我多么...
    小鱼1989阅读 144评论 0 0