自动化运维工具——puppet详解(一)

原文目录

一、puppet 介绍

1、puppet是什么

2、puppet的工作机制

1)工作模型

2)工作流程

3)使用模型

3、puppet 名词解释

二、puppet 资源详解

1、程序安装及环境

2、puppet 资源简介

1)资源抽象

2)资源定义

3)资源属性中的三个特殊属性:

3、常用资源总结

4、资源的特殊属性

tag 标签

5、puppet 变量

1)puppet的变量种类

2)变量的作用域

6、puppet 流程控制语句

1)if 语句

2)case 语句

3)selector 语句

写在后面


正文

一、puppet 介绍

1、puppet是什么

puppet是一个IT基础设施自动化管理工具,它能够帮助系统管理员管理基础设施的整个生命周期: 供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting)。

基于puppet ,可实现自动化重复任务、快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模等。

遵循GPL 协议(2.7.0-), 基于ruby语言开发。

2.7.0 以后使用(Apache 2.0 license)

对于系统管理员是抽象的,只依赖于ruby与facter。

能管理多达40 多种资源,例如:file、user、group、host、package、service、cron、exec、yum repo等。

2、puppet的工作机制

1)工作模型

puppet 通过声明性、基于模型的方法进行IT自动化管理。

定义:通过puppet 的声明性配置语言定义基础设置配置的目标状态;

模拟:强制应用改变的配置之前先进行模拟性应用;

强制:自动、强制部署达成目标状态,纠正任何偏离的配置;

报告:报告当下状态及目标状态的不同,以及达成目标状态所进行的任何强制性改变;

puppet三层模型

puppet三层模型如下:

puppet三层模型

2)工作流程

工作流程

3)使用模型

puppet的使用模型分为单机使用模型master/agent模型,下面我们来看看这两个模型的原理图。

单机使用模型

实现定义多个manifests --> complier --> catalog --> apply

单机使用模型工作原理

master/agent模型

master/agent模型实现的是集中式管理,即 agent 端周期性向 master 端发起请求,请求自己需要的数据。然后在自己的机器上运行,并将结果返回给 master 端。

架构和工作原理如下:

架构

master/agent模式架构

工作原理

master/agent模式工作原理

3、puppet 名词解释

资源:是puppet的核心,通过资源申报,定义在资源清单中。相当于ansible中的模块,只是抽象的更加彻底。

类:一组资源清单。

模块:包含多个类。相当于ansible中的角色

站点清单:以主机为核心,应用哪些模块。

回到顶部

二、puppet 资源详解

接下来,我们就以单机模式来具体介绍一下puppet的各个部分。

1、程序安装及环境

首先,我们还是来安装一下puppet,puppet的安装可以使用源码安装,也可以使用rpm(官方提供)、epel源、官方提供的yum仓库来安装(通过下载官方提供的rpm包可以指定官方的yum仓库)。

在这里,我们就是用 yum 安装的方式。

yum install -y puppet

安装完成过后,我们可以通过rpm -ql puppet | less来查看一下包中都有一些什么文件。

其中主配置文件为/etc/puppet/puppet.conf,使用的主程序为/usr/bin/puppet。

2、puppet 资源简介

1)资源抽象

   puppet 从以下三个维度来对资源完成抽象:

相似的资源被抽象成同一种资源**“类型”** ,如程序包资源、用户资源及服务资源等;

将资源属性或状态的描述与其实现方式剥离开来,如仅说明安装一个程序包而不用关心其具体是通过yum、pkgadd、ports或是其它方式实现;

仅描述资源的目标状态,也即期望其实现的结果,而不是其具体过程,如“确定nginx 运行起来” 而不是具体描述为“运行nginx命令将其启动起来”;

这三个也被称作puppet 的资源抽象层(RAL)

RAL 由type( 类型) 和provider( 提供者,即不同OS 上的特定实现)组成。

2)资源定义

资源定义通过向资源类型的属性赋值来实现,可称为资源类型实例化;

定义了资源实例的文件即清单,manifest;

定义资源的语法如下:

type {'title':

attribute1 => value1,

atrribute2 => value2,

……

}

注意:type必须使用小写字符;title是一个字符串,在同一类型中必须惟一;每一个属性之间需要用“,”隔开,最后一个“,”可省略。

例如,可以同时有名为nginx 的“service”资源和“package”资源,但在“package” 类型的资源中只能有一个名为“nginx”的资源。

3)资源属性中的三个特殊属性:

Namevar:可简称为name;

ensure:资源的目标状态;

Provider:指明资源的管理接口;

3、常用资源总结

1)查看资源

'我们可以使用puppet describe来打印有关Puppet资源类型,提供者和元参数的帮助。使用语法如下:

puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type]

-l:列出所有资源类型;

-s:显示指定类型的简要帮助信息;

