1、Puppet:简介
OS Provision:
bare metal:pxe, cobbler
virtual machine:image file template
Configuration:
ansible(agentless)
puppet(master/agent) (ruby)
saltstack (python)
command and control:
ansible
fabric
func
...
https://puppet.com/products/open-source-projects
https://yum.puppet.com/
ruby语言研发
2、puppet工作模型:
单机模型(standalone):手动应用清单(定义相关配置,又叫做资源,清单文件以.pp结尾)
puppet apply
master/agent:由agent周期性的向Master请求清单并自动应用与本地
master:puppet master
agent: puppet agent
单机模型:
程序环境:
配置文件:/etc/puppet
puppet.conf
主程序:/usr/bin/puppet
3、 puppet程序:
puppet <subcommand子命令> [options] <action> [options]
help Display Puppet help. 查看子命令
apply Apply Puppet manifests locally
facts Retrieve and store facts.
module Creates, installs and searches for modules on the Puppet Forge.
man Display Puppet manual pages.
describe Display help about resource types 定义核心资源怎么使用
# puppet describe --list
puppet help <subcommand>
# puppet help resource
# puppet help resource-type
puppet help <subcommand> <action>
puppet apply:
Applies a standalone (单机模式)Puppet manifest to the local system.
puppet apply [-v|--verbose] [-d|--debug] [--noop] [--execute] <manifest_file>
4、puppet资源:
资源抽象的纬度(RAL是如何抽象资源的?):
类型:具有类似属性的组件,例如user, group, package等;
将资源的属性或状态主与其实现方式分离
仅描述资源的目标状态,也即期望其实现的结果,而不是具体过程;
RAL由“类型”和提供者(Provider);
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,
......
}
注意:type必须使用小写字符;title标识的名字,是一个字符串,在同一类型必须惟一;
如果是group tom,user tom是可以的,但是不可以有两个组或者用户同时为一个名字;
获取puppet支持所有资源类型及其说明:
puppet describe -l
获取特定类型的简要参数列表信息:
puppet describe -s <type>
获取特定类型的参数列表详细信息:
puppet describe <type>
获取特定类型的简要元参数列表信息:
puppet describe -s -m <type>
5、资源的三类特殊属性:
名称/名称变量:
Namevar,可简称为name,可由title表示;
ensure:
定义资源的目标状态;
present(创建)/absent(删除)
Provider:指明资源的管理接口,可以不用特意在指定
aix,directoryservice,groupadd,ldap(目录服务中),pw,
windows_adsi(Windows接口)
元参数:
依赖关系:
before
require
通知关系:
notify
subscribe
次序链:->
通知链:~>
system:是否为系统组
true/flase/yes/no
资源引用:
Type['title'],title可以直接默认为namevar值
属性的次序不重要
6、常用类型:
核心类型:
group: 组
user:用户
packge:程序包
service:服务
file:文件
exec:执行自定义命令,要求幂等
cron:周期性任务计划
notify:通知
notify:
Sends an arbitrary message to the agent run-time log.
向终端终端发送一个自定义信息,在我们自己某些条件触发时放在日志文件中来提醒用户
message:要发送的通知消息内容;
name:消息名称;
group:
Manage groups.
name:组名;
gid: GID;不添加则以最大ID号加一
ensure:目标状态present/absent;
system:是否为系统组;true,false,yes,no 布尔型值不能加引号
group{'distros':
gid => 2001,
ensure => present,
system => false,
}
6、user:
Manage users.
name:用户名;
uid:UID;有默认值
gid:基本组ID;
groups:附加组,不能包含基本组;
comment:注释;
expiry:过期时间;
home:家目录路径;有目录名
password:加密后的密码串;
password_min_age:
shell:用户默认的shell;有默认值
system:是否为系统用户;
managehome: Whether to manage the home directory when managing the user.
ensure:present/absent;
managehome:是否创建家目录,true,false
keys:秘钥信息
资源引用:
type{'title'
attribute => value,
...
}
Type['title'] 引用
before,require
类型的首字母必须大写;
关系元参数:before/require
A before B: B依赖于A,定义在A资源中;
{
...
before => Type['B'],
...
}
B require A: B依赖于A,定义在B资源中;
{
...
require => Type['A'],
...
}
7、cron:
Installs and manages cron jobs.
command:要执行的任务;
ensure:present, absent;
hour:
minute:
monthday:
month:
weekday:
user:添加至哪个用户;
name:cron job的名称;
示例:
cron{'timesync':
command => '/usr/sbin/ntpdate 172.16.0.1 &> /dev/null',
ensure => present,
minute => '*/3',
user => 'root',
}
8、package:
Manage packages.
name:The package name.
ensure:installed, present, latest, absent
source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg
provider:指明安装方式;
9、service:
Manage running services.
enable:true, false, manual
ensure:确定服务的相关状态. running, true; stopped, false;
hasrestart:是否支持重启,true/false,默认为false,尽量为true
hasstatus:判定目标服务状态
name:启动服务的名字
path:init scripts搜索路径;默认为/etc/rc.d/init.d/
start:手动定义启动命令
restart:用户手动指定的restart操作,通常用于定义reload操作;
10、file:
Manages files, including their content, ownership, and permissions.
ensure:present,absent, file, directory, link
present:存在
absent:删除
file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制![clipboard.png](http://upload-images.jianshu.io/upload_images/6854899-1882803f5702863a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
[图片上传中...(clipboard4.png-726a1-1512046880260-4)]
,
recurselimit递归复制的深度;
content:直接给定的文件内容;
path:文件路径;可使用puppet url来实现远程复制;
source:源文件;
target:符号链接的目标文件的;
owner:属主;
group:属组;
mode:权限;
atime/ctime/mtime:时间戳
replace:如果文件存在并且与定义的目录不一样,是否要替换
资源有特殊属性:
名称变量(namevar):
name可省略,此时将由title表示;
ensure:
定义资源的目标状态;
元参数:metaparameters
依赖关系:
before
require
通知关系:通知相关的其它资源进行“刷新”操作;
notify
A notify B:B依赖于A,且A发生改变后会通知B;B会刷新
{
...
notify => Type['B'],
...
}
subscribe
B subscribe A:B依赖于A,且B监控A资源的变化产生的事件;通知关系
{
...
subscribe => Type['A'],
...
}
示例1:
file{'test.txt':
path => '/tmp/test.txt',
ensure => file,
source => '/etc/fstab',
}
file{'test.symlink':
path => '/tmp/test.symlink',
ensure => link,
target => '/tmp/test.txt',
require => File['test.txt'],
}
file{'test.dir':
path => '/tmp/test.dir',
ensure => directory,
source => '/etc/yum.repos.d/',
recurse => true,
}
示例2:
service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service',
# subscribe => File['httpd.conf'],
}
package{'httpd':
ensure => installed,
}
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']
exec:
执行外部命令,必须保证命令是幂等的并且没有伤害性
类似于Ansible中的command和shell
command:namevar,要运行的命令;
cwd:运行命令的工作目录;
user/group:运行命令的用户身份;
onlyif:此处指定的命令运行成功方会运行command指明的命令;
path:命令的搜索路径;The search path used for command execution. Commands must be
fully qualified if no path is specified.
refresh:重新执行当前command的替代命令;
refreshonly:仅接收到订阅的资源通知时方才运行;
**creates**:文件路径,仅此路径表示的文件不存在时,command方才执行;
onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;
4、应用资源清单
puppet apply [option] file
-h help;
-V --version
-d 输出调试详细信息
-v 输出详细信息
-e 执行此处所直接给出的命令
-l 记录在日志文件中
--noop 干跑模式
# puppet appl -l /tmp/mainfest.log mainfest.pp
# puppet apply --modulepath=/root/dev/modules -e "include ntpd::server"
# puppet apply --catalog catalog.json
5、puppet variable:
$variable_name=value
puppet中的变量不管是定义还是引用都要加$符号
数据类型:
字符型:引号可有可无;但单引号为强引用,双引号为弱引用;
数值型:默认均识别为字符串,仅在数值上下文才以数值对待;
数组:[]中以逗号分隔元素列表;
布尔型值:true, false;
hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;{ 'mon' => 'Monday', 'tue' => 'Tuesday', };
undef:未定义 ;
正则表达式:
(?<ENABLED OPTION>:<PATTERN>) 启用这个属性
(?-<DISABLED OPTION>:<PATTERN>) 禁用这个属性
OPTIONS:
i:忽略字符大小写;
m:把.当换行符;
x:忽略<PATTERN>中的空白字符
(?i-mx :PATTERN)
不能赋值给变量 ,仅能用在接受=~或!~操作符的位置;
puppet的变量种类:
facts:
由facter提供;top scope;
#facter -p 如果主机已经被puppet获取,可以显示出它的內建变量
内建变量:
master端变量
$servername, $serverip, $serverversion
agent端变量
$clientcert, $clientversion, $environment
parser变量
$module_name
用户自定义变量:
变量有作用域,称为Scope;
top scope: $::var_name ::代表从根开始
node scope
class scope
6、puppet流程控制语句:
if语句:
if CONDITION {
...
} else {
...
}
CONDITION的给定方式:
(1) 变量
(2) 比较表达式
(3) 有返回值的函数
if $osfamily =~ /(?i-mx:debian)/ { 模式左右要加/,内部模式要用小括号括起来,以问号开头
$webserver = 'apache2'
} else {
$webserver = 'httpd'
}
package{"$webserver":
ensure => installed,
before => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf':
path => '/etc/httpd/conf/httpd.conf',
source => '/root/manifests/httpd.conf',
ensure => file,
}
service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}
$osfamily == 'RedHat'
$osfamily == $myos
![clipboard2.png](http://upload-images.jianshu.io/upload_images/6854899-01757c692278e095.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
case语句:
case CONTROL_EXPRESSION {
case1: { ... }
case2: { ... }
case3: { ... }
...
default: { ... }
}
CONTROL_EXPRESSION:
(1) 变量
(2) 表达式
(3) 有返回值的函数
各case的给定方式:
(1) 直接字串;
(2) 变量
(3) 有返回值的函数
(4) 正则表达式模式;
(5) default
case $osfamily {
"RedHat": { $webserver='httpd' } 精确匹配RedHat
/(?i-mx:debian)/: { $webserver='apache2' }
default: { $webserver='httpd' }
}
package{"$webserver":
ensure => installed,
before => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf':
path => '/etc/httpd/conf/httpd.conf',
source => '/root/manifests/httpd.conf',
ensure => file,
}
service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}
selector语句:
CONTROL_VARIABLE ? {
case1 => value1,
case2 => value2,
...
default => valueN,
}
Selectors 做多条件赋值
selector只能用于期望出现纸介质的地方,这包括变量赋值、资源属性、函数参数、资源标题、其他selector的值以及表达式
selector不能用于一个已经嵌套于selector的case中,也不能用于一个已经嵌套于case的case语句中
CONTROL_VARIABLE的给定方法:
(1) 变量
(2) 有返回值的函数
各case的给定方式:
(1) 直接字串;
(2) 变量
(3) 有返回值的函数
(4) 正则表达式模式;
(5) default
注意:不能使用列表格式;但可以是其它的selecor;
示例1:
$pkgname = $operatingsystem ? { 如果$pkgname匹配到第一个则返回apache2,匹配到第二个则返回httpd
/(?i-mx:(ubuntu|debian))/ => 'apache2',
/(?i-mx:(redhat|fedora|centos))/ => 'httpd',
default => 'httpd',
}
package{"$pkgname":
ensure => installed,
}
示例2:
$webserver = $osfamily ? {
"Redhat" => 'httpd',
/(?i-mx:debian)/ => 'apache2',
default => 'httpd',
}
package{"$webserver":
ensure => installed,
before => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf':
path => '/etc/httpd/conf/httpd.conf',
source => '/root/manifests/httpd.conf',
ensure => file,
}
service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}
7、puppet的类:
类:puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;
类可以被继承,也可以包含子类;
类的名称只能以小写字母开头,可以包含小写字母、数字和下划线
每个类都会引入一个新的变量scpoe,这意味着在任何时候访问类中的变量时都得使得其完全限定名称
不过,在本地scope可以重新为top scope中的变量赋予一个新值
语法格式:
class NAME {
...puppet code...
}
class NAME(parameter1, parameter2) {
...puppet code...
}
调用类
类代码只有声明后才会执行,调用方式:
(1) include CLASS_NAME1, CLASS_NAME2, ...
(2) class{'CLASS_NAME':
attribute => value,
}
示例1:
class apache2 {
$webpkg = $operatingsystem ? {
/(?i-mx:(centos|redhat|fedora))/ => 'httpd',
/(?i-mx:(ubuntu|debian))/ => 'apache2',
default => 'httpd',
}
package{"$webpkg":
ensure => installed,
}
file{'/etc/httpd/conf/httpd.conf':
ensure => file,
owner => root,
group => root,
source => '/tmp/httpd.conf',
require => Package["$webpkg"],
notify => Service['httpd'],
}
service{'httpd':
ensure => running,
enable => true,
}
}
include apache2 调用class apache2
示例2:(形参)
class dbserver($pkg,$srv) {
package{"$pkg":
ensure => latest,
}
service{"$srv":
ensure => running,
}
}
if $operatingsystem == "CentOS" or $operatingsystem == "RedHat" {
case $operatingsystemmajrelease {
'7': { $pkgname = 'mariadb-server' $srvname='mariadb' }
default: { $pkgname = 'mysql-server' $srvname='mysqld' }
}
}
class{'dbserver':
pkg => "$pkgname", 形式参数调用,pkg不加$符号,调用的参数加上$符号
srv => "$srvname",
}
类的继承:
class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {
...puppet code...
}
示例:
class nginx {
package{'nginx':
ensure => installed,
}
service{'nginx':
ensure => running,
enable => true,
restart => '/usr/sbin/nginx -s reload',
}
}
class nginx::web inherits nginx { nginx是父类,web是子类 ,nginx::web完全限定格式的名称
Service['nginx'] { 引用父类的资源
subscribe => File['ngx-web.conf'], 子类的资源
}
file{'ngx-web.conf':
path => '/etc/nginx/conf.d/ngx-web.conf',
ensure => file,
source => '/root/manifests/ngx-web.conf',
}
}
class nginx::proxy inherits nginx {
Service['nginx'] {
subscribe => File['ngx-proxy.conf'],
}
file{'ngx-proxy.conf':
path => '/etc/nginx/conf.d/ngx-proxy.conf',
ensure => file,
source => '/root/manifests/ngx-proxy.conf',
}
}
示例2:
class redis {
package{'redis':
ensure => latest,
} ->
service{'redis':
ensure => running,
enable => true,
}
}
class redis::master inherits redis {
file{'/etc/redis.conf':
ensure => file,
source => '/root/manifests/redis-master.conf',
owner => redis,
group => root,
}
Service['redis'] {
subscribe => File['/etc/redis.conf'],
}
}
class redis::slave inherits redis {
file{'/etc/redis.conf':
ensure => file,
source => '/root/manifests/redis-slave.conf',
owner => redis,
group => root,
}
Service['redis'] {
subscribe => File['/etc/redis.conf'],
}
}
在子类中为父类的资源新增属性或覆盖指定的属性的值:
Type['title'] {
attribute1 => value,
...
}
在子类中为父类的资源的某属性增加新值:
Type['title'] {
attribute1 +> value,
...
}
8、puppet模板:
模块就是一个按约定的、预定义的层级结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范;
puppet会在配置的路径下查找所需要的模块;
模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main"和"settings“;
MODULES_NAME:
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/:当前模块的使用帮助或使用范例文件;
注意:
1、puppet 3.8及以后的版本中,资源清单文件的文件名要与文件子类名保持一致,例如某子类名
为“base_class::child_class”,其文件名应该为child_class.pp;子类名.pp
redis/
mainfests/
init.pp: class redis {}
master.pp:class redis::master inherits redis {}
slave.pp:class redis::slave inherits redis {}
2、无需在资源清单文件中使用import语句;
3、manifests目录下可存在多个清单文件,每个清单文件包含一个类,其文件名同类名;
erb:模板语言,embedded ruby;
puppet兼容的erb语法:
https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html
file{'title':
ensure => file,
path =>
content => template('/PATH/TO/ERB_FILE'), 模板文件的路径
}
文本文件中内嵌变量替换机制:
<%= @VARIABLE_NAME %>
示例:
#mv nginx.conf nginx.conf.erb
#vim nginx.conf.erb
在worker_processes后面改为<%= @processorcount %>;
class nginx {
package{'nginx':
ensure => installed,
}
service{'nginx':
ensure => running,
enable => true,
require => Package['nginx'],
}
}
class nginx::web inherits nginx {
file{'ngx-web.conf':
path => '/etc/nginx/conf.d/ngx-web.conf',
ensure => file,
require => Package['nginx'],
source => '/root/manifests/nginx/ngx-web.conf',
}
file{'nginx.conf':
path => '/etc/nginx/nginx.conf',
ensure => file,
content => template('/root/manifests/nginx.conf.erb'),
require => Package['nginx'],
}
Service['nginx'] {
subscribe => [ File['ngx-web.conf'], File['nginx.conf'] ],
}
}
include nginx::web
课外练习:
1、用standalone的模式,在多主机本地运行清单,实现对keepalived高可用的nginx服务;
9、puppet config命令:
# puppet help config
print 显示
set 设定
获取或设定puppet配置参数;
# puppet config print 显示所有配置参数
# puppet config print [argument] 显示配置参数
puppet查找模块文件的路径:modulepath
mariadb模块中的清单文件示例:
class mariadb($datadir='/var/lib/mysql') {
package{'mariadb-server':
ensure => installed,
}
file{"$datadir":
ensure => directory,
owner => mysql,
group => mysql,
require => [ Package['mariadb-server'], Exec['createdir'], ],
}
exec{'createdir':
command => "mkdir -pv $datadir",
require => Package['mariadb-server'],
path => '/bin:/sbin:/usr/bin:/usr/sbin',
creates => “$datadir",
}
file{'my.cnf':
path => '/etc/my.cnf',
content => template('mariadb/my.cnf.erb'),
require => Package['mariadb-server'],
notify => Service['mariadb'],
}
service{'mariadb':
ensure => running,
enable => true,
require => [ Exec['createdir'], File["$datadir"], ],
}
}
10、standalone:puppet apply
master/agent:agent每隔30分钟到master端请求与自己相关的catalog
master: site manifest
node 'node_name' {
...puppet code...
}
node_name
程序包下载路径:
https://yum.puppetlabs.com/
官方文档:
https://docs.puppet.com/puppet/3/reference/
内建函数:
https://docs.puppet.com/puppet/3/reference/function.html
配置参数列表:
https://docs.puppet.com/puppet/3/reference/configuration.html
部署master:
安装程序包:facter, puppet, puppet-server
初始化master:
puppet master --no-daemonize --verbose
生成一个完整的配置参数列表:
puppet master --genconfig
puppet agent --genconfig
...
打印基于默认配置生效的各配置参数列表:
puppet config <action> [--section SECTION_NAME]
puppet config print
基于命令行设定某参数的值:
puppet config set
master端管理证书签署:
puppet cert <action> [--all|-a] [<host>]
action:
list
sign
revoke
clean:吊销指定的客户端的证书,并删除与其相关的所有文件;
站点清单的定义:
主机名定义:
主机名(主机角色)#-机架-机房-运营商-区域.域名
www1-rack1-yz-unicom-bj.magedu.com
/etc/puppet/manifests/site.pp
node 'base' {
include ntp
}
node 'HOSTNAME' {
...puppet code...
}
node /PATTERN/ {
...puppet code...
}
node /node[0-9]+\.magedu\.com/
节点定义的继承:
node NODE inherits PAR_NODE_DEF {
...puppet code...
}
nodes/
清单配置信息可模块化组织:
databases.d/
tomcatservers.d/
nodes.d/:可通过多个pp文件分别定义各类站点的清单;而后统一导入site.pp,方法如下:
site.pp文件使用中如下配置:
import 'nodes/*.pp'
多环境配置:
默认环境是production;
environmentpath =
puppet 3.4 之前的版本配置多环境的方法:
各环境配置:
/etc/puppet/environments/{production,development,testing}
master支持多环境:puppet.conf
[master]
# modulepath=
# manifest=
environments = production, development, testing
[production]
modulepath=/etc/puppet/environments/production/modules/
manifest=/etc/puppet/environments/production/manifests/site.pp
[development]
modulepath=/etc/puppet/environments/development/modules/
manifest=/etc/puppet/environments/development/manifests/site.pp
[testing]
modulepath=/etc/puppet/environments/testing/modules/
manifest=/etc/puppet/environments/testing/manifests/site.pp
puppet 3.6之后的版本配置多环境的方法:
master支持多环境:
(1) 配置文件puppet.conf
[master]
environmentpath = $confdir/environments
(2) 在多环境配置目录下为每个环境准备一个子目录
ENVIRONMENT_NAME/
manifests/
site.pp
modules/
agent端:
[agent]
environment = { production|development | testing }
额外配置文件:
文件系统:fileserver.conf
认证(URL):auth.conf
puppet kick:
agent:
puppet.conf
[agent]
listen = true
auth.conf文件中添加如下内容:
path /run
method save
auth any
allow master.magedu.com
path /
auth any
master端:
puppet kick
puppet kick [--host <HOST>] [--all]
GUI:
dashboard
foreman
项目实践:
haproxy(keepalived)
cache --> varnish
imgs--> nginx server
app --> httpd+tomcat
--> mariadb-server
zabbix -->
zabbix-server
zabbix-agent
生产环境案例:haproxy.pp
class haproxy {
# init haproxy
class init {
file { '/etc/init.d/haproxy':
ensure => present,
source => "puppet:///modules/haproxy/haproxy/init.d/haproxy.init",
group => "root",
owner => "root",
mode => "0755",
}
exec { 'init_haproxy_service':
subscribe => File['/etc/init.d/haproxy'],
refreshonly => true,
command => "/sbin/chkconfig --add haproxy; /sbin/chkconfig --level 235 haproxy off;",
}
service { 'haproxy':
ensure => running,
enable => true,
hasrestart => true,
hasstatus => true,
# restart => true,
}
}
# init haproxy.cfg
class conf {
# file { '/usr/local/haproxy','/usr/local/haproxy/etc':
file { ['/usr/local/haproxy','/usr/local/haproxy/etc']:
ensure => directory,
before => File['/usr/local/haproxy/etc/haproxy.cfg'],
group => "root",
owner => "root",
mode => "0755",
}
class piccenter {
file { '/usr/local/haproxy/etc/haproxy.cfg':
ensure => present,
source => "puppet:///modules/haproxy/haproxy/conf/haproxy_piccenter.cfg",
group => "root",
owner => "root",
mode => "0644",
}
}
}
}
keepalived.pp
class keepalived {
# init haproxy
class init {
file { '/etc/init.d/keepalived':
ensure => present,
source => "puppet:///modules/haproxy/keepalived/init.d/keepalived.init",
group => "root",
owner => "root",
mode => "0755",
}
exec { 'init_keepalived_service':
subscribe => File['/etc/init.d/keepalived'],
refreshonly => true,
command => "/sbin/chkconfig --add keepalived; /sbin/chkconfig --level 235 keepalived off;",
}
service { 'keepalived':
ensure => running,
enable => true,
hasrestart => true,
hasstatus => true,
restart => true,
}
}
}
总结:
puppet核心资源类型:group, user, file, package, service, exec, cron, notify
puppet describe [-l] [type]
资源清单:manifests, *.pp
type{'title':
attribute => value,
...
}
引用:Type['title']
元参数:
依赖:before/require
依赖和通知:notify/subscribe
数据类型:字符串、数值、布尔型、数组、hash、undef
正则表达式:(?<enable_flag>-<disable_flag>:<PATTERN>)
flag: i, m, x
变量:$variable,
facter, 内建变量,自定义变量
FQN: $::scope1::scope2::variable
$variable
编程元素:
流程控制:
if, case, selector, unless
类:
class class_name[($parameter1[=value1], $parameter2)] {
...puppet code...
}
class sub_class_name inherits class_name {
... puppet code ...
}
sub_class_name:
base_class::sub_class_name
子类中引用父类的资源:
Type['title'] {
attribute => value,
atrribute +> value,
}
声明类:
include class_name
class{'class_name':
attribute => value,
...
}
模板:
erb:Embedded RuBy
<%= erb code %>
<% erb code %>
<%# erb code %>
file类型的资源
content => template('/PATH/TO/ERB_FILE')
path =>
模块:
modulepath配置参数指定的目录路径下(puppet config print modulepath);
manifests/
init.pp (至少得存在一个与模块名同名的类)
sub_class_name.pp
files/
puppet:///modules/MOD_NAME/FILE_NAME
templates/
template('MOD_NAME/ERB_FILE')
lib/
tests/
spec/
standalone:
puppet apply -e 'include CLASS_NAME'
... puppet code ...