之前简单介绍了puppet的资源清单的编写方式,以及我们如何查看所支持的资源类型,也简单编写了一个资源group,ensure是一个非常重要的属性
在puppet当中定义资源的方式其实非常简单,只需要写一个普通的文本文件,一般以.pp结尾,而后定义资源的时候,语法格式、
定义资源的语法:
type {‘title’:同一种资源中,不同资源的区分的id(一般情况下是资源本身的同名属性值)
attribute1 => value1,
atrribute2 => value2,
……
}
name叫名称变了,可省略,省略的时候和title相同
定义资源的语法:
type(小写) {‘title’:同一种资源中,不同资源的区分的id(一般情况下是资源本身的同名属性值)
attribute1 => value1,
atrribute2 => value2,
……
}
注意:type必须使用小写字符;title是一个字符串,在同一类型中必须惟一;
资源有多种类型,其类型当中有一些是特殊属性,第一个特殊属性 ensure 用来定义资源的目标状态
第二个name/namevar 名称变量,省略时跟对应的资源title一致,很多时候简称为名称
namevar变量在同一种资源类型必须唯一
几乎所有的类型中,都有此两者特殊属性
**定义一个组常用属性有
name 组名
gid: gid
system 是否为系统组, true or false
ensure 目标状态 present/absent 存在或不存在
members 成员用户(组有多少成员)
**
第二个资源类型叫user,管理用户
user:
Manage users.
属性:
name:用户名;
uid: UID;
gid:基本组ID;
groups:附加组,不能包含基本组;
comment:用户注释;
expiry:账号过期时间 ;
home:家目录;
shell:默认shell类型;
system:是否为系统用户 ;
ensure:present/absent;
password:加密后的密码串;
要了解属性 ,用describ user
有很多属性
密码最小使用期限(密码最短多少时间才能改第二次)
密码最长使用时间(密码到达这个期限之前,要改密码)
指定密码加入的salt
每一个资源类型基本上都有providers
Provider:指明资源的管理接口;(用何种方式来完成这个资源的创建的)
一般而言在同一系统之上,同一种管理资源接口可能只有一种,但存在多种可以自定义使用哪一种
成功以后,你所指的基本组被不存在,需要被执行存在,所以被依赖的资源如果不存在,就会出现故障了,可以手动天加,也可以编辑配置文件
**现在应该就可以创建成功
**
再跑一遍不会有问题的,因为对于配置管理系统来讲,所有资源必须有一特点,幂等性,需要拥有幂等性,同一个定义配置,执行多少遍的结果是一样的,如果没有创建,就创建,创建了,就什么事情也不做
但是有些资源天生不具有幂等性
mkdir,执行完一次,再执行一次,不幂等,是报错的,所以有时候需要确保命令是幂等的,意味着要加一下判断,以确保命令执行完不出问题
所以叫幂等性,可以确保一个资源在执行N遍和执行一遍的结果一致,资源要具有幂等性,如果不具有,想办法让它拥有幂等性
刚才万一组不存在了,刚才就出现了资源创建不成功的问题,那么只能实现创建组,如果资源定义在前,组定义在后面,是否会出现故障
用户在前,组在后
自动创建redis组给用户
在同一个文件没有问题,但是换文件就有问题了,不能分析出依赖关系
所以在同一个文件没有问题,不能确保每一次配置文件都分析成功,它能知道彼此的依赖关系,这种只有组合用户之间本来就隐含依赖关系才能分析成功,假如定义的是程序包,先出创建文件,后去安装程序包就有可能出现问题,不一定能分析出这里因此的依赖关系,所以对于资源定义而言,还有另外一组特殊属性
资源间的次序(依赖关系)
这种依赖关系提供了四种特殊属性,来定义依赖关系,把四种属性叫原参数,要了解特殊属性之前,定义变量还要引用变量
资源可以被定义,也可以被引用,资源被引用时要使用一种特殊方式
使用大写类型名称Type []中括号,+资源名称=[‘title’] 来引用,如引用magedu用户,首字母大写其他小写
可以定义资源时来定义它的引用关系了
直接明确依赖于group
也可以定义group 必须先于redis用户创建也可以,定义依赖关系有两种,前资源,后资源,在后资源中定义require,前资源定义before
关系元参数:before/require
A before B: B依赖于A,定义在A资源中;
{
…
before => Type[‘B’],
…
}
B require A: B依赖于A,定义在B资源中;
{
…
require => Type[‘A’],
…
}
管理程序包的资源
安装的报名是什么
这里ensure的值比较独特
installed安装上
absent 不安装
latest 最新版本(yum仓库可能会有多个版本,默认安装最新版本,否则加版本号)
purge 不装了
held 装上去
安装多个包可以用数组格式的数据
安装选项,可以指明安装在哪个路径下
同一个程序包在不同的发行版上,名字可能不一样,尤其是httpd,在centos上就叫httpd,deepin叫apache2,因此要判断底层操作系统版本是什么,需要加判断
如果solaris就安装smcossl
linux就安装openssl
**不同操作系统的安装程序是不一样的
linux的程序包可以用pkg
windows msi
**
package:
Manage packages.
属性:
ensure:installed, present, latest, absent
name:包名;
source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg;
先删除,待会安装的时候会自动给生成用户名
s改成1
安装完成
也可以放在本地用rpm包安装
这是用rpm指明source文件直接安装
假如现在仓库中有redis-3.2版本,有3.0 现在想安装3.0 的,在写name的时候,写redis-3.0,ensure present
安装程序包之后就需要启动服务了
service:
Manage running services.
属性:
ensure:Whether a service should be running. Valid values are stopped
(also called false
),running
(also called true
).是否启动
enable:Whether a service should be enabled to start at boot. Valid values are true
, false
,manual
.是否开机启动启动
name:(跟你的unit名字或者脚本名保持一致)
path:The search path for finding init scripts.
Multiple values should be separated by colons or provided as an array. 脚本的搜索路径,默认为/etc/init.d/;(centos在usrl/lib/systemd/uni file)
hasrestart:(对于这个脚本有没有restart的方法。如果没有就只能先stop后start,有就直接restart)
hasstatus:(有没有status操作方法,有就是true 没有就是false)
start:手动定义启动命令;(不用脚本或unit自带的)
stop:
status:
restart:Specify a restart command manually.If left unspecified, the service will be stopped and then started. 通常用于定义reload操作;(有些命令不能重启,比如nginx调度器,reload下即可)
puppet describe service
path脚本搜索路径
指明自己应用程序路径的
不想用默认的脚本启动关闭,可以自己定义start stop
现在服务应该就能启动起来
6379端口启动,如果期望监听0.0.0.0,那就需要改配置文件,redis要能启动最起码程序包先要装上去,有依赖关系
require表示依赖关系
想要让redis验证和改端口监听,需要推一个配置文件过去,再启动服务,就是file
file:
Manages files, including their content, ownership, and permissions.管理文件类型资源,确保生成一个文件时,能够直接生产文件内容,定义所属主属组
所以我们可以自己来定义这些属性
ensure:Whether the file should exist, and if so what kind of file it should be. Possible values are present
,absent
, file
, directory
, and link
.(文件类型很多,普通文件,链接文件,目录,所以ensure类型就有很多了)
file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;
path:文件路径;
source:源文件;(直接从源文件复制过去)(directory 就可以指定源目录,把源目录内容复制过去,recurse属性指明是否递归复制)
content:直接指定文件内容;(不适合大量的文件内容)
target:符号链接的目标文件; (link要指明文件,指向的文件是谁)
owner:属主
group:属组
mode:权限;
atime/ctime/mtime:时间戳;
复制目录的时候要确保递归复制,需要使用recurse,true,false, remote
权限使用八进制和rwx都可以
把redis配置复制过来,改成需要的样子
把这个配置文件当作模板推送过去使用
不管不给全路径,只给名字,后面必须要指定path,source 源文件
查看之前的文件默认属组是什么
mode 权限模型 0644
这个文件是有的只不过md5值跟我们改的目标的值并不一样,需要复制过去
一个文件夹内容发生改变会触发一个刷新的事件
一般而言服务配置文件发生改变,服务必须要重启生效
查看文件是否发生改变
但是服务可能并没有重启,要想重启,需要使用另外一组元参数
元参数: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’],后资源引用A资源
…
}
链式依赖,链式通知,A依赖B,B依赖C,这时候可以把依赖关系拿出来单独定义
配置修改后要重启服务,现在定义一个完整的清单
**有安装程序,还有配置文件,一般在包安装后,才发生配置文件
如果这个资源发生改变就通知notify,通知给service 重启
**
也可以用subscribe
修改/etc/redis配置文件
告诉我们配置文件发生改变,会触发一个事件,refresh of service redis刷新对多出服务而言就是重启
依赖关系一个一个写还是比较麻烦的,一般都是先安装程序包,修改配置文件,启动服务
可以这么写
表示前面通知后面这个
也可以拿出来单独定义,在后面加一段
改一下文件使得能触发
content发生改变,triggered 触发事件,redis服务就重启过了,d但是有些服务器重启是可怕的,比如nginx做调度器不能重启,修改restart命令为reload
文件内容还可以基于content生成
content可以基于模板,调用其他文件的函数生成
这就是第二种方式指定给定内容,第三种
确保是link类型文件,target指向目标文件
也可以创建一个目录
recurse 递归复制整个目录
这就是递归复制目录创建文件的方法
file:
Manages files, including their content, ownership, and permissions.
ensure:Whether the file should exist, and if so what kind of file it should be. Possible values are `present`,
`absent`, `file`, `directory`, and `link`.
file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;
path:文件路径;
source:源文件;
content:文件内容;
target:符号链接的目标文件;
owner:属主
group:属组
mode:权限;
atime/ctime/mtime:时间戳;
通知元参数:
A notify B:B依赖于A,接受由A触发refresh;
B subscribe A:B依赖于A,接受由A触发refresh;
示例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']
核心的package service file,
user
基本类型资源有8个
后面可以使用条件判断语句,甚至可以使用变量