类:class
用于公共资源的一组资源,是命名的代码块,创建互殴可在puppet全局进行调用,类可以被继承
语法资源:
class class_name {
...puppet code...
}
注意:类名只能包含小写字母、数字、下划线且必须以小写字母开头
类定义实例:
声明类方式:
1.include:include+类名可以以逗号相隔,声明多个类
2.require:require+类名
3.resource:class{‘类名’:里面还可以写一些属性}类似资源的调用,资源用type
4.ENC
1和3比较常用
类只有在声明之后才能被执行
定义能够接受参数的类
定义:
class 类名($arg1='value1',$arg2='value2'){
...code...
}
传参:
class{‘类名’:
arg1 =>'nginx'
}
类继承:
定义方式:
class base_class ::class_name inherits basee_class,父类名::类名,base_class ::class_name只是一个名字,本身没有继承功能,就行起名的时候带上父亲的名字一样
作用:
在于继承一个已有的类,并且实现覆盖资源属性,或向资源属性追加额外值
=> 覆盖 +>追加
类继承时:
1.声明子类时,其基类会被自动首先声明
2.基类成为子类的父作用域,基类的变量、属性默认被子类复制
3.子类可以覆盖父类中同一资源的相同属性值
这是一个类继承实例:
在子类中覆盖父类中已经定义的属性值
模板:
概念:
基于ERB模板语言,在静态文件中使用变量编程元素生成的适用于多种不同环境的文本文件(配置文件):Embedded RuBy,用于实现在文本文件中嵌入ruby代码,原本的信息不会改变,但是ruby代码会被执行。执行的结果会直接替换原来的代码。
<%= Ruby Expression %>:替换表的式值。
<% Ruby Expression %>:不替换表的式值。
<%# command %>:文本注释
<%% :输出<%
%%>:输出%>
在模板中可以使用变量,包括puppet任意可用变量,但是变量名使用@开头
条件判断:
<% if CONDITION -%>
some text
<% end %>
迭代:
<% @ArrayName.echo do | Variabnle_Name | -%>
some test with <% Variable_Name %>
<% end %>
模板调用实例:
配置nginx模板:
准备nginx配置模板,修改nginx配置的work_processes为变量 vim nginx.conf.erb worker_processes <%= @processorcount %>; 定义类 vim nginx.pp class nginx { package{'nginx': ensure => latest; } -> file{'/etc/nginx/nginx.conf': ensure => file, content => template('/root/nginx.conf.erb'), } ~> service{'nginx': ensure => running, } } include nginx 执行脚本 puppet apply nginx.pp
使用content指明模板文件的路径,直接生成这个文件内容,而template是puppet内置函数
模块:
模块就是一个按约定的、预定义的层级结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范;
puppet会在配置的路径下查找所需要的模块;
MODULES_NAME:
manifests/
模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main"和"settings“;
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;
2、无需在资源清单文件中使用import语句;
3、manifests目录下可存在多个清单文件,每个清单文件包含一个类,其文件名同类名;
puppet config命令:
获取或设定puppet配置参数;
puppet config print [argument]
puppet查找模块文件的路径:modulepath
puppet config print modulepath
set更改参数的值,以下命令更改后直接保存在配置文件里
可以查看这个网站提供的nginx模块
[root@localhost ~]# puppet module search nginx
Notice: Searching https://forgeapi.puppetlabs.com ...
从网上安装nginx模块
puppet module install nginx
模块管理命令:
自定义模块开发:
参加模块相关目录,注意路径结构
mkdir -pv /etc/puppet/modules/redis/{manifests,files,templates,lib,spec,tests}
建议先在其他路径下,如/root下创建一个modules模块,等模板都编辑完成后在拷贝到/etc/puppet/modules下。
mkdir -pv /root/modules/redis/{manifests,files,templates,lib,spec,tests}
把静态文件放到files里,模板文件(erb格式)放到templates里
cp /root/puppet/redis.module/redis-master.conf /root/modules/redis/files/
cp /root/puppet/redis.module/redis-slave.conf.erb /root/modules/redis/templates/
在manifests下定义和模块名同名的类,在init.pp里,同时定义master.pp和slave.pp的子类,模块方式注意文件的路径的定义有简化的
格式 和绝对路径两种,因为在模块下,文件放置的路径是固定的,所以,用相对路径就可以查找到配置文件模板的路径
source 定义模板的路径
source => 'puppet:///modules/MOD_NAME/FILE_NAME',
例子
source => 'puppet:///modules/redis/redis-master.conf',
等价于写绝对路径
source => '/etc/puppet/modules/redis/files/redis-master.conf',
content定义模板的路径
格式 content => template('MOD_NAME/ERB_FILE')
例子
content => template('redis/redis-slave.conf.erb'),
等价于写绝对路径
content => template('/etc/puppet/modules/redis/templates/redis-slave.conf.erb'),
vim /root/modules/redis/manifests/init.pp class redis { package{'redis': ensure => latest, } service {'redis': ensure => running, enable => true, hasrestart => true, restart => 'service redis restart', require => Package['redis'], } }
vim /root/modules/redis/manifests/master.pp class redis::master inherits redis { file{'/etc/redis.conf': ensure => file, source => '/etc/puppet/modules/redis/files/redis-master.conf', owner => redis, group => root, require => Package['redis'], } Service['redis']{ restart => 'systemctl restart redis', subscribe => File['/etc/redis.conf'], } }
#slave配置文件,这里利用变量来传递参数
vim /root/modules/redis/manifests/slave.pp class redis::slave($masterip,$masterport='6379') inherits redis { file{'/etc/redis.conf': ensure => file, content => template('/etc/puppet/modules/redis/templates/redis-slave.conf.erb'), owner => redis, group => root, require => Package['redis'], } Service['redis']{ restart => 'systemctl restart redis', subscribe => File['/etc/redis.conf'], } }
#注意修改配置文件如下
vim /root/modules/redis/templates/redis-slave.conf.erb slaveof <%= @masterip %> <%= @masterport %>
#目前目录结构如下
[root@CentOS7C modules]#tree
.
└── redis
├── files
│ └── redis-master.conf
├── lib
├── manifests
│ ├── init.pp
│ ├── master.pp
│ └── slave.pp
├── spec
├── templates
│ └── redis-slave.conf.erb
└── tests
文件都准备完成后,把redis整个模块放到对应的软件指定的目录/etc/puppet/modules/下
cp -r /root/modules/redis/ /etc/puppet/modules/
测试
查看模块
[root@CentOS7C ~]#puppet module list /etc/puppet/modules └── redis (???) /usr/share/puppet/modules (no modules installed)
redis模块后面显示为???,为redis的相关元数据信息,用来描述模块的,但是显示异常,忽略该情况
声明类
为哪个主机调用这个类,这里演示为当前主机调用,没有跨主机
注意,调用是指明类名,而不是指明模块
测试调用基类
puppet apply -v --noop -d --test -e "include redis"
测试调用子类,注意slave子类有变量,需要传递值
puppet apply -v --noop -d --test -e "include redis::master" puppet apply -v --noop -d --test -e "class {'redis::slave': masterip => '172.18.50.73', masterport => '6379',}"
执行
puppet apply -e "include redis::master" puppet apply -e "class {'redis::slave': masterip => '172.18.50.73', masterport => '6379',}"