-m:显示指定类型的元参数,一般与-s一同使用;'

2)group:管理系统上的用户组。

查看使用帮助信息:

group使用帮助

属性:

name:组名,可以省略,如果省略,将继承title的值;

gid:GID;

system:是否为系统组,true OR false;

ensure:目标状态,present/absent;

members:成员用户;

  简单举例如下:

vim group.pp

group{'mygrp':

        name => 'mygrp',

        ensure => present,

        gid => 2000,

}

  我们可以来运行一下:

运行写好的group资源

3)user:管理系统上的用户。

查看使用帮助信息:

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的管理软件包。

查看使用帮助信息:

package使用帮助

属性:

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

service使用帮助

属性:

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:管理文件、目录、软链接

查看使用帮助信息:

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

exec使用帮助

属性:

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:定义周期性任务

查看使用帮助信息:

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来列出,上文中也已经说过了~

4、资源的特殊属性

puppet中也提供了beforerequirenotifysubscribe四个参数来定义资源之间的依赖关系和通知关系。

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'] #定义依赖关系

tag 标签

如同 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.pp运行结果

  现在,我们就去登录一下redis看看是否生效:

redis-cli -a keerya

redis验证

  验证成功,实验完成。

5、puppet 变量

puppet 变量以“$”开头,赋值操作符为“=”,语法为$variable_name=value。

数据类型:

字符型:引号可有可无;但单引号为强引用双引号为弱引用;支持转义符;

数值型:默认均识别为字符串,仅在数值上下文才以数值对待;

数组:[]中以逗号分隔元素列表;

布尔型值:true, false;不能加引号;

hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };

undef:从未被声明的变量的值类型;

正则表达式:

(?:)

(?-:)

OPTIONS:

i:忽略字符大小写;

m:把.当换行符;

x:忽略中的空白字符;

(?i-mx:PATTERN)

注意:不能赋值给变量,仅能用在接受=~或!~操作符的位置;

1)puppet的变量种类

puppet 种类有三种,为facts,内建变量和用户自定义变量。

facts:

由facter提供;top scope;

内建变量:

master端变量

$servername, $serverip, $serverversion

agent端变量

$clientcert, $clientversion, $environment

parser变量

$module_name

用户自定义变量

2)变量的作用域

不同的变量也有其不同的作用域。我们称之为Scope。

作用域有三种,top scope,node scope,class scope。

其生效范围排序为:top scope > node scope > class scope

变量生效范围

  其优先级排序为:top scope < node scope < class scope

6、puppet 流程控制语句

puppet 支持if 语句case 语句selector 语句

1)if 语句

  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,

}

2)case 语句

类似 if 语句,case 语句会从多个代码块中选择一个分支执行,这跟其它编程语言中的 case 语句功能一致。

case 语句会接受一个控制表达式和一组 case 代码块,并执行第一个匹配到控制表达式的块。

使用语法如下:

case CONTROL_EXPRESSION {

case1: { ... }

case2: { ... }

case3: { ... }

……

default: { ... }

}

  其中,CONTROL_EXPRESSION的给定方式有如下三种:

变量

表达式

有返回值的函数

  各case的给定方式有如下五种:

直接字串;

变量

有返回值的函数

正则表达式模式;

default

举例

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'],

}

3)selector 语句

Selector 只能用于期望出现直接值(plain value) 的地方,这包括变量赋值、资源属性、函数参数、资源标题、其它 selector。

selector 不能用于一个已经嵌套于于selector 的case 中,也不能用于一个已经嵌套于case 的case 语句中。

具体语法如下:

CONTROL_VARIABLE ? {

case1 => value1,

case2 => value2,

...

default => valueN,

}

  其中,CONTROL_EXPRESSION的给定方式有如下三种:

变量

表达式

有返回值的函数

  各case的给定方式有如下五种:

直接子串;

变量;

有返回值的函数;

正则表达式模式;

default

selectors 使用要点:

整个selector 语句会被当作一个单独的值,puppet 会将控制变量按列出的次序与每个case 进行比较,并在遇到一个匹配的 case 后,将其值作为整个语句的值进行返回,并忽略后面的其它 case。

控制变量与各 case 比较的方式与 case 语句相同,但如果没有任何一个 case 与控制变量匹配时,puppet 在编译时将会返回一个错误,因此,实践中,其必须提供default case。

selector 的控制变量只能是变量或有返回值的函数,切记不能使用表达式。

其各 case 可以是直接值(需要加引号) 、变量、能调用返回值的函数、正则表达式模式或 default。

但与 case 语句所不同的是,selector 的各 case 不能使用列表。

selector 的各 case 的值可以是一个除了 hash 以外的直接值、变量、能调用返回值的函数或其它的 selector。

举例

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/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

大家写文都不容易,希望尊重劳动成果哟~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容