puppet基础学习(二)
六、ResourceOrdering(资源定序)
使用变化参数before , require , notify , subscribe
catalog是对一个给定的系统的所有资源及关系的编译,在编译catalog时,除非我们指定资源的执行顺序,不然puppet是以其自己的顺序管理,大多数时候puppet指定适当的方式,例如puppet管理用户gigabyte应该存在和文件夹/home/gigabyte/bin应该存在并属于用户gigabyte时,puppet会自动指定一个关系,用户的管理先于文件夹,即先管理用户后再对文件夹bin进行管理,即puppet的隐式顺序关系。
有些资源的先后顺序,在puppet中没有做隐式指定(考虑到多变性及多样性),例如,管理某个package要存在并正确配置时,要优先于管理依赖其的某个服务要启动,这时候就需要我们手动给这些资源定序。
? before 引起一个资源被应用在一个指定的资源之前
? require 引起一个资源被应用在一个指定的资源之后
? notify 引起一个资源被应用在一个指定的资源之前(notify甚至在资源改变的时候生成一个刷新)
? subscribe 引起一个资源被应用在一个指定的资源之后(如果目标资源发生改变,订购的资源将会刷新)
上述的变化参数before、require、notify、subscribe的值都是目标资源的标题,标题可以以数组形式出现。
注意:跟在这些变化参数之后的资源首字母都要大写且是中括号,例如File、Package等
subscribe语句
vi sshd.pp #创建pp文件,填入下面代码 #修改配置文件后需要重启服务才能生效,所以有个subscribe的用法 file { '/etc/ssh/sshd_config': ensure => file, #确保是文件及存在 mode => 600, #这是权限设置 source => '/root/examples/sshd_config', #替换为此文件的内容,也可以用不同的URI指定一个文件 } service { 'sshd': ensure => running, enable => true, subscribe => File['/etc/ssh/sshd_config'], #注意此处的File是大写的,中括号中的内容是file中的标题 } 执行结果 [[email protected] ~]# puppet parser validate sshd.pp [[email protected] ~]# puppet apply --noop sshd.pp Notice: Compiled catalog for learn.localdomain in environment production in 0.40 seconds Notice: /Stage[main]/Main/File[/etc/ssh/sshd_config]/content: current_value {md5}1641e4ea9aabf5721392499ecc5bc5e8, should be {md5}405dcb3c00b4c7e518402769e81cb17f (noop) Notice: /Stage[main]/Main/Service[sshd]: Would have triggered 'refresh' from 1 events Notice: Class[Main]: Would have triggered 'refresh' from 2 events Notice: Stage[main]: Would have triggered 'refresh' from 1 events Notice: Finished catalog run in 0.79 seconds [[email protected] ~]# puppet apply sshd.pp Notice: Compiled catalog for learn.localdomain in environment production in 0.33 seconds Notice: /Stage[main]/Main/File[/etc/ssh/sshd_config]/content: content changed '{md5}1641e4ea9aabf5721392499ecc5bc5e8' to '{md5}405dcb3c00b4c7e518402769e81cb17f' Notice: /Stage[main]/Main/Service[sshd]: Triggered 'refresh' from 1 events Notice: Finished catalog run in 1.46 seconds [[email protected] ~]# ps -ef|grep sshd root 1876 1 0 09:41 ? 00:00:00 sshd: [email protected]/0 root 4138 1901 0 14:38 pts/1 00:00:00 grep sshd root 9018 1 0 11:53 ? 00:00:00 /usr/sbin/sshd #由执行时间可知已重启 #上述pp文件apply后将会改变/etc/ssh/sshd_config中的内容,并重启sshd服务
file资源的配置文件基于package资源,service资源需要使用配置文件的改变,因此有了如下模式:
package/file/service模式(很有用的一种指导思路,确保软件包安装,然后配置文件修改,最后重启服务)
在上面sshd.pp文件前添加package资源的代码,就形成了package/file/service模式,如下:
package { 'openssh-server': ensure => present, #确保包已安装 before => File['/etc/ssh/sshd_config'], #在此文件之前执行 } file { '/etc/ssh/sshd_config': ensure => file, #确保是文件及存在 mode => 600, #这是权限设置 source => '/root/examples/sshd_config', #替换为此文件的内容,也可以用不同的URI指定一个文件 } service { 'sshd': ensure => running, enable => true, subscribe => File['/etc/ssh/sshd_config'], #注意此处的File是大写的,中括号中的内容是file中的标题 }
七、Classes(类)
puppet中的类与面向对象的类无关,只是作为代码块的容器一样,方便调用。
类定义(Defining Classes)
用法如下:
class ntp { }
例如:直接执行puppet apply /root/examples/modules1-ntp1.pp没有效果,这句的作用只是让puppet知道定义的这个类。
[[email protected] ~]# more /root/examples/modules1-ntp1.pp # /root/examples/modules1-ntp1.pp class ntp { case $operatingsystem { centos, redhat: { #如果case的多个选项,用逗号隔开 $service_name = 'ntpd' $conf_file = 'ntp.conf.el' } debian, ubuntu: { $service_name = 'ntp' $conf_file = 'ntp.conf.debian' } } package { 'ntp': ensure => installed, } file { 'ntp.conf': path => '/etc/ntp.conf', ensure => file, require => Package['ntp'], source => "/root/examples/answers/${conf_file}" } service { 'ntp': name => $service_name, ensure => running, enable => true, subscribe => File['ntp.conf'], } }
类声明(Declaring Classes)
对于上述的类定义,需要类声明以后才能生效。
即,在上述的文件/root/examples/modules1-ntp1.pp末尾添加一句include ntp即可。
[[email protected] ~]# more /root/examples/modules1-ntp2.pp # /root/examples/modules1-ntp2.pp class ntp { case $operatingsystem { centos, redhat: { $service_name = 'ntpd' $conf_file = 'ntp.conf.el' } debian, ubuntu: { $service_name = 'ntp' $conf_file = 'ntp.conf.debian' } } package { 'ntp': ensure => installed, } file { 'ntp.conf': path => '/etc/ntp.conf', ensure => file, require => Package['ntp'], source => "/root/examples/answers/${conf_file}" } service { 'ntp': name => $service_name, ensure => running, enable => true, subscribe => File['ntp.conf'], } } include ntp 执行结果:原本ntp服务是关闭的,则可看出ntp.conf已被更改,且ntp进程启动了。 [[email protected] ~]# puppet apply /root/examples/modules1-ntp2.pp Notice: Compiled catalog for learn.localdomain in environment production in 3.05 seconds Notice: /Stage[main]/Ntp/File[ntp.conf]/content: content changed '{md5}7fda24f62b1c7ae951db0f746dc6e0cc' to '{md5}dc20e83b436a358997041a4d8282c1b8' Notice: /Stage[main]/Ntp/Service[ntp]/ensure: ensure changed 'stopped' to 'running' Notice: Finished catalog run in 4.57 seconds [[email protected] ~]# ps -ef|grep ntp ntp 10725 1 0 17:13 ? 00:00:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g root 10857 1901 0 17:13 pts/1 00:00:00 grep ntp
详细分析下lvmguide这个class
class lvmguide ( #注意这个小括号里面的是类参数,作用域是整个类文件,类参数$document_root、$port $document_root = '/var/www/html/lvmguide', #设置默认值为/var/www/html/lvmguide $port = '80', #设置默认值为80 ){ class { 'apache': #第一个看到的是这个class,模块化的好处就是方便所有类的调用,跟include的作用一样,是另一种。 default_vhost => false, } apache::vhost { 'learning.puppetlabs.vm': #声明了一个apache::vhost资源类型,并且给port和docroot属性传值 port => $port, docroot => $document_root, } file { '/var/www/html/lvmguide': ensure => directory, owner => $::apache::params::user, group => $::apache::params::group, source => 'puppet:///modules/lvmguide/html', recurse => true, require => Class['apache'], } }
八、Modules(模块)
如果resources和classes看成是原子和分子,modules可以看做变形虫(单细胞生物),第一个在puppet世界的独立生物,modules就是把前面所学的全包含,多节点任务时便于管理,为实现某个目标包含成一个模块,也利于puppet查找识别和其他人查看,也加强复用性,作为一个母版框架集合预写的代码模块化。
模块路径(Module Path)
modulepath变量定义了模块路径
(企业版)
默认配置文件路径:/etc/puppetlabs/puppet/puppet.conf
打印路径 <pre name="code" class="ruby"><pre name="code" class="ruby">[[email protected] ~]# puppet agent --configprint modulepath
/etc/puppetlabs/puppet/modules:/opt/puppet/share/puppet/modules
(开源版)
默认配置文件路径:/etc/puppet/puppet.conf
<pre name="code" class="ruby" style="font-size: 14px;">[[email protected] ~]# puppet agent --configprint modulepath
/etc/puppet/environments/production/modules:/etc/puppet/environments/common:/etc/puppet/modules:/usr/share/puppet/modules
上述命令除了打印路径外(查找在用的modules所在的文件夹),同时这些目录下的模块将变得可用
模块结构(Module Structure)
用tree命令查看module的基本目录结构的两层
[[email protected] ~]# ls /etc/puppetlabs/puppet/modules apache lvmguide [[email protected] ~]# tree -L 2 -d /etc/puppetlabs/puppet/modules/ /etc/puppetlabs/puppet/modules/ ├── apache │ ├── files │ ├── lib │ ├── manifests │ ├── spec │ ├── templates │ └── tests └── lvmguide ├── files ├── manifests └── tests 11 directories [[email protected] ~]#
创建并使用模块
1、创建目录
[[email protected] ~]# cd /etc/puppetlabs/puppet/modules [[email protected] /etc/puppetlabs/puppet/modules]# ls apache lvmguide [[email protected] /etc/puppetlabs/puppet/modules]# mkdir users #顶级目录都是模块的名称,即users模块 [[email protected] /etc/puppetlabs/puppet/modules]# mkdir users/{manifests,tests} #manifests一定要建 [[email protected] /etc/puppetlabs/puppet/modules]# ls apache lvmguide users [[email protected] /etc/puppetlabs/puppet/modules]# tree users #查看users目录结构 users ├── manifests └── tests 2 directories, 0 files
2、创建.pp文件
manifests 目录可以包含任何数量的.pp文件,但init.pp清单文件是main class,且文件里面class的命名要和模块的名字一样
vi users/manifests/init.pp #创建manifests目录下的pp文件,添加如下代码 class users { user { 'alice': #添加alice用户 ensure => present; } } 语法验证: [[email protected] /etc/puppetlabs/puppet/modules]# puppet parser validate users/manifests/init.pp [[email protected] /etc/puppetlabs/puppet/modules]#
3、使用.pp文件
声明类:使用include,如果类还没被声明,include函数会声明一个类,如果已被声明,则不作操作
这样可以安全的在多个地方使用include声明,如果一个类有依赖另一个类,直接在那个类include一次即可。
vi users/tests/init.pp#创建tests目录下的pp文件,添加如下代码 include users 应用: [[email protected] /etc/puppetlabs/puppet/modules]# puppet apply --noop users/tests/init.pp Notice: Compiled catalog for learn.localdomain in environment production in 0.36 seconds Notice: /Stage[main]/Users/User[alice]/ensure: current_value absent, should be present (noop) Notice: Class[Users]: Would have triggered 'refresh' from 1 events Notice: Stage[main]: Would have triggered 'refresh' from 1 events Notice: Finished catalog run in 0.51 seconds [[email protected] /etc/puppetlabs/puppet/modules]# puppet apply users/tests/init.pp#调用了类users Notice: Compiled catalog for learn.localdomain in environment production in 0.30 seconds Notice: /Stage[main]/Users/User[alice]/ensure: created Notice: Finished catalog run in 1.43 seconds [[email protected] /etc/puppetlabs/puppet/modules]# puppet resource user alice#可以看到alice用户已创建 user { 'alice': ensure => 'present', gid => '502', home => '/home/alice', password => '!!', password_max_age => '99999', password_min_age => '0', shell => '/bin/bash', uid => '502', } [[email protected] /etc/puppetlabs/puppet/modules]#
分类(Classification)
将指定的类应用到指定的节点
为确保能够应用到节点,需保证以下3点
a、在Puppet master上的模块存放文件下有个和class名称一样的module文件夹
(这里的class指的是init.pp里面的,例如上述中的users案例,模块目录是users,class也是users)
b、module有个文件init.pp在manifests文件夹下
c、init.pp文件包含了类的定义
企业版使用Puppet Enterprise Console,可以轻易的将多个模块组合运用,像配置lvmguide一样,前台添加配置如图:
开源版初级使用site.pp文件,深入后使用hiera.yaml,可惜的是没有图形界面,后期可以自己开发界面或者直接使用Foreman开源框架也自带节点分类器。
九、Forge and Module Tool(炼炉与模块工具)
炼炉与模块工具,the forge专门锻造puppetmodule的地方(暂时这么理解吧。。)
The Forge是puppet的社区团体整的模块的公共资源库,例如可以登录查看mysql相关的资源https://forge.puppetlabs.com/puppetlabs/mysql
puppet module工具的子命令是用命令行的方式,在forge中可以更加容易的查找、安装、管理模块。
子命令如下:
? list - 列出已安装的模块
? search - 查找Puppet Forge中的某个模块
? install - 从Puppet Forge或者释放包中安装某个模块
? upgrade - 升级某个模块
? uninstall - 卸载某个模块
? build - 建立一个模块释放包
? changes - 显示一个已安装的模块的修改的文件
? generate -生成新的模块的样板
下面是用法举例:
list
[[email protected] ~]# puppet module list --tree#以树的形式展现模块清单,此处不加tree也行 /etc/puppetlabs/puppet/modules ├─┬ puppetlabs-apache (v1.0.1) │ ├── puppetlabs-stdlib (v3.2.0) [/opt/puppet/share/puppet/modules] │ └── puppetlabs-concat (v1.0.0) [/opt/puppet/share/puppet/modules] ├── lvmguide (???) └── users (???) /opt/puppet/share/puppet/modules ├─┬ puppetlabs-postgresql (v2.5.0-pe2) │ ├── puppetlabs-stdlib (v3.2.0) │ ├── puppetlabs-firewall (v1.0.2) │ ├── puppetlabs-apt (v1.4.0) │ └── puppetlabs-concat (v1.0.0) ├── puppetlabs-pe_razor (v0.1.6) ├── puppetlabs-reboot (v0.1.4) └─┬ puppetlabs-pe_repo (v0.7.6) ├── puppetlabs-pe_staging (v0.3.1) └─┬ puppetlabs-puppet_enterprise (v3.2.0) ├── puppetlabs-inifile (v1.0.0) ├─┬ puppetlabs-pe_mcollective (v0.2.9) │ ├── puppetlabs-pe_accounts (v2.0.1) │ └── puppetlabs-java_ks (v1.2.0) ├─┬ puppetlabs-pe_puppetdb (v1.0.2) │ └── puppetlabs-pe_postgresql (v1.0.3) ├── puppetlabs-auth_conf (v0.2.1) ├── puppetlabs-request_manager (v0.1.0) └── puppetlabs-pe_console_prune (v0.1.0) [[email protected] ~]#<strong> </strong>
search
[[email protected] ~]# puppet module search puppetlabs-mysql #查找puppet forge中的模块 Notice: Searching https://forgeapi.puppetlabs.com ... NAME DESCRIPTION AUTHOR KEYWORDS puppetlabs-mysql Mysql module @puppetlabs mysql percona centos rhel ubuntu debian [[email protected] ~]# 上述亦可模糊匹配puppet module search mysql,搜到很多,一般模块名称是“作者-模块名”
install
[[email protected] ~]# puppet module install puppetlabs-mysql --version 2.2.2 Notice: Preparing to install into /etc/puppetlabs/puppet/modules ... Notice: Downloading from https://forgeapi.puppetlabs.com ... Notice: Found at least one version of puppetlabs-mysql compatible with PE (3.2.2); Notice: Skipping versions which don't express PE compatibility. To install the most recent version of the module regardless of compatibility with PE, use the '--ignore-requirements' flag. Notice: Found at least one version of puppetlabs-stdlib compatible with PE (3.2.2); Notice: Skipping versions which don't express PE compatibility. To install the most recent version of the module regardless of compatibility with PE, use the '--ignore-requirements' flag. Notice: Installing -- do not interrupt ... /etc/puppetlabs/puppet/modules └─┬ puppetlabs-mysql (v2.2.2) └── puppetlabs-stdlib (v3.2.0) [/opt/puppet/share/puppet/modules] #上述可看出不仅安装了puppetlabs-mysql,也安装了其依赖的puppetlabs-stdlib,puppetlabs-mysql默认安装在指定路径modulepath下 [[email protected] ~]# cd /etc/puppetlabs/puppet/modules/ #验证可知,已安装 [[email protected] /etc/puppetlabs/puppet/modules]# ls apache lvmguide mysql users
upgrade
[[email protected] ~]# puppet module upgrade puppetlabs-mysql #升级此包 Notice: Preparing to upgrade 'puppetlabs-mysql' ... Notice: Found 'puppetlabs-mysql' (v2.2.2) in /etc/puppetlabs/puppet/modules ... Notice: Downloading from https://forgeapi.puppetlabs.com ... Notice: Found at least one version of puppetlabs-mysql compatible with PE (3.2.2); Notice: Skipping versions which don't express PE compatibility. To install the most recent version of the module regardless of compatibility with PE, use the '--ignore-requirements' flag. Notice: Found at least one version of puppetlabs-stdlib compatible with PE (3.2.2); Notice: Skipping versions which don't express PE compatibility. To install the most recent version of the module regardless of compatibility with PE, use the '--ignore-requirements' flag. Notice: Upgrading -- do not interrupt ... /etc/puppetlabs/puppet/modules └── puppetlabs-mysql (v2.2.2 -> v2.2.3) [[email protected] ~]# 上述可知已升级,版本v2.2.2 升级成v2.2.3
uninstall
[[email protected] ~]#puppet module uninstall puppetlabs-mysql #卸载此包 Notice: Preparing to uninstall 'puppetlabs-mysql' ... Removed 'puppetlabs-mysql' (v2.2.3) from /etc/puppetlabs/puppet/modules [[email protected] ~]# cd /etc/puppetlabs/puppet/modules/ [[email protected] /etc/puppetlabs/puppet/modules]# ls apache lvmguide users
如果使用mysql模块,直接在清单文件中include‘::mysql::server‘
企业版支持的模块:https://forge.puppetlabs.com/supported
企业版支持的模块清单:https://forge.puppetlabs.com/modules?supported=yes
社区上面的的模块就体现了其复用性,模块可被下载使用
十、Glossary Of Puppet Vocabulary(名词解析)
名词解析 filebucket puppet替换文件时,用于存储备份文件的地方,可以在节点上,也可以在管理机器上。通常指定一个地方作为整个网络的备份点。似乎在site.pp上定义 Heiratool site.pp 经常位于/etc/puppet/manifests/site.pp,这个清单文件经常定义agent节点,以便其接受一个唯一的catalog noop 参数,是No Operations的缩写 notification +> 添加值到资源属性 plugin 通过module的形式实现 refresh 刷新,包括服务重新启动; 挂载点卸载或者重新挂载; execs 通常啥都不做, 但是会开始执行在属性refreshonly被设置后 title 资源类型或者class一被定义,$title变量在整个定义中就可用,title只是个引用 type (defined) 由本地类型结合的混合类型 type (native) 本地类型 virtual resource 在catalog里面声明的资源,不会应用到系统,除非显式实现。 |