Linux基础教程之Puppet 的使用与进阶

Puppet

基于puppet 可实现自动化重复任务, 快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模.
基于master/agent 模型. 基于RPC 的通信, 基于xml 进行数据交换

define : 使用puppet 语言来定义资源的状态
模拟 : 根据资源关系图, puppet 可以模拟部署无损运行测试代码
强制 : 对比客户端主机状态和定义的资源状态是否一致, 自动强制执行
report : 通过puppt API 可以将日志发送到第三方监控工具

puppet 工作模型 :

  • 单机模型 : 手动应用清单
  • master / agent : 基于RPC 的通信, 基于xml 进行数据交换

puppet 常用资源类型

资源抽象的维度, RAL 如何抽象资源的

三个层次  : 资源抽象层, 事物层, 配置语言层

类型 : 具有类似属性的组件, 例如 package, service, file
将资源的属性或状态与其实现方式分离
仅描述资源的目标状态, 也即实现的结果状态, 而不是具体过程

RAL 由 “类型” 和”提供者” (“provider”) 共同实现

puppet 子命令 :

help :

显示帮助

1 puppet help <command>
1 puppet help <command> <action>
apply :

手动控制如何应用清单
`puppet apply [-d | —debug] [-v | —verbose] [-e | —execute] [ —noop ]

describe :

显示资源类型的帮助信息

1
2
3
4
-l : 列出所有的资源类型
-s : 显示指定类型的简要帮助信息
puppet describe -s Command
-m : 显示指定类型的元参数, 一般与-s 一同使用

资源定义  : 向资源类型的属性赋值来实现, 可称为资源类型的实例化
资源定义所在的文件即为资源清单 manifest

定义资源的语法 :

1
2
3
4
type {“title”:
attribute => value1,
attribute2 => value2,
}

注意 ; type 必须使用小写字母, title 是一个字符串, 在同一类型中必须唯一

status :

显示server 的状态

agent :

运行客户端程序

master :

作为服务器主机, 用于控制其他的客户端和本机

module :

官方支持的模块

资源类型

  • group :
    创建和管理组
    name : 组名
    gid : 组ID
    ensure : 状态[present  | absent]
    system : 是否为用户组 [true | false]
    members : 成员用户
  • user :
    管理用户
    name : 用户名
    uid : UID
    gid : 基于组ID
    groups : 附加组
    comment : 注释
    expiry : 过期时间
    home : 家目录
    shell : 默认shell 类型
    system : 是否为系统用户
    ensure : present | absent
    password : 加密后的密码串
  • package :
    管理软件包
    name : 软件包名
    ensure : [ installed | present | absent]
    source : 程序包来源 [rpm | yum]
  • service
    服务管理
    ensure : [ installed | present | latest | ]
    path : 启动服务的脚本
    name : 服务名称
    enable : 是否开机启动
    restart : 通常用于重定义为 reload
    hasrestart : 有重启命令 [true | false]
    hasstatus : 有状态查询命令
  • file :
    管理文件
    ensure : 文件类型的确认 [file | directory | link | present | absent ]
    path : 文件路径
    source : 源文件
    content : 文件内容
    target : 符号连接的目标文件
    owner : 属主
    group : 属组
    mode : 权限
    atime/ctime/mtime : 时间戳
  • exec :
    执行命令
    cwd :  命令执行的目录
    command : 要运行的程序
    creates : 文件路径不存在即创建
    user/group : 运行命令的用户身份
    onlyif : 此属性指定一个命令, 此命令正常(退出码为0)运行时, 当前command 才会运行
    unless : 此属性指定一个命令, 此命令非正常(退出码为0)运行时, 当前command 才会运行
    refresh : 重新执行当前command 的替代命令
    refreshonly : 仅接收到订阅资源的通知时方才运行
  • cron :
    设置定时任务
    command:要执行的任务;
    ensure:present/absent;
    hour:
    minute:
    monthday:
    month:
    weekday:
    user:添加在哪个用户之上;
    name:cron job的名称;
    1
    2
    3
    4
    5
    6
    cron{“timesync”:
    command => “/usr/sbin/ntpdate 10.1.0.1 &> /dev/null”,
    ensure  => present,
    minute  => “*/3”,
    user    => “root”,
    }
  • notify :
    在日志中追加记录信息
    message : 信息内容
    name : 信息名称
    1
    2
    3
    4
    notify {“hello”
    message  => ‘hello guys’
    name => ‘hello message’
    }

资源引用 :

Type[‘title’]

类型的首字母必须大写

资源有特殊属性 :
  • 名称变量 : (namevar) : name 可省略, 此时将由title表示
  • ensure : 定义资源的目标状态
  • 元参数 : metaparameter :
    • 依赖关系 : before | require
    • 通知关系 : 通知相关其他资源进行刷新操作 notify | subscribe

补充 : before 是表明必须在某个操作之前进行, require 是要求在某个操作执行完后进行

定义的时候, 只需要在意的是目标的状态, 不需要在乎目标的过程

变量

数据类型 :

字符型:引号可有可无;但单引号为强引用,双引号为弱引用;
数值型:默认均识别为字符串,仅在数值上下文才以数值对待;
数组:[]中以逗号分隔元素列表;
布尔型值:true, false;
hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };
undef:未赋值型 ;
正则表达式:
(?[ENABLED OPTION]:[PATTERN])
(?-[DISABLED OPTION]:[PATTERN])

OPTIONS:
i:忽略字符大小写;
m:把 ‘.’ 当换行符;
x:忽略[PATTERN]中的空白字符

变量类型:
  • facts:agent向master 传递信息之前收集的信息
    由facter提供;top scope;将主机信息收集并规范化
  • 内建变量:
    master端变量 $servername, $serverip, $serverversion
    agent端变量 $environment, $clientcert(客户端证书), $clientversion
    parser变量 $module_name(当前应用的模块名称)
  • 用户自定义变量:
    $parameter_value
变量的作用范围

作用域 : top scope | node scope | class scope

任何给定的scope 都可以访问它自己的内容, 以及接收来自于其父scope, 节点scope 以及top scope 的内容

如果要访问非当前scope中的变量, 则需要通过完全限制名称进行, 如 $vhostdir = $apache::params::vhostdir
需要注意的是, top scope 的名称为空, 因此, 如若引用其变量, 则需要使用类似$::osfamily 进行
自己作用域的变量是不需要使用完全限制名称解析进行访问

操作符

=~ : 左侧的字符串能够被右侧的字符所匹配
!~ : 左侧的字符串不能被右侧的字符所匹配
in : 左侧的字符串在右侧的列表中能被匹配到

Puppet 中的if 语句

条件判断, 其中CONDITION 可以有各宗

1
2
3
4
5
6
7
8
9
if CONDITIONS {

}
elsif CONDITIONS{

}
else {

}

示例 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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,
}

Puppet 中的case 语句

使用方法:

1
2
3
4
5
6
7
case CONTROL_EXPRESSION {
case1: { … }
case2: { … }
case3: { … }

default: { … }
}

CONTROL_EXPRESSION:

  1. 变量
  2. 表达式
  3. 有返回值的函数

各case的给定方式:

  1. 直接字串;
  2. 变量
  3. 有返回值的函数
  4. 正则表达式模式;
  5. default

注意:不能使用列表格式;但可以是其它的selecor;
示例 :

1
2
3
4
5
$webserver = $osfamily ? {
‘Redhat’ => “httpd”,
/(?i-mx:debian)/ => “apache2”,
default => “httpd”,
}

Puppet 的类

类 : puppet 中命名的代码模块, 常用于定义一组通用目标的资源, 可在puppet 全局调用, 类可以被继承, 也可以包含子类

1
2
3
4
5
6
class NAME {
…puppet code…
}
class NAME(parameter1, parameter2) {
…puppet code…
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

Puppet 的模块

模块就是一个按约定的, 预定义的结构存放了多个文件或子目录的目录, 目录里的这些文件遵循一定格式的命名规范
puppet 会在配置的路径下查找所需要的模块

1
2
3
4
5
6
7
8
MODULES_NAME:
|-manifests/
|   |_init.pp
|-files/
|-lib/
|-templates/
|-spec/
|_tests/

模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main”和”settings“;

1
2
3
4
5
6
7
8
9
10
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/:当前模块的使用帮助或使用范例文件;

mariadb模块中的清单文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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”,
}

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’], ],
}
}

相关新闻

历经多年发展,已成为国内好评如潮的Linux云计算运维、SRE、Devops、网络安全、云原生、Go、Python开发专业人才培训机构!