一、Puppet的定义
puppet:是一个IT基础设施自动化管理工具,它能帮助系统管理员管理基础设施的整个生命周期:供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting)
Puppet的工作模型:
puppet通过声明性,基于模型的方法进行IT自动化管理
定义:通过puppet的声明性配置语言定义基础设置配置的目标状态
模拟:强制应用改变的配置之前先进行模拟性应用:dry-run
强制:自动、强制部署达成目标状态,纠正任何偏离的配置
报告:报告当下状态及目标状态的不同,以及达成目标状态所进行的任何强制性改变
Puppet三层模型:
Configuration Language(配置语言)
Transactional Layer(定义事务)
Resource Abstraction Layer(资源抽象层)
Puppet的两种使用模式
1,单机使用模型:手动应用清单
2,master/agent模型
Puppet资源:
资源抽象的维度(RAL如何抽象资源的?)
类型:×××类似 属性的组件,例如:package、service、file;
将资源的属性或状态与其实现方式分离;
仅描述资源的目标状态,也即期望其实现的结果状态,而不是具体过程
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,
...
}
一个属性都不给不会报错,但是不会创建出来,一般只给ensure就可以创建出来
例如;grop{'mygrp':
name => 'mygrp',
ensure => present,
gid => 2000,
}
注意:type必须使用小写字符;title是一个字符串,在同一类型中必须唯一;
资源属性中的三个特殊的属性:
Namevar:可简称为name
ensure:资源的目标状态
Provider:指明资源的管理接口
资源类型:
1,group:
Manage group
属性:
name:组名,
gid:GID,
system:是否属于系统组,true or false,
ensure:目标状态,present/absent,
member:成员用户,
2,user:
Manage users
属性:
name:用户名,/
uid:UID,
gid:基本组ID,
groups:附加组,不能包含基本组,
comment:注释,
expiry:过期时间,
home:家目录,
shell:默认shell类型,
system:是否为系统用户,
ensure:present/absent,
password:加密后的密码串,
资源引用:
Type;['']
类型的首字母必须大写;
关系元参数:before/require
A before B:B依赖于A,定于在A资源中;
{
...
before => Type['B'],
...
}
B require A: B依赖于A,定义在B资源中;
{
...
require => Type['A'],
...
}
3,Package:
Manage package
属性:
ensure:installed,present,latest,absent,
name:包名,
source:程序包来源,仅对不会自动下载的相关程序包的privide有用,例如:rpm或dbkg
provider:指明安装方式
4,service
puppet describe service -s -m :查看service资源的简单介绍
Manage running service
属性:
ensure:running/true or stopped/false
enable:ture or false
name:
path:脚本的搜索路径,默认为/etc/init.d
hasrestart:
hasstatus:
start:手动定于启动命令,
stop:
status:
restart:可自定义,通常用于定义reload操作
5,file
Manage files
属性:
ensure:present、absent、file、directory、link
file:类型为普通文件,
link:类型为符号链接文件,必须由target属性指明其链接的目标文件,
directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否是递归复制,
path:文件路径,
source:源文件,
content:文件内容,
target:符号链接的目标文件,
owner:属主,
group:属组,
mode:权限,
atime/ctime/mtime:时间戳
资源有特殊属性:
名称变量
name可省略,此时将由title表示
ensure:
定义资源的目标状态
元参数:metaparameters
依赖关系:
before
require
通知关系:通知相关的其他资源进行刷新操作
notify
A notify B:B依赖于A,且A发生改变后会通知B;
{
...
notify => Type['B'],
...
}
subscribe
B subscribe A:B依赖于A,且B监控A资源的变化产生的事件;
{
...
subscribe => Type['A'],
...
}
示例:file{'test.txt':
path => '/tmp/test.txt',
ensure => file,
source => '/etc/fstab',
}
file{'test.symlink':
path => '/tmp/test.txt',
ensure => link,
target => '/tmp/test.txt'
require => File['test.txt'],
}
file{'test.dir':
path => '/tmp/test.dir',
ensure => directory,
source => '/etc/yum.repo.d/',
recurse => true,
}
示例2:service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service'
}
package{'httpd':
ensure=>true,
}
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']
6,exec:
Executes external commands. Any command in an `exec` resource **must** be able to run multiple times without causing harm --- that is, it must be *idempotent*.
**command** (*namevar*):要运行的命令;
cwd:The directory from which to run the command.
**creates**:文件路径,仅此路径表示的文件不存在时,command方才执行;
user/group:运行命令的用户身份;
path:The search path used for command execution. Commands must be fully qualified if no path is specified.
onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;
refresh:重新执行当前command的替代命令;
refreshonly:仅接收到订阅的资源的通知时方才运行;
cron:
Installs and manages cron jobs. Every cron resource created by Puppet requires a command and at least one periodic attribute (hour, minute, month, monthday, weekday, or special).
command:要执行的任务;
ensure:present/absent;
hour:
minute:
monthday:
month:
weekday:
user:以哪个用户的身份运行命令
target:添加为哪个用户的任务
name:cron job的名称;
示例:
cron{'timesync':
command => '/usr/sbin/ntpdate 172.16.0.1 &> /dev/null',
ensure => present,
minute => '*/3',
user => 'root',
}
notify:
Sends an arbitrary message to the agent run-time log.
属性:
message:信息内容
name:信息名称;
核心类型:
group: 组
user:用户
packge:程序包
service:服务
file:文件
exec:执行自定义命令,要求幂等
cron:周期性任务计划
notify:通知
二、Puppet的类
类:puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;
类可以被继承,也可以包含子类;
语法格式:
class NAME {
...puppet code...
}
class NAME(parameter1, parameter2) {
...puppet code...
}
可以为资源定义tag,格式:
type{'title':
...
tag => 'TAG1',
}
type{'title':
...
tag => ['TAG1','TAG2',...],
}
手动调用:
puppet apply --tags TAG1,TAG2,... FILE.PP
puppet variable:
$variable_name=value
三、实践出真知
1,定义一个redis类,并调用
class redis {
package {'redis':
ensure => installed,
}
file{'redis.conf':
ensure => file,
source => '/root/manifests/redis.conf',
path => '/etc/redis.conf',
owner => 'redis',
group => 'root',
mode => '0644',
}
service {'redis':
ensure => running ,
enable => true,
hasstatus => true,
hasrestart => true,
}
Package['redis'] -> File['redis.conf'] ~> Service['redis']
}
include redis #调用类
2,定义一个带参数的类,并调用类
class inspkg($pkg) { #定义一个带参数的类
package {'$pkg':
ensure => latest,
}
}
class {'inspkg': #调用类
pkg => 'nginx',
}
3,定义一个带默认参数的类
4,定义一个父类和子类,使得子类继承父类
5,如何创建一个redis模块(module)?
首先应该了解一下模块的相关定义:
MODULE NAME:模块名称,也即模块目录名称;模块名称只能以小写字母开头,可以包含小写字母、数字和下划线,但不能使用“main”或“settings”作为模块名
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/:当前模块的使用帮助或使用范例文件;
调用模块:puppet apply -v -e "include redis(模块名)"
调用模块的子类:puppet apply -v -e "include redis::master"
步骤:
1,首先创建一个redis模块目录及其相关子文件
mkdir -pv redis/{manifests,files,templates,lib,spec}
2,vim /redis/manifests/init.pp
3,vim /redis/manifests/master.pp
4,vim /redis/manifest/slave.pp
5,把调用的模板文件放到template目录中
6,把slave.pp中重读的file中的redis-master.pp放到/redis/file目录中
此时redis模块已经创建完成;使用puppet module list 可以查看
转载于:https://blog.51cto.com/13296660/2052680