前言:
对于运维人员而言,自动化运维工具是工作必备,不仅可以节省工作时间,还能省心省力,减少人为失误。软工的构建、开发环境都对环境的一致性要求较高。在云下阶段服务器一直采用的是 ansible 来进行环境配置管理。使用 playbook 完成服务器环境的初始化交付,命令行对支持服务器环境维护、工具更新。目前业务开发环境服务器数量已经 4500+,编译服务器数量也有 2000+。随着服务器数量增加和业务环境的变化。ansible 也暴露出如下缺点:
执行速度:ansible 基于 ssh 对服务器进行管理,每次执行任务都需要连接到目标主机,在大规模环境中执行任务会比较慢;
环境一致性:软工业务对于某些环境需保持一致权限(比如 root 环境下的公私钥),这些环境直接影响构建的成功率。一旦环境发生改变,ansible 无法自我检查和修复;
puppet 介绍
什么是 puppet
基本定义:
Puppet 是一个 IT 基础设施自动化管理工具,它主要用于帮助系统管理员管理基础设施的整个生命周期,包括供应(provisioning)、配置(configuration)、联动(orchestration)及报告(reporting)。 基于 Ruby 语言开发的配置管理软件,特别适用于 Linux、Unix 平台。
它通过声明性、基于模型的方法进行 IT 自动化管理,使得系统管理员能够定义基础设施配置的目标状态,并自动确保系统保持在这种状态。
功能特点:
- 资源管理
Puppet 能够管理多达 40 多种资源,如文件、用户、组、主机、软件包、服务、cron 任务、exec 执行命令等。这些系统实体在 Puppet 中被称之为资源。 - 依赖关系处理:
Puppet 的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。 - 自动化部署:
基于 Puppet,可以实现自动化重复任务、快速部署关键性应用以及在本地或云端完成主动管理变更和快速扩展架构规模等。 - 报告与审计:
Puppet 提供了强大的报告功能,能够报告当下状态及目标状态的不同,以及达成目标状态所进行的任何强制性改变。
架构与工作原理
架构
Puppet 主要有两种运行模式:客户端-服务器(C/S)模式和独立运行模式(stand-alone)
工作原理:
- 初始化连接:
Puppet Agent 启动时,会向 Puppet Master 发送一个连接请求,建立 SSL 加密的通信通道。 - 收集 Facts:
Puppet Agent 调用 Facter 工具,收集当前节点的系统信息(如操作系统版本、硬件信息、网络配置等),这些信息被称为 Facts。
root@xxxx:~# apt-get install puppet
###安装 puppet 之后自动安装 facter
root@xxxx:~# facter
architecture => amd64
augeasversion => 1.4.0
bios_release_date => 04/01/2014
bios_vendor => SeaBIOS
bios_version => rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org
blockdevice_vda_size => 59055800320
blockdevice_vda_vendor => 0x1af4
blockdevice_vdb_size => 376832
blockdevice_vdb_vendor => 0x1af4
blockdevice_vdc_size => 3758096384000
blockdevice_vdc_vendor => 0x1af4
blockdevice_vdd_size => 214748364800
blockdevice_vdd_vendor => 0x1af4
blockdevice_vde_size => 429496729600
blockdevice_vde_vendor => 0x1af4
blockdevice_vdf_size => 4398046511104
blockdevice_vdf_vendor => 0x1af4
blockdevice_vdg_size => 54760833024
blockdevice_vdg_vendor => 0x1af4
blockdevice_vdh_size => 2199023255552
blockdevice_vdh_vendor => 0x1af4
blockdevice_vdj_size => 3758096384000
blockdevice_vdj_vendor => 0x1af4
blockdevice_vdl_size => 3877281726464
blockdevice_vdl_vendor => 0x1af4
blockdevices => vda,vdb,vdc,vdd,vde,vdf,vdg,vdh,vdj,vdl
facterversion => 2.4.6
filesystems => erofs,ext2,ext3,ext4,iso9660,squashfs,vfat
fqdn => xxxx
gid => root
hardwareisa => x86_64
hardwaremodel => x86_64
hostname => xxxx
id => root
interfaces => docker0,eth0,eth1,lo,lxcbr0
ipaddress => 192.168.253.1
ipaddress_docker0 => 192.168.253.1
ipaddress_eth0 => 10.xxxx
ipaddress_eth1 => 192.168.144.102
ipaddress_lo => 127.0.0.1
ipaddress_lxcbr0 => 10.0.3.1
is_virtual => true
kernel => Linux
kernelmajversion => 4.15
kernelrelease => 4.15.0-147-generic
kernelversion => 4.15.0
lsbdistcodename => xenial
lsbdistdescription => Ubuntu 16.04.6 LTS
lsbdistid => Ubuntu
lsbdistrelease => 16.04
lsbmajdistrelease => 16.04
macaddress => 02:42:a2:55:9e:c3
macaddress_docker0 => 02:42:a2:55:9e:c3
macaddress_eth0 => fa:16:ea:55:20:b7
macaddress_eth1 => 00:1b:11:09:9e:69
macaddress_lxcbr0 => 00:16:3e:00:00:00
manufacturer => KubeVirt
memoryfree => 35.34 GB
memoryfree_mb => 36186.20
memorysize => 43.95 GB
memorysize_mb => 45007.75
mtu_docker0 => 1500
mtu_eth0 => 1500
mtu_eth1 => 1500
mtu_lo => 65536
mtu_lxcbr0 => 1500
netmask => 255.255.255.0
netmask_docker0 => 255.255.255.0
netmask_eth0 => 255.255.224.0
netmask_eth1 => 255.255.255.0
netmask_lo => 255.0.0.0
netmask_lxcbr0 => 255.255.255.0
network_docker0 => 192.168.253.0
network_eth0 => 10.xx.xx.xx
network_eth1 => 192.168.144.0
network_lo => 127.0.0.0
network_lxcbr0 => 10.0.3.0
operatingsystem => Ubuntu
operatingsystemmajrelease => 16.04
operatingsystemrelease => 16.04
.................
swapfree => 49.59 GB
swapfree_mb => 50780.48
swapsize => 49.59 GB
swapsize_mb => 50781.25
system_uptime => {"seconds"=>2509325, "hours"=>697, "days"=>29, "uptime"=>"29 days"}
timezone => CST
type => Other
uniqueid => 007f0100
uptime => 29 days
uptime_days => 29
uptime_hours => 697
uptime_seconds => 2509325
uuid => 9C0B0459-5D9E-4B10-A69C-CDF0D0EFD4E2
virtual => kvm
- 发送 Facts 到 Puppet Master:
Puppet Agent 将收集到的 Facts 通过 SSL 连接发送给 Puppet Master。 - 解析配置:
Puppet Master 接收到 Facts 后,会根据 Facts 中的信息以及存储在 Puppet Master 上的配置清单(manifests)来解析出该节点应有的配置状态。
Puppet Master 会查找与客户端主机名相匹配的 node 定义,并解析该 node 定义中指定的资源及其状态。 - 生成 Catalog:
Puppet Master 将解析结果编译成一个 Catalog(目录),其中包含了一系列需要应用到客户端的资源及其配置指令。 - 发送 Catalog 到 Puppet Agent:
Puppet Master 将 Catalog 通过 SSL 连接发送给 Puppet Agent。 - 执行配置:
Puppet Agent 接收到 Catalog 后,会验证 Catalog 中的资源及其配置指令,并执行必要的操作以确保系统达到 Catalog 中指定的状态。
如果需要,Puppet Agent 还会从 Puppet Master 指定的文件服务器上下载所需的文件或软件包。 - 报告执行结果:
Puppet Agent 将执行结果(包括成功、失败或更改的详细信息)通过 SSL 连接发送给 Puppet Master。
Puppet Master 将执行结果记录到日志中,并可以通过报告系统进一步分析或展示。
工作流程图
- 独立运行模式的工作模型:
puppet apply -v xxxx.pp ##一般以这种方式运行,用于调试验证居多
- C/S 运行模式的工作模型
puppet 入门
puppet 语法格式
Usage: puppet <subcommand> [options] <action> [options]
root@xxxxx:~# puppet describe -l ##获取所支持的所有的资源类型:
These are the types known to puppet:
augeas - Apply a change or an array of changes to the ...
computer - Computer object management using DirectorySer ...
cron - Installs and manages cron jobs
exec - Executes external commands
file - Manages files, including their content, owner ...
filebucket - A repository for storing and retrieving file ...
group - Manage groups
host - Installs and manages host entries
interface - This represents a router or switch interface
k5login - Manage the `.k5login` file for a user
macauthorization - Manage the Mac OS X authorization database
mailalias - .. no documentation ..
maillist - Manage email lists
mcx - MCX object management using DirectoryService ...
mount - Manages mounted filesystems, including puttin ...
nagios_command - The Nagios type command
nagios_contact - The Nagios type contact
nagios_contactgroup - The Nagios type contactgroup
nagios_host - The Nagios type host
nagios_hostdependency - The Nagios type hostdependency
nagios_hostescalation - The Nagios type hostescalation
nagios_hostextinfo - The Nagios type hostextinfo
nagios_hostgroup - The Nagios type hostgroup
nagios_service - The Nagios type service
nagios_servicedependency - The Nagios type servicedependency
nagios_serviceescalation - The Nagios type serviceescalation
nagios_serviceextinfo - The Nagios type serviceextinfo
nagios_servicegroup - The Nagios type servicegroup
nagios_timeperiod - The Nagios type timeperiod
notify - .. no documentation ..
package - Manage packages
resources - This is a metatype that can manage other reso ...
router - .. no documentation ..
schedule - Define schedules for Puppet
scheduled_task - Installs and manages Windows Scheduled Tasks
selboolean - Manages SELinux booleans on systems with SELi ...
selmodule - Manages loading and unloading of SELinux poli ...
service - Manage running services
ssh_authorized_key - Manages SSH authorized keys
sshkey - Installs and manages ssh host keys
stage - A resource type for creating new run stages
tidy - Remove unwanted files based on specific crite ...
user - Manage users
vlan - .. no documentation ..
whit - Whits are internal artifacts of Puppet's curr ...
yumrepo - The client-side description of a yum reposito ...
zfs - Manage zfs
zone - Manages Solaris zones
zpool - Manage zpools
root@xxxxx:~# puppet describe file -ms #获取 file 资源类型的属性
root@xxxxx:~# puppet describe file -ms
.............
Parameters
----------
backup, checksum, content, ctime, ensure, force, group, ignore, links,
mode, mtime, owner, path, purge, recurse, recurselimit, replace,
selinux_ignore_defaults, selrange, selrole, seltype, seluser, show_diff,
source, source_permissions, sourceselect, target, type, validate_cmd,
validate_replacement
Meta Parameters
---------------
alias, audit, before, loglevel, noop, notify, require, schedule, stage,
subscribe, tag
Providers
---------
posix, windows
基于单节点配置语言(资源)
资源特性
资源三要素
每个资源都应该有 type、title、attributes,如:
type {'title':
attribute1 => value1,
attribute2 => value2,
}
注意: title 必须在同一个资源类型中唯一,且必须小写
其他属性:
在资源的属性(attributes)中,除了资源本身的属性中,我们还可以为它定义以下属性:
- namevar:
大多数 type 都有在目标系统上标识资源的一个属性,这个常常被称为 namevar,namevar 的值在配的资源 type 中必须是唯一的,除了少数例外(exec)。 - ensure:
用于大多数资源中,用于控制资源的存在性 - metaparameters:
用于资源引用,资源的依赖关系,通知关系等。
常用的资源类型:
group、user、file、package、service、exec、cron、notify
后面将会围绕这几个常用资源展开
定义资源
group ##应用于组管理
资源属性:
name: namevar 组名
gid: GID
system: true|false
ensure: present|absent
members: 组内成员
示例
root@xxxxx:/etc/puppet/manifests# vim group.pp
group {"test":
gid => 1031,
system => true,
ensure => present
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test --noop group.pp
Notice: Compiled catalog for xxxxx in environment production in 0.09 seconds
Info: Applying configuration version '1721123475'
Notice: /Stage[main]/Main/Group[test]/ensure: current_value absent, should be present (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.02 seconds
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test group.pp
Notice: Compiled catalog for xxxxx in environment production in 0.09 seconds
Info: Applying configuration version '1721123621'
Notice: /Stage[main]/Main/Group[test]/ensure: created
Notice: Finished catalog run in 0.04 seconds
root@xxxxx:/etc/puppet/manifests# cat /etc/group |grep test
test:x:1031:
user ##用户管理
资源属性:
comment: 注释信息
ensure: true|false
expiry: 过期期限
gid: 基本组
groups: 附加组
home: 家目录
shell: 默认 shell
name: namevar 用户名
system: true|false
uid: UID
password: 这里需要的是加密后的密码
####可以用这个方式生成密码:
root@xxxxx:~# openssl passwd -1 "test"
$1$JBG8XLBI$3ML7nIidQhpzfarI20h97/
示例
root@xxxxx:/etc/puppet/manifests# vim user.pp
user {'hupeng':
name => 'hupeng',
uid => 3000,
gid => 10000, ###组 id 需要存在,不然会报错
home => '/home/hupeng',
shell => '/bin/bash',
comment => 'puppet create user',
ensure => present,
password => '$1$JBG8XLBI$3ML7nIidQhpzfarI20h97/'
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test user.pp
Notice: Compiled catalog for xxxxx in environment production in 0.12 seconds
Info: Applying configuration version '1721124393'
Notice: /Stage[main]/Main/User[hupeng]/ensure: created
Notice: Finished catalog run in 0.04 seconds
file ##管理文件的内容、从属关系以及权限,内容可以通过 content 属性直接给出,也可以通过 source 属性根据远程服务器路径下载生成
资源属性:
backup: .puppet.bak 覆盖前备份
content: 直接给出文件内容,支持\n,\t
source: 从指定位置下载文件,可以是本地文件路径(单机模式),也可以是 puppet:///modules/module_name/file_name
ensure: file,directory,link,present,absent
force: 强制创建,可用值 yes,no,true,false
group: 属组
owner: 属主
mode: 权限,支持八进制格式权限,以及 u,g,o 的赋值方式
path: namevar,绝对路径
target: 当 ensure 为 link 时,target 表示 path 指向的文件是一个符号文件,其目标为此 target 属性指向的路径
示例:
eg1:
root@xxxxx:/etc/puppet/manifests# vim file1.pp
file {"test":
ensure => file,
path => "/tmp/passwd",
backup => ".$::uptime_seconds.bk",
owner => "root",
mode => 0644,
source => "/etc/passwd",
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test file1.pp
Notice: Compiled catalog for xxxxx in environment production in 0.09 seconds
Info: Applying configuration version '1721127255'
Notice: /Stage[main]/Main/File[test]/ensure: defined content as '{md5}e873d075ba34ca82adf5c9189efd1e1d'
Notice: Finished catalog run in 0.04 seconds
root@xxxxx:/etc/puppet/manifests# ll /tmp/ |grep pass
-rw-r--r-- 1 root root 3169 Jul 16 18:54 passwd
eg2:
root@xxxxx:/etc/puppet/manifests# vim file2.pp
file {"test01":
ensure => link,
target => "/etc/apt/sources.list",
path => "/tmp/sources.list",
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test file2.pp
Notice: Compiled catalog for xxxxx in environment production in 0.10 seconds
Info: Applying configuration version '1721128135'
Notice: /Stage[main]/Main/File[test01]/ensure: created
Notice: Finished catalog run in 0.02 seconds
root@xxxxx:/etc/puppet/manifests# ll /tmp/ |grep apt
lrwxrwxrwx 1 root root 21 Jul 16 19:08 sources.list -> /etc/apt/sources.list
exec ##运行一个外部命令:命令应该具备"幂等性"
幂等性:
- 命令本身具备幂等性,运行多少遍都无影响
- 资源有onlyif,unless,create等属性以实现命令的条件运行
- 资源有refreshonly的属性,以实现只有订阅的资源发生时才执行
资源属性:
command:运行的命令 namevar
creates:此属性指定的文件不存在时才运行
cwd:此属性指定的路径下运行命令
user:以指定的用户身份运行命令
group:以指定的用户组身份运行命令
onlyif:此属性指定一个命令,此命令正常(退出码为 0)运行时,当前 command 才会运行
unless:此属性指定一个命令,此命令非正常(退出码为非 0)运行时,当前 command 才会运行
refresh:接受其他资源发来的 refresh 通知时,默认时重新执行 exec 定义的 command,refresh 属性可改变这种行为,即可指定仅在 refresh 时运行的命令
refreshonly:仅在收到 refresh 通知,才运行此资源
returns:期望返回的返回值
path:命令查找的路径
tries:尝试执行的次数
timeout:超时的时长
示例:
eg1.
root@xxxxx:/etc/puppet/manifests# vim exec.pp
exec {"test":
command => "echo 'hello puppet\n' > /tmp/test.file",
creates => '/tmp/test.file',
path => ['/usr/bin','/usr/sbin','/bin'],
user => 'root',
group => 'root',
tries => 2,
timeout => 5
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test exec.pp
Notice: Compiled catalog for xxxxx in environment production in 0.05 seconds
Info: Applying configuration version '1721128602'
Notice: /Stage[main]/Main/Exec[test]/returns: executed successfully
Notice: Finished catalog run in 0.04 seconds
root@xxxxx:/etc/puppet/manifests# cat /tmp/test.file
hello puppet
eg2:
root@xxxxx:/etc/puppet/manifests# vim exec1.pp
exec {"test-01":
command => "echo 'yes' > /tmp/test.file",
onlyif => "test -e /tmp/test.file",
path => ['/usr/bin','/usr/sbin',"/bin"]
}
exec {"test1-02":
command => "echo 'no' > /tmp/test.file1",
unless => "test -e /tmp/test.file",
path => ['/usr/bin','/usr/sbin',"/bin"]
}
root@xxxxx:/etc/puppet/manifests# ll /tmp/ |grep test
-rw-r--r-- 1 root root 4 Jul 16 19:22 test.file
root@xxxxx:/etc/puppet/manifests# cat /tmp/test.file
yes
eg3.
root@xxxxx:/etc/puppet/manifests# cat exec2.pp
file {'test':
path => "/tmp/issue",
source => "/etc/issue",
ensure => file,
notify => Exec['test']
}
exec {'test':
command => "echo '1' > /tmp/test.file",
refresh => "echo '2' > /tmp/test.file",
path => ['/usr/bin','/usr/sbin',"/bin"]
}
root@xxxxx:/etc/puppet/manifests# cat /tmp/test.file
2
eg4:
root@xxxxx:/etc/puppet/manifests# vim exec2.pp
file {'test':
path => "/tmp/issue",
source => "/etc/issue",
ensure => file,
notify => Exec['test']
}
exec {'test':
command => "echo '3' > /tmp/test.file",
path => ['/usr/bin','/usr/sbin',"/bin"],
refreshonly => true
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test exec2.pp
Notice: Compiled catalog for xxxxx in environment production in 0.13 seconds
Info: Applying configuration version '1721129561'
Notice: Finished catalog run in 0.03 seconds
root@xxxxx:/etc/puppet/manifests# cat /tmp/test.file
2
root@xxxxx:/etc/puppet/manifests# rm -rf /tmp/issue
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test exec2.pp
Notice: Compiled catalog for xxxxx in environment production in 0.13 seconds
Info: Applying configuration version '1721129590'
Notice: /Stage[main]/Main/File[test]/ensure: defined content as '{md5}3a78cec1d9c34187a871b34ef868c446'
Info: /Stage[main]/Main/File[test]: Scheduling refresh of Exec[test]
Notice: /Stage[main]/Main/Exec[test]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.05 seconds
root@xxxxx:/etc/puppet/manifests# cat /tmp/test.file
3
###因为具有幂等性,检查到/tmp/issue 没有变化,所没有触发命令执行
cron ##管理定时任务
资源属性:
ensure:present,absent
command:要运行的 job
hour:
minute:
month:
monthday:
weekday:
name:namevar
user:运行的用户
environment:运行时的环境变量
示例:
root@xxxxx:/etc/puppet/manifests# cat cron.pp
cron {'test':
name => "sync time",
command => "ntpdate ntp.myoas.com",
ensure => present,
minute => 45,
hour => 19,
monthday => '*',
month => 7,
weekday => '*',
}
####星号(*)需要加单引号
root@xxxxx:/etc/puppet/manifests# crontab -l
# Puppet Name: sync time
45 19 * 7 * ntpdate ntp.myoas.com
package ##管理安装包
资源属性
install_options: 安装选项如["-y"]
ensure: installed,latest, present, absent(installed 表示软件若不存在则安装,absent 和 purged 都表示卸载,但是当要卸载的软件包为其他软件包的依赖时,absent 会拒绝执行卸载命令,而 purged 则会依然卸载,latest 表示升级到最新版本)
name: 程序包名称
source:包来源,可以本地文件或者 url
provider: 指定供应商
示例:
root@xxxxx:/etc/puppet/manifests# cat package.pp
package {'test':
name => 'xmldiff',
ensure => present,
install_options => [ '--allow-unauthenticated'],
}
root@xxxxx:/etc/puppet/manifests# dpkg -l |grep xmldiff
ii xmldiff 0.6.10-2.1 amd64 tree to tree correction between xml documents
service ##管理服务
资源属性:
enable:是否开机自动启动,true|false
ensure:启动(running),停止(stopped)
hasrestart: 是否支持 restart 参数
hasstatus: 是否支持 status 参数
name: 服务名称,NameVar
path: 服务查找路径
pattern:用于搜索此服务相关的进程的模式;当脚本不支持 restart/status 时,用于确定服务是否支持处于运行状态
restart:自定义脚本
status:自定义脚本
stop:自定义脚本
示例:
root@xxxxx:/etc/puppet/manifests# cat service.pp
service {'test':
name => "nginx",
ensure => running,
hasstatus => true,
hasrestart => true,
restart => "systemctl reload nginx",
path => ['/usr/bin','/usr/sbin']
}
root@xxxxx:/etc/puppet/manifests# netstat -ntlp |grep 80
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test service.pp
Notice: Compiled catalog for xxxxx in environment production in 0.11 seconds
Info: Applying configuration version '1721131446'
Notice: /Stage[main]/Main/Service[test]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Main/Service[test]: Unscheduling refresh on Service[test]
Notice: Finished catalog run in 0.05 seconds
root@xxxxx:/etc/puppet/manifests# netstat -ntlp |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 534635/nginx -g dae
tcp6 0 0 :::80 :::* LISTEN 534635/nginx -g dae
notify ##打印信息
资源属性:
message:要发送的消息的内容
示例:
root@xxxxx:/etc/puppet/manifests# cat notify.pp
notify{'test':
message => 'hello puppet'
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v --test notify.pp
Notice: Compiled catalog for xxxxx in environment production in 0.03 seconds
Info: Applying configuration version '1721131887'
Notice: hello puppet
Notice: /Stage[main]/Main/Notify[test]/message: defined 'message' as 'hello puppet'
Notice: Finished catalog run in 0.03 seconds
元参数(Metaparameters)
元参数描述:
元参数属于资源的特殊属性,可以通过这个属性的定义资源间的依赖的关系,或者资源间的通知关系。
before、require、 -> ##表示依赖关系
notify、subscribe、~> ##表示通知关系
依赖关系
root@xxxxx:/etc/puppet/manifests# cat nginx.pp
package {'nginx':
name => 'nginx',
ensure => latest,
before => File["config"],
}
file {'config':
source => "/root/manifest/conf/nginx.conf",
path => "/etc/nginx/nginx.conf",
backup => ".puppet.bak",
ensure => file,
}
service {'nginx':
name => 'nginx',
ensure => running,
hasstatus => true,
hasrestart => true,
restart => "systemctl reload nginx",
path => ["/usr/sbin","/usr/bin"],
require => [Package['nginx'],File['config']]
}
A before B: B 依赖于 A
B require A: B 需要 A
A -> B ->C :链式依赖,先执行 A,然后 B,最后 C
另外两种表现形式:
形式 1:
root@xxxxx:/etc/puppet/manifests# cat nginx.pp
package {'nginx':
name => 'nginx',
ensure => latest,
# before => File["config"],
}->
file {'config':
source => "/root/manifest/conf/nginx.conf",
path => "/etc/nginx/nginx.conf",
backup => ".puppet.bak",
ensure => file,
}->
service {'nginx':
name => 'nginx',
ensure => running,
hasstatus => true,
hasrestart => true,
restart => "systemctl reload nginx",
path => ["/usr/sbin","/usr/bin"],
# require => [Package['nginx'],File['config']]
}
形式 2:
package {'nginx':
name => 'nginx',
ensure => latest,
# before => File["config"],
}
file {'config':
source => "/root/manifest/conf/nginx.conf",
path => "/etc/nginx/nginx.conf",
backup => ".puppet.bak",
ensure => file,
}
service {'nginx':
name => 'nginx',
ensure => running,
hasstatus => true,
hasrestart => true,
restart => "systemctl reload nginx",
path => ["/usr/sbin","/usr/bin"],
# require => [Package['nginx'],File['config']]
}
Package["nginx"] -> File["config"] -> Service ['nginx']
###资源引用时,type 首字母必须大写,比如如 File[“nginx”]
通知关系
root@xxxxx:/etc/puppet/manifests# cat nginx01.pp
package {'nginx':
name => 'nginx',
ensure => latest
} ~>
exec {'log':
command => "echo 'package nginx install ok' > /tmp/test.log",
path => ['/usr/bin','/usr/sbin',"/bin"],
refreshonly => true
}
file {'config':
source => "/root/manifest/conf/nginx.conf",
path => "/etc/nginx/nginx.conf",
backup => ".puppet.bak",
ensure => file,
notify => Service['nginx'] ##配置文件变动之后通知执行 Service['nginx']资源
} ~>
exec {'log1':
command => "echo 'nginx conf replace ok' >> /tmp/test.log",
refreshonly => true,
path => ['/usr/bin','/usr/sbin',"/bin"]
}
service {'nginx':
name => 'nginx',
ensure => running,
hasstatus => true,
hasrestart => true,
restart => "systemctl reload nginx",
path => ["/usr/sbin","/usr/bin","/bin"],
require => [Package['nginx'],File['config']],
subscribe => File['config'] ##监听配置文件变动之后执行 Service['nginx']资源
}
A notify B : A 变动,通知 B 执行
A subscribe B: A 监听 B,B 发生变动,执行 A 资源
链式通知: ~>
##通知信息,常用的就是在更改配置信息后重新启动服务等之类的通知。
puppet 中的变量
变量命名与定义
- 命名规则:
Puppet 变量的名称必须以$符号开头,后接变量名。变量名可以是字母、数字、下划线(_)的组合,但不能以数字开头。 - 定义方式:
使用赋值操作符=将值赋给变量。例如,$webserver = nginx;表示将字符串"nginx"赋值给变量$webserver。
变量值类型
- 字符串:
非结构化的文本字符串,可以使用引号(单引号或双引号)或不使用引号。单引号表示强引用(不进行变量替换),双引号表示弱引用(进行变量替换)。 - 数值:
包括整数和浮点数。Puppet 在数值上下文中将数值视为数值型,在其他情况下则视为字符串。 - 布尔型:
true 和 false,不能加引号。某些表达式和类型(如非空字符串、非零数值等)会自动转换为布尔型。 - 数组:
中括号[]内以逗号分隔的列表,元素可以是任意数据类型,包括其他数组和哈希。 - 哈希(Hash):
键值对集合,键为字符串,值为任意数据类型。使用=>分隔键和值,整个哈希定义在{}内。 - undef:
表示变量未被赋值的状态,类似于其他编程语言中的 null 或 None。
变量作用域
Puppet 中的变量作用域用于限定变量的可见性和使用范围。主要的作用域包括:
- 顶级作用域(Top Scope):
全局可见,但通常用于存储系统级或全局的配置信息。 - 节点作用域(Node Scope):
在节点级别定义,可用于存储与特定节点相关的配置信息。 - 类作用域(Class Scope):
在类内部定义,仅在该类及其子类中可见。 - 资源作用域(Resource Scope):
在资源定义内部定义,仅在该资源定义内部可见。
变量引用
简短名称:直接使用变量名(如$webserver)引用变量。
完全限定名称(FQN):在复杂或大型配置中,为了避免变量名冲突,可以使用完全限定名称(如$::scope::variable)来引用变量。
内建变量
Puppet 还提供了内建变量,这些变量由 Puppet 系统或 facter(一个系统信息收集工具)自动生成,并可在配置文件中直接使用。例如:
- agent 端内建变量:
如$clientcert(agent 端的证书)、$clientversion(agent Puppet 的版本信息)等。 - master 端内建变量:
如$servername(服务端名称)、$serverip(服务端 IP)、$serverversion(服务端 Puppet 的版本信息)等。 - facter 变量:
facter 收集的系统信息(如操作系统类型、硬件信息等),以变量形式提供给 Puppet 使用。
正则表达式
非标准的数据类型,不能赋值给变量,仅能用在接受=~或!~操作符的位置
语法结构:
(?<ENABLED OPTION>:<SUBPATTERN>)
(?-<DISABLED OPTION>:<SUBPATTERN>)
OPTION:
i:忽略大小写
m:把.当换行符
x:忽略模式中的空白的注释
示例
# 定义变量
$webserver = 'nginx'
# 使用变量定义资源
package { "$webserver":
ensure => installed,
}
puppet 流程控制语句
if 语句
说明
条件判断主要通过 if、elsif(可选)、else(可选)语句来实现,条件可以基于变量、事实(facts)、资源的状态等多种因素。
单分支:
if CONDITION {
statement
……
}
双分支:
if CONDITION {
statement
……
}
else{
statement
……
}
多分支:
if CONDITION {
statement
……
}
elsif CONDITION{
statement
……
}
else{
statement
……
}
##其中,CONDITION 的给定方式有如下三种:
- 变量
- 比较表达式
- 有返回值的函数
示例
root@xxxxx:/etc/puppet/manifests# cat if.pp
if $operatingsystem =~ /(?i-mx:redhat)/ {
$db_pkg='mariadb-server'
}else{
$db_pkg='mysql-server'
}
notify {"printinfo":
message => "db name $db_pkg"
}
root@xxxxx:/etc/puppet/manifests# puppet apply -v if.pp --test
Notice: Compiled catalog for xxxxx in environment production in 0.03 seconds
Info: Applying configuration version '1721179142'
Notice: db name mysql-server
Notice: /Stage[main]/Main/Notify[printinfo]/message: defined 'message' as 'db name mysql-server'
Notice: Finished catalog run in 0.03 seconds
case 语句
说明
- 类似 if 语句,case 语句会从多个代码块中选择一个分支执行,这跟其它编程语言中的 case 语句功能一致。
- case 语句会接受一个控制表达式和一组 case 代码块,并执行第一个匹配到控制表达式的块。
使用语法如下:
case CONTROL_EXPRESSION {
case1: { ... }
case2: { ... }
case3: { ... }
……
default: { ... }
}
##其中,CONTROL_EXPRESSION 的给定方式有如下三种:
变量
表达式
有返回值的函数
各 case 的给定方式有如下五种:
直接字串;
变量
有返回值的函数
正则表达式模式;
default
示例
root@xxxxx:/etc/puppet/manifests# cat case.pp
case $osfamily {
"RedHat": { $webserver='httpd' }
/(?i-mx:debian)/: { $webserver='apache2' }
default: { $webserver='apache2' }
}
package {"$webserver":
ensure => installed,
}
file {'apache2.conf':
path => '/etc/apache2/apache2.conf',
source => '/root/manifests/apache2.conf',
ensure => file,
}
service {'apache2':
ensure => running,
enable => true,
restart => 'systemctl restart apache2.service',
subscribe => File['apache2.conf'],
}
Package["$webserver"] -> File["apache2.conf"] -> Service["apache2"]
selector 语句
说明
- selector 只能用于期望出现直接值(plain value) 的地方,这包括变量赋值、资源属性、函数参数、资源标题、其它 selector。
- selector 不能用于一个已经嵌套于于 selector 的 case 中,也不能用于一个已经嵌套于 case 的 case 语句中。
具体语法如下:
CONTROL_VARIABLE ? {
case1 => value1,
case2 => value2,
...
default => valueN,
}
###
其中,CONTROL_EXPRESSION 的给定方式有如下三种:
变量
表达式
有返回值的函数
各 case 的给定方式有如下五种:
直接子串;
变量;
有返回值的函数;
正则表达式模式;
default
注意事项:
- 整个 selector 语句会被当作一个单独的值,puppet 会将控制变量按列出的次序与每个case进行比较,并在遇到一个匹配的case后,将其值作为整个语句的值进行返回,并忽略后面的其它case;
- 控制变量与各case比较的方式与case语句相同,但如果没有任何一个 case 与控制变量匹配时,puppet 在编译时将会返回一个错误,因此,实践中,其必须提供default case;
- selector 的控制变量只能是变量或有返回值的函数,切记不能使用表达式;
- 各case可以是直接值(需要加引号) 、变量、能调用返回值的函数、正则表达式模式或default;
- 与case语句所不同的是,selector的各case不能使用列表;
- selector 的各case的值可以是一个除了hash以外的直接值、变量、能调用返回值的函数或其它的selector;
示例
root@xxxxx:/etc/puppet/manifests# vim selector.pp
$pkgname = $operatingsystem ? {
/(?i-mx:(ubuntu|debian))/ => 'apache2',
/(?i-mx:(redhat|fedora|centos))/ => 'httpd',
default => 'httpd',
}
notify {"test":
message => "web server $pkgname"
}
标签:入门,nginx,基础,etc,puppet,test,root,xxxxx
From: https://blog.csdn.net/weixin_46546303/article/details/140478216