Puppet 开始

  1. 安装

    aptitude install puppet puppetmaster

  2. 工作机制

    puppet是通过ssl方式进行安全通信的,在正常同步前,需要进行证书的获取和认证 puppet运行机制大概是这样:

    客户端向服务端发送facts信息,请求返回catalog, 服务端检查类文件等的关于客户端的信息打包catalog返回给客户端, 客户端按照catalog进行一系列检查同步操作。

  3. puppet资源类型及属性

    3.1 资源

    资源是puppet处理主机而分解的基本元素,资源的属性控制资源的形态

    e1. puppet resource 
     file {'/root/':
         ensure  =>  'directory',
         group   =>  '0',
         owner   =>  '0',
         mode    =>  '700',
     }

    资源type为file,title为/root/, 其余是属性部分,一个资源的所有属性和帮助可以通过puppet describe RESOURCE_TYPE来查看,常见的资源类型有user,group,file,package,service,cron,exec,notify等。

    3.2 资源类型详细书写

    3.2.1 用户资源user

    用户:

    user {'liuliancao':
         ensure  =>  present,     # 是否允许uid重复
         allowdupe   =>  true,
         uid     =>  '503',     # 指定过期时间
         expiry  =>  '2016-8-13',     # 用户家目录
         managehome  =>  true,
         home    =>  '/home/liuliancao',
         shell   =>  '/bin/bash',
     }

    用户组:

    group {'system':
         ensure  =>  present,
         name    =>  'system',
         allowdupe   =>  false,
         gid     =>  '15',
         members =>  ['liuliancao','luqixue'],
     }

    3.2.3 包资源package

    # 这里是一个判断与选择
     $ssl = $operatingsystem  ?   {
         solaris =>  SMCossl,     default =>  openssl,
     }
     package {$ssl:
         ensure  =>  installed,     # 别名功能,引用的时候可以Package['openssl']
         alias   =>  openssl,
         provider    =>  apt-get,
     }

    3.2.4 文件资源file

    file {'/tmp/llc_test.txt':
         ensure  =>  file,
         owner   =>  liuliancao,
         group   =>  system,     # 文件权限
         mode    =>  '644',     # 文件内容
         content =>  'This is a puppet test.',
     } file {'/tmp/llc_test2.txt':
         ensure  =>  file,
         owner   =>  liuliancao,
         group   =>  system,     # 指定文件来源位置
         source  =>  'puppet://$fileserver/modules/test/test.txt'
     }

    3.2.5 服务管理service

    service {'sshd':     # true也可以的
         ensure  =>  running,     # 是否加入开机启动
         enable  =>  true,
         subscribe   =>  File['/etc/sshd/ssh_config'],
         hasrestart  =>  true,     # sshd检查重启的时候,使用restart的参数(如果有),否则检查是否hasrestart为true,如果为true则尝试restart,否则就尝试start/stop操作
         restart =>  '/etc/init.d sshd restart',
     }

    3.2.6 定时脚本cron

    cron {'ntpdate':
         command =>  "/usr/sbin/ntpdate ntpserver.domain.com",
         user    =>  root,     # 23点到次日7点每2个小时执行一次,8点也执行一次
         hour    =>  '23-7/2,8'',
         minute  =>  0,
     }

    3.2.7 命令执行exec

    exec {'tar xf /tmp/nginx-1.3.8.tar.gz':     # 工作目录
         cwd =>  '/tmp',     # 仅当该文件不存的时候才执行这个exec
         creates =>  '/tmp/myfile',     # 定义环境变量
         path    =>  ['/usr/bin', '/usr/sbin', '/bin'],
     } 
     file {'/etc/aliases':
         source  => 'puppet://server/module/aliases'
     } exec {'newaliases':
         path    =>  ['/usr/sbin','/usr/bin','/bin'],
         subscribe   =>  File['/etc/aliases'],     # refreshonly指仅当依赖的对象被改变才会触发,需要和subscribe和notify结合使用才有意义
         refreshonly =>  True,
     }

    3.3 资源依赖与触发关系

    因为puppet读取清单中内容并不一定是按顺序读取,此时就需要定义先后和依赖关系

    依赖关系requirebefore

    file {'/etc/sshd/ssh_config':
         ensure  =>  file,
         require =>  Package['sshd'],
     }

    require:此时表示该文件的资源实现需要先满足sshd这个package资源,这里首字母要大写。 package {'sshd': ensure => installed, before => File['/etc/sshd/ssh_config], }

    before:表示pack befores file只需要写一个就可以确定先后顺序,符合自己的逻辑习惯即可

    触发关系notifysubscribe

    file {'/etc/sshd/ssh_config':
         ensure  =>   file,
         require =>   Package['sshd'],
         notify  =>   Service['sshd'],
     } service {'sshd':
         ensure  =>  running,
         subscribe   =>  File['/etc/sshd/ssh_config'],
     }

    notify:主动通知,当事件发生通知依赖的服务,当ssh_config这个文件修改会通知到service变化

    subscribe:订阅关系,当依赖的资源变动会引起自己的变动

    符号

    ->符号表示require依赖关系 ~>符号表示notify触发动作

    Package['sshd'] -> File['/etc/sshd/ssh_config'] ~> Service['sshd']

3.4 package,file,service

# ssh service为例package {'openssh-server':
    ensure  =>  present,
    before  =>  File['/etc/ssh/sshd_config'],
}    
file {'/etc/ssh/ssh_config':
    ensure  =>  file,
    source  => 'puppet://modules/ssh/sshd_config',
}service {'sshd':
    ensure  =>  running,
    enable  =>  true,
    subscribe   =>  File['/etc/ssh/sshd_config'],
}
  1. puppet的语法结构

4.1 条件判断

if $operatingsystem in  ['Ubuntu','debian'] {
        notify('Ubuntu system detected!')
    }
    elsif   $operatingsystem in ['Centos','Redhat','Fedora','SuSE'] {
        notify('Centos type system detected!')
    }    else {
        notify('Some other system detected!')
    }    case $operatingsystem {        'Solaris': { include role::solaris }        'RedHat','Centos': { include role::redhat },
        /^(debian|Ubuntu)$/: { include role::debian },
        default: { include role::generic }
    }    
    $rootgroup = $osfamily ? {        'Solaris'  =>   'wheel',
        /(Darwin|FreeBSD)/  =>  'wheel',
        default =>  'root',
    }

4.2 变量和作用域

puppet继续

一个类定义文件内容 来源于Learning puppet文件p41
# Class:  ntp# # This class installs/configures/manages NTP. It can optionaly disable NTP# on virtual machines. Only supported on Debian-derived and Red Hat-derivedOSes.## Parameters:#   - $servers:
        An array of NTP servers, with or without +iburst+ and
        +dynamic+ statements appended. Defaults to the OS's defaults.#   - $enable
        Whether to start the NTP service on boot. Defaults to true. Valid
        values: true and false.#   - $ensure
        Whether to run the NTP service. Defaults to running. Valid values:
        ruuning and stopped.## Requires:#   Nothing.## Sample Usage:#   class {'ntp':#       servers =>  ['ntp1.puppetlabs.lan dynamic",#                   'ntp2.puppetlabs.lan dynamic",],#   }#   class {'ntp':#       enable  =>  false,#       ensure  =>  stopped,#   }class ntp ($servers = undef, $enable = true, $ensure = running) {    case $operatingsystem {
        centos, redhat: {            $service_name   =   'ntpd'
            $conf_template  =   'ntp.conf.e1.erb'
            $default_servers= [ "0.centos.pool.ntp.org",                                "1.centos.pool.ntp.org",                                "2.centos.pool.ntp.org",
                                ]
        }
        debian, ubuntu: {            $service_name   =   'ntp'
            $conf_template  =   'ntp.conf.debian.erb'
            $default_servers= [ "0.debian.pool.ntp.org",                                "1.debian.pool.ntp.org",                                "2.debian.pool.ntp.org",
                                ]
        }
    }
    
    if $servers ==  undef {        $servers_real   =   $default_servers
    }
    else {        $servers_real   =   $servers
    }
    
    package { 'ntp':
        ensure  =>  installed,
    }
    
    service { 'ntp':
        name    =>  $service_name,        ensure  =>  $ensure,
        enable  =>  $enable,
        subscribe   =>  File['ntp.conf'],
    }
    
    file { 'ntp.conf':
        path    =>  '/etc/ntp.conf',        ensure  =>  file,
        require =>  Package['ntp'],
        content =>  template("ntp/${conf_template}"),
    }
}
template ERB语法

