Puppet
IT 基础设施的自动管理工具, 重量级, 需要自己编写许多模块
运维框架 :
基础 : 运维标准, 有了标准才能最大程度减小由于差异带来的麻烦, 统一硬件, 统一操作系统, 统一同应用的配置
监控 : 对于出现的应急情况进行预警和业务切换
部署 : 对于新上线的主机的快速配置
provsioning(供应) : 通过puppet 安装软件
configuration(配置) : 通过puppet 推送配置文件
orchestration(联动) : 编排, 把一组应用联动生效
reporting(报告) : 对系统变动通知管理员
资源清单 (manifest) : 资源所在文件, 运行特定的程序对系统进行管理
站点清单 : 为了能够使得每个被管控的主机明确自己的角色, 定义站点清单来确定每个主机在puppt 中的角色
对于不同主机, 我们通过资源清单和站点清单中的定义, 来使用定义好的模块和配置, 把变动结果放置在数据库中, 方便管理员进行查看和审计
定义模块 : 定义好给特定主机的规则, 实现脱离人工重复操作的自动化部署和配置
Puppet 的角色 :
Master/Agent
使用基于SSL 的HTTP 协议来完成数据传输, 借助HTTP 协议传输RPC(远程过程调用) 调用, 传输的xml格式的文件(描述了如何去部署和应用)用于RPC
Master 直接查询相应的, 模块Master 端发送的经由编译的字节码文件然后发送给客户端, 客户端直接运行
catalog : 编译后的相关配置
Agent 在请求之前要发送自己的facter 给 Master 端. 收到catalog 后, 将执行结果发送给Master 端, Master 将收到的结果保存到数据库中, 客户端每隔30 分钟进行一次拉取
总结 ; 可实现自动化重复任务, 快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模
基于puppet 可实现自动化重复任务, 快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模.
基于master/agent 模型. 基于RPC 的通信, 基于xml 进行数据交换
define : 使用puppet 语言来定义资源的状态
模拟 : 根据资源关系图, puppet 可以模拟部署无损运行测试代码
强制 : 对比客户端主机状态和定义的资源状态是否一致, 自动强制执行
report : 通过puppt API 可以将日志发送到第三方监控工具
puppet 工作模型 :
- 单机模型 : 手动应用清单, 在本地编译, 本地应用
- master / agent : 基于RPC 的通信, 基于xml 进行数据交换
类型 : 具有类似属性的组件, 例如 package, service, file
将资源的属性或状态与其实现方式分离
仅描述资源的目标状态, 也即实现的结果状态, 而不是具体过程
RAL 由 “类型” 和”提供者” (“provider”) 共同实现
Puppet 使用方式 : (单机模型)
Usage : puppet <subcommand> [options] <action> [options]
puppet 子命令 :
help :
显示帮助
puppet help <command>
puppet help <command> <action>
apply :
手动控制如何应用清单
`puppet apply [-d | –debug] [-v | –verbose] [-e | –execute] [ –noop ]
Puppet 资源 :
资源抽象的维度 :
- 类型 : 具有类似属性的组件,
- 将资源的属性或状态描述机制与其实现方式分离
- 仅描述资源的目标状态, 期望其实现的结果, 而不是具体过程
RAL 由”类型”和提供者(Provider)组成
puppet 常用资源类型
资源抽象的维度, RAL 如何抽象资源的
三个层次 : 资源抽象层, 事物层, 配置语言层 — 从低到高
由Puppet 对系统支持的方式进行判断, 并抽象出来作为一个通用的接口, 方便用户进行调用
在配置语言层提供相应的编程语言编译接口, 让管理员能通过编写自定义的配置清单文件来对主机集群进行管理, 管理过程与之前的资源清单和主机清单的应用相同
describe :
显示资源类型的详细帮助信息
-l : 列出所有的资源类型
-s : 显示指定类型的简要帮助信息
puppet describe -s Command
-m : 显示指定类型的元参数, 一般与-s 一同使用
资源定义 : 向资源类型的属性赋值来实现, 可称为资源类型的实例化
资源定义所在的文件即为资源清单 manifest
定义资源的语法 :
名称/名称变量 : name( 可由title 表示)
ensure ( 定义资源的目标状态)
require (定义依赖关系)
before (定义依赖关系)
notify (定义通知关系) : 发送直接字符串到运行时日志, 单机模式下发送到终端上
notify {'hi'
message => 'hello world',
}
subscribe (定义订阅关系)
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 : 用户手动指定的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的名称;
cron{'timesync':
command => '/usr/sbin/ntpdate 10.1.0.1 &> /dev/null',
ensure => present,
minute => '*/3',
user => 'root',
}
- notify :
在日志中追加记录信息
message : 信息内容
name : 信息名称
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, serverversionagent端变量 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 可以有各宗
if CONDITIONS {
...
}
elsif CONDITIONS{
...
}
else {
...
}
示例 :
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 语句
使用方法:
case CONTROL_EXPRESSION {
case1: { ... }
case2: { ... }
case3: { ... }
...
default: { ... }
}
CONTROL_EXPRESSION:
1. 变量
2. 表达式
3. 有返回值的函数
各case的给定方式:
1. 直接字串;
2. 变量
3. 有返回值的函数
4. 正则表达式模式;
5. default
注意:不能使用列表格式;但可以是其它的selecor;
示例 :
$webserver = $osfamily ? {
"Redhat" => 'httpd',
/(?i-mx:debian)/ => 'apache2',
default => 'httpd',
}
Puppet 的类
类 : puppet 中命名的代码模块, 常用于定义一组通用目标的资源, 可在puppet 全局调用, 类可以被继承, 也可以包含子类
class NAME {
...puppet code...
}
class NAME(parameter1, parameter2) {
...puppet code...
}
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 会在配置的路径下查找所需要的模块
MODULES_NAME:
|-manifests/
| |_init.pp
|-files/
|-lib/
|-templates/
|-spec/
|_tests/
模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main”和”settings“;
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/:当前模块的使用帮助或使用范例文件;
注意 : 在指明puppet URL 时, 根据如上示例进行定义, 不需要加该文件在模块目录下的具体目录名.
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',
}
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"], ],
}
}
Puppet Agent/Master
每一个 Agent 访问 Master 的时候,会发起证书签署请求, Master 的CA 会给信任的主机签署请求. Master端游内建的CA 用于证书的签署
客户端的必须要能将名称解析成IP地址, 所有要求有DNS 服务器