一、简介1、puppet是一个IT基础设施自动化管理工具,puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。基于puppet,实现自动化重复工作,快速部署关键性应用及本地或云端管理更改。基于ruby开发对于管理员是抽象的,依赖于ruby和facter。管理内容丰富,包括file、user、group、host、package、service、cron、exec、yumrepo等。使用模型:单机环境创建.pp文件申报资源归为类目录:模块分布式使用,master/agent2、puppet基本执行流程puppet modules:puppet 模块,功能类似于变量,可以被puppet多次调用,这个也是puppet的核心设置,模块中保存的是“类”,而“类”中定义的是资源。目前可以通过网站下载相关的功能模块,减少了开发难度。(https://forge.puppet.com),puppet模块位于master端(服务器端),master端同样还定义了node,就是被管理的客户端(agent)节点,node里面定义了适用的class,而不是模块,这里要注意。而agent(客户端)则通过自身的facter程序反馈给master自己的信息(客户端的ip、系统等相关信息),master收到agent的facter信息后会将适用于它 的node配置转成catalog信息,并推送到agent端。由于puppet的master和agent是基于“https”协议进行通信的,所以在大企业中也往往在master前端布置一个nginx或者haproxy进行反向代理,实现负载均衡功能。版本控制工具cvs—》svn———》gitpuppet的文件1、资源清单文件,.pp后缀,用于定义资源所在的位置的文件。二、安装2.6属于废弃的版本,应该使用2.7或者3.3。我这里是centos6.7,使用的是2.7

1、安装更新puppet的仓库

[root@localhost yum.repos.d]# rpm -Uvh --force  https://yum.puppetlabs.com/puppetlabs-release-pc1-el-6.noarch.rpm

Retrieving https://yum.puppetlabs.com/puppetlabs-release-pc1-el-6.noarch.rpm

warning: /var/tmp/rpm-tmp.laVV75: Header V4 RSA/SHA1 Signature, key ID ef8d349f: NOKEY

Preparing...                ########################################### [100%]

   1:puppetlabs-release-pc1 ########################################### [100%]


2、安装puppetserver

[root@localhost yum.repos.d]# yum install puppetserver



三、配置文件1、帮助信息

[root@localhost ~]# puppet help


Usage: puppet [options] [options]


2、获取特定选项的帮助信息

[root@localhost ~]# puppet help apply


USAGE

-----

puppet apply [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose]

  [-e|--execute] [--detailed-exitcodes] [-L|--loadclasses]

  [-l|--logdest syslog|eventlog||console] [--noop]

  [--catalog ] [--write-catalog-summary]



四、基本用法显示资源类型:常见的group 、user、pickage、notify、mount、cron、exec、file、yumrepo、service、user。

[root@localhost ~]# puppet describe --list

These are the types known to puppet:

augeas          - Apply a change or an array of changes to the  ...

computer        - Computer object management using DirectorySer ...

cron            - Installs and manages cron jobs

exec            - Executes external commands

file            - Manages files, including their content, owner ...

filebucket      - A repository for storing and retrieving file  ...

group           - Manage groups


puppet基本的数据类型:字符型:直接字符串,需要引号数组:[‘elemenet1’,’element2’]布尔型:不能加引号,true、false。undef:hash:(应用不多)正则表达式:(?<标志位>:<正则表达式>)或者(?-<标志位>:<正则表达式>),常常应用于case和selector场景中。标志位:!:不区分大小写m:把”.”当做换行符使用x:忽略模式中的空白字符和注释,如果不使用其中的某个标志位可以使用“-”去除。样例理解:通过facter来收集系统信息,并判断是什么系统,最终输出信息。

[root@localhost ~]# vim test.pp


$package = $operatingsystem ? {

        /(?i-mx:^(Centos|fedar|redhat))/ => "httpd",

        /(?i-mx:^(debian|ubuntu))/ => "apache2",

        }


notify {"notify":

        message => "install $package",

}

~               

[root@localhost ~]# vim test.pp

[root@localhost ~]# puppet apply test.pp 

Notice: Compiled catalog for localhost.localdomain in environment production in 0.10 seconds

Notice: install httpd

Notice: /Stage[main]/Main/Notify[notify]/message: defined 'message' as 'install httpd'

Notice: Applied catalog in 0.04 seconds


常见操作符:五、puppet的条件判断语句2.7:if、case、selector3.0:if、case、selector、unless

if语句判断依据是条件表达式结果的布尔类型,如果为true就执行,如果为false就执行另一个命令。
实例:

[root@localhost ~]# vim notify.pp


$old = 21

if $old > 30 {

        notice ("old man")

}       else {

        notice ("young man")

}


$eld = 34

if $eld > 30 {

        notify {"old man":}

}       else {

        notify {"young man":}

}

[root@localhost ~]# vim notify.pp

[root@localhost ~]# puppet apply notify.pp 

Notice: Scope(Class[main]): young man

Notice: Compiled catalog for localhost.localdomain in environment production in 0.11 seconds

Notice: old man

Notice: /Stage[main]/Main/Notify[old man]/message: defined 'message' as 'old man'

Notice: Applied catalog in 0.04 seconds


实例2:通过正则表达式判断系统,然后安装web服务程序。

[[email protected] ~]# vim yumwebapp.pp 


if $operatingsystem =~ /(?!-mx:^(centos|fedra|redhat))/ {

        $webserver = "httpd"

} elsif $operatingsystem =~ /(?!-mx:^(debian|ubuntu))/ {

        $webserver = "apache2"

} else {

        $webserver = undef

        notice ("unknow os")

}


package {"$webserver":

        ensure => installed,

}

[[email protected] ~]# puppet apply yumwebapp.pp 

Notice: Compiled catalog for node7.dtedu.com in environment production in 0.78 seconds

Notice: /Stage[main]/Main/Package[httpd]/ensure: created

Notice: Applied catalog in 3.04 seconds


case判断语句基本使用方法:

[[email protected] ~]# vim case.pp


case $operatingsystem {

        "centos": {notice ("welcome to centos system")}

        'redhat','fedora': {notice ("welcome to redhat famly")}

        /^(centos|ubuntu)$/: {notice ("welcom to debian")}

        default: {notice ("i do not konw you!")}

}



selector只用用于出现直接值的地方,就是一个条件判断并赋值的功能。 表达式格式:
实例: 使用要点: 六、puppet本地使用实例
1、创建资源类型基本格式

type { "title":

        attribute => value,

     }  


1.1本地安装nginx,执行命令通过puppet apply nginx.pp来进行。

[root@localhost ~]# puppet describe package help


package { "nginx":

        ensure => installed,

        }


[root@localhost ~]# puppet apply nginx.pp 

1.2定义nginx服务启动起来。

package { "nginx":

        ensure => installed,

        }


service {"nginx":

        ensure => true,

        }


1.3定义group资源

[root@localhost ~]# vim group.pp


group {"mysqld":

        ensure => "present",

        gid => 1001,

        }


1.4定义用户资源,密码需要事先加密,并且如果有$,则需要加引号

[root@localhost ~]# vim user.pp


user {"mysql":

        gid =>"1001",

        groups => "root",

        home => "/home/mysql”,

passwd => “Y0Z07VW9DPvow"

        managehome => "true",

}


创建shadow内使用的加密密码

[root@localhost ~]# openssl passwd 

Password: 

Verifying - Password: 

Y0Z07VW9DPvow


1.5定义file资源,可用的文件类型file、present、directory、link。

[root@localhost ~]# vim file.pp 


file {"/root/nginx.conf":

        ensure => "file",

        source => "/etc/nginx/nginx.conf",

        owner => "root",

        group => "mysqld",

        mode => "0644",

        }



1.6定义exec资源,执行chkconfig命令。

[root@localhost ~]# vim exec.pp


exec {"test":

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

        command => “chkconfig —add nginx;chkconfig nginx on",

        user => "root",

}


七、资源间依赖关系puppet提供了before、require、notify、subscribe四种元参数来定义资源间的依赖关系。这四个元参数都以另外的其他资源或资源组作为其值,所以也称为资源引用。如果是继承的类使用依赖,符号是:+>资源引用, 引用时类型的首字母必须大写。 定义方式: before => 类型[“资源名称”]:表示引用资源之前先要保证自身没有问题。 require => 类型[“资源名称”]:表示先引用资源,再执行本身的资源。
notify =>  类型[“资源名称”]:表示通知,将结果通知到后面的资源名中并执行。通常适用于服务的配置文件变更情况。 subscribe => 类型[“资源名称”]:表示订阅,接受到资源名称变化后执行。

[root@localhost ~]# vim nginx.pp 


package { "nginx":

        ensure => installed,

        }


service {"nginx":

        ensure => true,

        require => Package["nginx"],

        }


[root@localhost ~]# vim file.pp 


file {"/etc/nginx/nginx.conf":

        ensure => "file",

        source => "/etc/nginx/nginx.conf.old",

        owner => "root",

        group => "mysqld",

        mode => "0644",

        notify => Service["nginx"],

        }


service {"nginx":

        ensure => "running",

        }


资源间的应用次序链“->”用来定义次序链,通常左侧的被右侧的依赖。“~>”用来定义通知链他们既可以用户资源间引用,可以用于资源申报之间。puppet的变量1、名称以“$”开头,赋值操作符是“=”,可以使用任何数值类型。2、变量有其作用域。3、变量名称通常使用$scope::variable的形式,如果引用顶级作用域的变量,就是$::variable了,因为通常顶级作用域没有名称。scope用于标识一个特定的代码区域,用于同程序中的其他代码隔离开来。在puppet中,scope可用于限定变量及资源默认属性的作用范围,但不能用于限定资源名称及资源引用的生效范围。当前作用域只能引用其父作用域,节点作用域、顶级作用域的变量。
八、puppet类1、定义:用于通用目的的一组资源,他是命名的代码块,在某个位置创建后可以在puppet全局使用,并可以被继承。2、声明类的方法(类似调用)include:最简单requireresource:可以声明class的属性3、通用格式:class myclass_name {puppet code…….}include myclass_name实例:

class yumweb {

        if $operatingsystem =~ /(?!-mx:^(centos|fedra|redhat))/ {

                $webserver = "httpd"

        } elsif $operatingsystem =~ /(?!-mx:^(debian|ubuntu))/ {

                $webserver = "apache2"

        } else {

                $webserver = undef

                notice ("unknow os")

        }


        package {"$webserver":

                ensure => installed,

        }

}

include yumweb

# resource {“yumweb”:}


4、类的继承在原有类的基础上,增加一些的功能,就是继承。

[[email protected] ~]# vi nginx.pp 


class nginx {

        package {"nginx":

                ensure => present,

        }

}

class nginx::rproxy inherits nginx {

        file {"/etc/nginx/nginx.conf":

                ensure => "file",

                mode => "0644",

                group => "root",

                owner => "root",

                source => "/etc/nginx/nginx.conf.old",

                require => Package["nginx"],

        }

        service {"nginx":

                ensure =>"start",

                subscribe => File["/etc/nginx/nginx.conf"],

        }

}



class nginx::websrv inherits nginx {

        file { "/etc/nginx/nginx.conf":

                ensure => file,

                mode =>0644,

                group =>root,

                user =>root,

                source => "/etc/nginx/nginx.conf.new",

                require => Package["nginx"],

        }

        service {"nginx":

                ensure =>"start",

                subscribe => File["/etc/nginx/nginx.conf"],

        }

}


#include nginx

#include nginx::websrv

include nginx::rproxy


九、puppet模块1、定义:预先定义、约定的一组目录及文件结构如果puppet是master模式,就需要使用 puppet master —genconfig来定义,并且模块的存放位置也是可以定义的。

[[email protected] ~]# puppet master --genconfig |grep basemodulepath

    basemodulepath = /etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules


2、目录结构:

  • MODULE_NAME

    • manifests资源清单,用来存放各种类,资源的.pp文件,清单列表文件init.pp是必须存在的,且只能包含一个单独的类定义,且类的名称必须和模块名称相同。资源文件的访问方式:modulename::[subdirectoryname::]manifestfilename。

    • files用来存放file资源调用的文件,方式方式:puppet:///modules/module_name/filename。

    • templates存放模板文件,以下都不常用。

    • lib存放插件文件

    • tests存放测试文件

    • spec

3、创建自定义的模块

[[email protected] ~]# mkdir /opt/puppetlabs/puppet/modules/nginx/{manifests,file,lib,tests,spec,templates} -pv

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/manifests"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/files"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/lib"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/tests"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/spec"

mkdir: 已创建目录 “/opt/puppetlabs/puppet/modules/nginx/templates"


[[email protected] ~]# mv /etc/puppetlabs/puppet/modules/* /opt/puppetlabs/puppet/modules/ 

[[email protected] ~]# puppet module list

/etc/puppetlabs/code/environments/production/modules (no modules installed)

/etc/puppetlabs/code/modules (no modules installed)

/opt/puppetlabs/puppet/modules

└── nginx (???)


4、module的nginx下创建init.pp文件。这里的类名称必须和模块名相同。

[[email protected] /opt/puppetlabs/puppet/modules/nginx/manifests]# vim init.pp 


class nginx {

        package {"nginx":

                ensure => present,

        }

}

class nginx::rproxy inherits nginx {

        file {"/etc/nginx/nginx.conf":

                ensure => "file",

                mode => "0644",

                group => "root",

                owner => "root",

                source => "puppet:///modules/nginx/nginx.conf.old”,这里的路径指的是file目录下。

                require => Package["nginx"],

        }

        service {"nginx":

                ensure =>"running",

                restart => true,

                subscribe => File["/etc/nginx/nginx.conf"],

        }

}



class nginx::websrv inherits nginx {

        file { "/etc/nginx/nginx.conf":

                ensure => file,

                mode =>0644,

                group =>root,

                user =>root,

                source => “puppet/modules/nginx/nginx.conf.new",

                require => Package["nginx"],

        }

        service {"nginx":

                ensure =>"running",

                subscribe => File["/etc/nginx/nginx.conf"],

        }

}


#include nginx

#include nginx::websrv


include nginx::rproxy


[[email protected] /opt/puppetlabs/puppet/modules/nginx]# ll file/

总用量 8

-rw-r--r-- 1 root root 3004 6月  20 10:47 nginx.conf.new

-rw-r--r-- 1 root root 3004 6月  20 16:16 nginx.conf.old


站点清单(master/agent模型)实现此模块需要先安装puppetserver程序(我这里已经安装完毕了)。站点清单格式:site.ppnode 'FQDN' {include class}1、在puppet目录下创建manifests目录并创建site.pp文件,通过site.pp文件调用puppet里面的资源。

[[email protected] /opt/puppetlabs/puppet/modules/nginx/files]# vim /etc/puppetlabs/puppet/manifests/site.pp


node 'node7.dtedu.com' {

        include nginx


}

高级技巧:可以将本地模块的init.pp最简单话定义,也就是指定义一个类,然后再定义其他的类来引用它,并在站点清单中直接引用。

[[email protected] /opt/puppetlabs/puppet/modules/nginx/files]# vim /etc/puppetlabs/puppet/manifests/site.pp


node 'node7.dtedu.com' {

        include nginx:nginxserver


}

3、下载模块

[[email protected] ~]# puppet module search nginx

Notice: Searching https://forgeapi.puppet.com ...


安装模块

[[email protected] /opt/puppetlabs/puppet/modules/nginxtest]# puppet module install puppet-nginx

Warning: Setting configtimeout is deprecated. 

   (at /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/settings.rb:1159:in `issue_deprecation_warning')

Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...

Notice: Downloading from https://forgeapi.puppet.com ...

Notice: Installing -- do not interrupt ...

/etc/puppetlabs/code/environments/production/modules

└─┬ puppet-nginx (v0.6.0)

  ├── puppetlabs-apt (v2.4.0)

  ├── puppetlabs-concat (v2.2.1)

  └── puppetlabs-stdlib (v4.17.1)

You have new mail in /var/spool/mail/root


十、puppet/master 1、创建master端的配置文件

[[email protected] /root]# puppet master --genconfig >/etc/puppetlabs/puppet/puppet.conf


2、启动master服务,教程上是service puppetmaster start,但我这里没有实现,我使用的是puppet master启动。首次启动要按照以下格式启动。

[[email protected] /root]# puppet master --no-daemonize --debug --verbos

[[email protected] /root]# puppet master start

3、客户端安装puppet-agent程序,并使用唯一的主机名,然后使用以下命令注册puppet,并生成CA证书。这里的node7.dtedu.com域名要求注册可以在公网使用。(如果是在互联网上使用puppet的话)

[[email protected] ~]# puppet agent --server node7.dtedu.com --no-daemonize --debug --verbos


4、服务器端对客户端请求进行签发

[[email protected] /opt/puppetlabs/puppet/modules/nginxtest/manifests]# puppet cert --sign --all

Warning: Setting configtimeout is deprecated. 

   (at /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/settings.rb:1159:in `issue_deprecation_warning')

Signing Certificate Request for:

  "node6.dtedu.com" (SHA256) 29:8C:4A:C8:86:F7:CC:61:D7:1D:18:94:43:24:0D:FD:C3:83:0E:FC:2B:D7:E5:6B:93:D4:A2:9C:F4:69:BF:9B

Notice: Signed certificate request for node6.dtedu.com

Notice: Removing file Puppet::SSL::CertificateRequest node6.dtedu.com at '/etc/puppetlabs/puppet/ssl/ca/requests/node6.dtedu.com.pem'


要点: 1、客户端同步必须使用服务器的域名而不能是ip地址。 2、如果删除证书要在服务器端进行过期和删除操作,客户端删除ssl目录下的所有文件。 3、保证服务器端和客户端时间一致。         4、服务器配置文件及环境做如下设置: puppet.conf配置文件:

[main]

certname = node1.dtedu.com

server = node1.dtedu.com

environment = production

runinterval = 1h

strict_variables = true

对应的module目录中存放class类文件及site.pp文件。

[root@node1 nginxtest]# tree -L 2 /etc/puppetlabs/code/environments/production/

/etc/puppetlabs/code/environments/production/

├── environment.conf

├── hieradata

├── manifests

│   └── site.pp

└── modules

    └── nginxtest


客户端同步更新方式:1、手动更新,使用命令puppet agent —server hostname的方式。2、自动更新客户端的puppet.conf文件中添加server = servername客户端启动puppet服务 service puppet start服务器端实现自动签发CA证书。

Master端证书的管理

  1. 1.         master上查看申请证书请求

puppet cert --list

  1. 2.         签发证书

puppet cert --sign node1.zhang.com

如果一次性签发所有的证书,采用如下命令:

puppet cert --sign –all

也可以设置自动签发证书。

  1. 3.         让证书过期

puppet cert -revoke puppet-test

删除证书

puppet cert --clean puppet-test

证书签名的过期或删除需要重启puppetmaster服务。

  1. 4.         可以通过/etc/puppet/auth.conf文件配置签名的ACL列表。


puppet中文wiki: http://puppet-manifest-share.googlecode.com/files/vmx_puppet.tgzpuppet官网文档: https://docs.puppet.com/puppet/4.10/config_file_main.html#example-agent-configpuppet开源软件地址: https://puppet.com/download-open-source-puppet