1 常规变量

如facter获取到operatingsystem

<%= @operatingsystem %> 是对其的值引用,@不用也可以,用了可以防止变量名冲突

对于超过本地作用域范围的变量,可以通过scope对象查找

<%= scope.lookupvar('apache::user') %>

2 判断

<% if @myvar %>
    my var has <%= @myvar %> value<% end %>

3 数组迭代

如$arr = ['1','2','a','b']
    <% arr.each do | val | -%>        array has value <%= val %>
    <% end -%>

这里<% -%>表示不解释后面跟着的换行,否则会多出两个换行

4 模板整合 pp文件中template(a,b)就行了

5 语法检查 erb文件可以通过如下方式检查语法规则

root@debian:/etc/puppet/modules# cat test/templates/test.erb%First hostname <%=  fqdn  %>

%Second<% if @operatingsystem %>
    the system is <%= @operatingsystem %>
<% end %>

%Third$arr = ['1','2','3']
<% arr.each do |val| -%>
    arr has value <%= val %>!
<% end -%>

root@debian:/etc/puppet/modules# erb -P -x -T '-' test/templates/test.erb | ruby -cSyntax OK# -P:忽略%开头的行 -x:打印出ruby script -T 指定trim mode,指定是否输出换行的模式
hiera

当manifest里面的pp文件中夹杂了太多判断,这个时候就需要通过定义变量的方式来自定义我们的配置文件,puppet的hiera机制实现最常用的几次匹配过滤,比如根据域名,比如根据操作系统,比如根据调用的模块等等。 这样,一个典型的catalog查询就开始比较复杂,具体过程如下: 建立连接后,puppet的一个agent开始向服务端请求自己的catalog,master开始做查询。首先检查对应的manifests的nodes节点下面的pp文件,按次序解释返回。当有hiera参与时,会首先在/etc/puppet/manifests/site.pp中加入hiera_include('classes')类似信息,来表示这个时候加入的类。 如果没有hiera,在nodes文件夹下对应的pp文件也可能是包含相应的模块和类,这都是一个追加的过程。在/etc/puppet/hiera.yaml文件中定义了几个过滤模块,具体可以参考官方文档的hiera部分,这里面其实是定义了过滤器和文件的对应关系。过滤器是并集,满足1的会执行,满足2的也会执行,是classes相加。最终这些文件yaml或json格式的内容会被读取,这些文件和nodes文件夹下的pp文件最终效果一样。大部分是对已有模块的参数说明。

以上可能有点虚,具体参考puppet结合nginx结合hiera的例子。