接下来,我们就以单机模式来具体介绍一下
的各个部分。
- puppet
首先,我们还是来安装一下
,
- puppet
的安装可以使用源码安装,也可以使用 rpm(官方提供)、epel 源、官方提供的 yum 仓库来安装(通过下载官方提供的 rpm 包可以指定官方的 yum 仓库)。 在这里,我们就是用 yum 安装的方式。
- puppet
- yum install - y puppet
安装完成过后,我们可以通过
来查看一下包中都有一些什么文件。 其中主配置文件为
- rpm -ql puppet | less
,使用的主程序为
- /etc/puppet/puppet.conf
。
- /usr/bin/puppet
puppet 从以下三个维度来对资源完成抽象:
- 相似的资源被抽象成同一种资源 **"类型"** ,如程序包资源、用户资源及服务资源等;
- 将资源属性或状态的描述与其实现方式剥离开来,如仅说明安装一个程序包而不用关心其具体是通过 yum、pkgadd、ports 或是其它方式实现;
- 仅描述资源的目标状态,也即期望其实现的结果,而不是其具体过程,如 "确定 nginx 运行起来" 而不是具体描述为 "运行 nginx 命令将其启动起来";
这三个也被称作 puppet 的资源抽象层 (RAL)
RAL 由 type(类型) 和 provider(提供者,即不同 OS 上的特定实现) 组成。
资源定义通过向资源类型的属性赋值来实现,可称为资源类型实例化;
定义了资源实例的文件即清单,manifest;
定义资源的语法如下:
- type {
- 'title': attribute1 = >value1,
- atrribute2 = >value2,
- ……
- }
注意:type 必须使用小写字符;title 是一个字符串,在同一类型中必须惟一;每一个属性之间需要用 "," 隔开,最后一个 "," 可省略。
例如,可以同时有名为 nginx 的 "service" 资源和 "package" 资源,但在 "package" 类型的资源中只能有一个名为 "nginx" 的资源。
:可简称为 name;
- Namevar
:资源的目标状态;
- ensure
:指明资源的管理接口;
- Provider
1)查看资源
我们可以使用
来打印有关 Puppet 资源类型,提供者和元参数的帮助。使用语法如下:
- puppet describe
- puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type]
- -l:列出所有资源类型;
- -s:显示指定类型的简要帮助信息;
- -m:显示指定类型的元参数,一般与-s一同使用;
2)group:管理系统上的用户组。
查看使用帮助信息:
- 属性:
- name:组名,可以省略,如果省略,将继承title的值;
- gid:GID;
- system:是否为系统组,true OR false;
- ensure:目标状态,present/absent;
- members:成员用户;
简单举例如下:
- vim group.pp
- group{'mygrp':
- name => 'mygrp',
- ensure => present,
- gid => 2000,
- }
我们可以来运行一下:
3)user:管理系统上的用户。
查看使用帮助信息:
- 属性:
- name:用户名,可以省略,如果省略,将继承title的值;
- uid: UID;
- gid:基本组ID;
- groups:附加组,不能包含基本组;
- comment:注释;
- expiry:过期时间 ;
- home:用户的家目录;
- shell:默认shell类型;
- system:是否为系统用户 ;
- ensure:present/absent;
- password:加密后的密码串;
简单举例如下:
- vim user1.pp
- user{'keerr':
- ensure => present,
- system => false,
- comment => 'Test User',
- shell => '/bin/tcsh',
- home => '/data/keerr',
- managehome => true,
- groups => 'mygrp',
- uid => 3000,
- }
4)package:puppet 的管理软件包。
查看使用帮助信息:
- 属性:ensure:installed,
- present,
- latest,
- absent,
- any version string(implies present) name:包名,可以省略,如果省略,将继承title的值;source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg;provider: 指明安装方式;
简单举例如下:
- vim package1.pp
- package{'nginx':
- ensure => installed,
- procider => yum
- }
5)service:定义服务的状态
查看使用帮助信息:
- puppet describe service - s - m
- 属性:
- ensure:服务的目标状态,值有true(running)和false(stopped)
- enable:是否开机自动启动,值有true和false
- name:服务名称,可以省略,如果省略,将继承title的值
- path:服务脚本路径,默认为/etc/init.d/下
- start:定制启动命令
- stop:定制关闭命令
- restart:定制重启命令
- status:定制状态
简单举例如下:
- vim service1.pp
- service{'nginx':
- ensure => true,
- enable => false
- }
6)file:管理文件、目录、软链接
查看使用帮助信息:
- 属性:
- ensure:目标状态,值有absent,present,file,directory和link
- file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
- link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
- directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;
- path:文件路径;
- source:源文件;
- content:文件内容;
- target:符号链接的目标文件;
- owner:定义文件的属主;
- group:定义文件的属组;
- mode:定义文件的权限;
- atime/ctime/mtime:时间戳;
简单举例如下:
- vim file1.pp
- file{'aaa':
- path => '/data/aaa',
- source => '/etc/aaa',
- owner => 'keerr',
- mode => '611',
- }
7)exec:执行命令,慎用。通常用来执行外部命令
查看使用帮助信息:
- puppet describe exec - s - m
- 属性:
- command(namevar):要运行的命令;
- cwd:指定运行该命令的目录;
- creates:文件路径,仅此路径表示的文件不存在时,command方才执行;
- user/group:运行命令的用户身份;
- path:指定命令执行的搜索路径;
- onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
- unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;
- refresh:重新执行当前command的替代命令;
- refreshonly:仅接收到订阅的资源的通知时方才运行;
简单举例如下:
- vim exec1.pp
- exec{'cmd':
- command => 'mkdir /data/testdir',
- path => ['/bin','/sbin','/usr/bin','/usr/sbin'],
- # path => '/bin:/sbin:/usr/bin:/usr/sbin',
- }
8)cron:定义周期性任务
查看使用帮助信息:
- 属性:
- command:要执行的任务(命令或脚本);
- ensure:目标状态,present/absent;
- hour:时;
- minute:分;
- monthday:日;
- month:月;
- weekday:周;
- user:以哪个用户的身份运行命令(默认为root);
- target:添加为哪个用户的任务;
- name:cron job的名称;
简单举例如下:
- vim cron1.pp
- cron{'timesync':
- command => '/usr/sbin/ntpdata 172.16.0.1',
- ensure => present,
- minute => '*/3',
- user => 'root',
- }
我们可以运行一下,查看我们的 crontab,来看看该任务是否已经被添加:
- [root@master manifests]# puppet apply -v --noop cron1.pp #试运行
- [root@master manifests]# puppet apply -v cron1.pp #运行
- [root@master manifests]# crontab -l #查看计划任务
- # HEADER: This file was autogenerated at 2017-12-14 15:05:05 +0800 by puppet.
- # HEADER: While it can still be managed manually, it is definitely not recommended.
- # HEADER: Note particularly that the comments starting with 'Puppet Name' should
- # HEADER: not be deleted, as doing so could cause duplicate cron jobs.
- # Puppet Name: timesync
- */3 * * * * /usr/sbin/ntpdata 172.16.0.1
9)notify:调试输出
查看使用帮助信息:
- 属性:
- message:记录的信息
- name:信息名称
该选项一般用于
中,来记录一些操作的时间,比如重新安装了一个程序呀,或者重启了应用等等。会直接输出到代理机的运行日志中。
- master/agent模式
以上,就是我们常见的 8 个资源。其余的资源我们可以使用
来列出,上文中也已经说过了~
- puppet describe -l
中也提供了 before、require、notify 和 subscribe 四个参数来定义资源之间的依赖关系和通知关系。
- puppet
before:表示需要依赖于某个资源
require:表示应该先执行本资源,在执行别的资源
notify:A notify B:B 依赖于 A,且 A 发生改变后会通知 B;
subscribe:B subscribe A:B 依赖于 A,且 B 监控 A 资源的变化产生的事件;
同时,依赖关系还可以使用
和
- ->
来表示:
- ~>
-> 表示后资源需要依赖前资源
~> 表示前资源变动通知后资源调用
举例如下:
- vim file.pp file {
- 'test.txt': #定义一个文件path = >'/data/test.txt',
- ensure = >file,
- source = >'/etc/fstab',
- }
- file {
- 'test.symlink': #依赖文件建立超链接path = >'/data/test.symlink',
- ensure = >link,
- target = >'/data/test.txt',
- require = >File['test.txt'],
- }
- file {
- 'test.dir': #定义一个目录path = >'/data/test.dir',
- ensure = >directory,
- source = >'/etc/yum.repo.d/',
- recurse = >true,
- }
我们还可以使用在最下面统一写依赖关系的方式来定义:
- vim redis.pp package {
- 'reids': ensure = >installed,
- }
- file {
- '/etc/redis.conf': source = >'/root/manifets/files/redis.conf',
- ensure = >file,
- owner = >redis,
- group = >root,
- mode = >'0640',
- }
- service {
- 'redis': ensure = >running,
- enable = >true,
- hasrestart = >true,
- }
- Package['redis'] - >File['/etc/redis.conf'] - >Service['redis']#定义依赖关系
如同 anssible 一样,puppet 也可以定义 "标签"——tag,打了标签以后,我们在运行资源的时候就可以只运行某个打过标签的部分,而非全部。这样就更方便于我们的操作。
一个资源中,可以有一个
也可以有多个。具体使用语法如下:
- tag
- type{'title':
- ...
- tag => 'TAG1',
- }
- type{'title':
- ...
- tag => ['TAG1','TAG2',...],
- }
调用时的语法如下:
- puppet apply --tags TAG1,TAG2,... FILE.PP
实例
首先,我们去修改一下
文件,添加一个标签进去
- redis.pp
- vim redis.pp package {
- 'redis': ensure = >installed,
- }
- file {
- '/etc/redis.conf': source = >'/root/manifets/file/redis.conf',
- ensure = >file,
- owner = >redis,
- group = >root,
- mode = >'0640',
- tag = >'instconf'#定义标签
- }
- service {
- 'redis': ensure = >running,
- enable = >true,
- hasrestart = >true,
- }
- Package['redis'] - >File['/etc/redis.conf'] - >Service['redis']
然后,我们手动先开启
服务:
- redis
- systemctl start redis
现在,我们去修改一下
目录下的配置文件:
- file
- vim file/redis.conf
- requirepass keerya
接着,我们就去运行
,我们的配置文件已经修改过了,现在想要实现的就是重启该服务,实现,需要使用密码
- redis.pp
登录:
- keer
- puppet apply - v--tags instconf redis.pp
现在,我们就去登录一下 redis 看看是否生效:
- redis - cli - a keerya
验证成功,实验完成。
puppet 变量以 "$" 开头,赋值操作符为 "=",语法为
。 数据类型:
- $variable_name=value
字符型:引号可有可无;但单引号为强引用,双引号为弱引用;支持转义符;
数值型:默认均识别为字符串,仅在数值上下文才以数值对待;
数组:[] 中以逗号分隔元素列表;
布尔型值:true, false;不能加引号;
hash:{} 中以逗号分隔 k/v 数据列表; 键为字符型,值为任意 puppet 支持的类型;{'mon'=> 'Monday', 'tue' => 'Tuesday', };
undef:从未被声明的变量的值类型;
正则表达式:
(?
: )
(?-: )
OPTIONS:
i:忽略字符大小写;
m:把. 当换行符;
x:忽略中的空白字符;
(?i-mx:PATTERN)
注意:不能赋值给变量,仅能用在接受或
- =~
操作符的位置;
- !~
puppet 种类有三种,为
,
- facts
和
- 内建变量
。 facts: 由 facter 提供;top scope; 内建变量: master 端变量 $servername, $serverip, $serverversion agent 端变量 $clientcert, $clientversion, $environment parser 变量 $module_name 用户自定义变量
- 用户自定义变量
不同的变量也有其不同的作用域。我们称之为
。 作用域有三种,top scope,node scope,class scope。
- Scope
其优先级排序为:top scope < node scope < class scope
puppet 支持 if 语句,case 语句和 selector 语句。
if 语句支持单分支,双分支和多分支。具体语法如下:
- 单分支:
- if CONDITION {
- statement
- ……
- }
- 双分支:
- if CONDITION {
- statement
- ……
- }
- else{
- statement
- ……
- }
- 多分支:
- if CONDITION {
- statement
- ……
- }
- elsif CONDITION{
- statement
- ……
- }
- else{
- statement
- ……
- }
其中,CONDITION 的给定方式有如下三种:
举例
- vim
- if.pp
- if $operatingsystemmajrelease == '7' {
- $db_pkg = 'mariadb-server'
- } else {
- $db_pkg = 'mysql-server'
- }
- package {
- "$db_pkg": ensure = >installed,
- }
类似 if 语句,case 语句会从多个代码块中选择一个分支执行,这跟其它编程语言中的 case 语句功能一致。
case 语句会接受一个控制表达式和一组 case 代码块,并执行第一个匹配到控制表达式的块。
使用语法如下:
- case CONTROL_EXPRESSION {
- case1: { ... }
- case2: { ... }
- case3: { ... }
- ……
- default: { ... }
- }
其中,CONTROL_EXPRESSION 的给定方式有如下三种:
各 case 的给定方式有如下五种:
举例
- vim case.pp
- case $osfamily {
- "RedHat": { $webserver='httpd' }
- /(?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 只能用于期望出现直接值 (plain value) 的地方,这包括变量赋值、资源属性、函数参数、资源标题、其它 selector。
selector 不能用于一个已经嵌套于于 selector 的 case 中,也不能用于一个已经嵌套于 case 的 case 语句中。
具体语法如下:
- CONTROL_VARIABLE ? {
- case1 = >value1,
- case2 = >value2,
- ...
- default = >valueN,
- }
其中,CONTROL_EXPRESSION 的给定方式有如下三种:
各 case 的给定方式有如下五种:
selectors 使用要点:
举例
- vim selector.pp
- $pkgname = $operatingsystem ? {
- /(?i-mx:(ubuntu|debian))/ => 'apache2',
- /(?i-mx:(redhat|fedora|centos))/ => 'httpd',
- default => 'httpd',
- }
- package{"$pkgname":
- ensure => installed,
- }
以上,我们本次的介绍就告一段落,剩余的部分,请看下回分解。
来源: http://www.cnblogs.com/keerya/p/8040071.html