自动化运维工具之Puppet常用资源(一)
前文我们聊到了puppet的架构,单机模型和master/agent模型的工作流程以及puppet的基础使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14052241.html;今天我们主要来了解下puppet的核心资源的使用;
什么是资源?
在puppet中,资源就是指我们要操作被管控端主机的对象;puppet中的资源概念有点类似ansible中的模块,在ansible中不同模块有着不同的功能,比如用户管理,我们就要用user模块,文件管理就要用file模块,执行命令有shell模块和command模块;puppet中的资源也是类似的作用,不同的是puppet中资源是高度抽象的;所谓高度抽象就是指用户无需关心底层操作系统接口;比如我们要在被管控端安装一个nginx软件,如果用puppet来实现,我们直接使用package这个资源即可完成,用户不用考虑底层到底是windows还是centos或者ubuntu,puppet它能够自动识别,然后采用不同的安装方法;而在ansible中对于不同操作系统,使用的模块有所不同,比如redhat系列要使用yum这个模块,debian系列要使用apt模块;puppet把相似的资源被抽象成同一种资源类型,比如程序包资源,用户资源以及服务资源等;将资源属性或状态的描述与其实现方式剥离开;如安装程序包用户无需关心使用什么方法去实现,只需要描述清楚资源的目标状态以及相关属性信息即可;
puppet常用资源的使用
1、group:该资源类型主要用来管理被管控端主机上的组;
主要属性
name:该属性主要用来描述组名,namevar如果默认不人工手动指定,则以title字符串来替代;
gid:该属性用来描述GID(组ID);
system:该属性用来描述是否为系统组,取值yes/no或者true/false;
ensure:该属性用来描述目标状态(即用户期待目标主机对应该资源的期望状态),取值present/absent;
members:该属性用来描述组中的成员用户信息;
示例:创建一个test组
[root@node12 ~]# cat group.pp group{'create_group': name => 'test', gid => 1212, system => false, ensure => present, } [root@node12 ~]#
模拟运行以上资源清单检查是否有语法错误
[root@node12 ~]# puppet apply -v --noop group.pp Notice: Compiled catalog for node12.test.org in environment production in 0.05 seconds Info: Applying configuration version '1606827824' Notice: /Stage[main]/Main/Group[create_group]/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@node12 ~]#
应用到本地主机
[root@node12 ~]# puppet apply -v group.pp Notice: Compiled catalog for node12.test.org in environment production in 0.05 seconds Info: Applying configuration version '1606827835' Notice: /Stage[main]/Main/Group[create_group]/ensure: created Notice: Finished catalog run in 0.08 seconds [root@node12 ~]#
验证:查看本机是否创建test组?对应gid是否是我们指定的gid?
[root@node12 ~]# getent group test test:x:1212: [root@node12 ~]#
2、user:该资源类型主要用来管理被管控端主机上的用户,如新建用户,删除用户等等;
主要属性
name:用户名,namevar
uid:UID;
gid:基本组id;
groups:附加组,不能包含基本组;
comment:注释;
expiry:过期时间;
home:家目录;
shell:默认shell类型;
system:是否为系统用户,取值yes/no或者true/false;
ensure:用户期望的目标状态,取值present/absent;
password:加密后的密码串;
示例:创建一个用户
[root@node12 ~]# cat user.pp user{"create_user": name => "jerry", uid => 1213, groups => ["test","test1","test2","test3"], comment => "this is create test user", system => no, ensure => present, } [root@node12 ~]#
验证语法和应用到本机
[root@node12 ~]# puppet apply -v --noop user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.06 seconds Info: Applying configuration version '1606829084' Notice: /Stage[main]/Main/User[create_user]/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@node12 ~]# puppet apply -v user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.06 seconds Info: Applying configuration version '1606829091' Notice: /Stage[main]/Main/User[create_user]/ensure: created Notice: Finished catalog run in 0.05 seconds [root@node12 ~]#
验证:查看jerry用户是否创建完成,对应属性是否是我们指定的属性呢?
[root@node12 ~]# id jerry uid=1213(jerry) gid=1213(jerry) groups=1213(jerry),1000(test1),1001(test2),1002(test3),1212(test) [root@node12 ~]# getent passwd jerry jerry:x:1213:1213:this is create test user:/home/jerry:/bin/bash [root@node12 ~]#
以上示例在指定附加组是系统上已经存在的情况,如果指定的组没有这么办呢?我们知道puppet执行资源清单时,有一个很重要的特性,幂等性;所谓幂等性就是指不管执行多少遍资源清单,对应的目标状态会保持一致,如果应系统指定的资源不是用户定义的目标状态,puppet会强制让其状态保持为目标状态,如果对应系统资源状态满足我们定义的目标状态,则不执行或跳过;结合上述说的,在创建用户时,指定的附加组不存在,理论上我们应该先确保对应组存在,然后再创建用户;所以用户资源可能依赖组资源;简单讲user资源依赖group资源,在创建用户时,对应的附加组应该提前创建;
在puppet中资源和资源是有依赖关系的,定义资源和资源间的依赖关系有两种方式,如下
A before B: A优先于B,定义在A资源中;
{ ... before => Type['B'], ... }
B require A: B依赖于A,定义在B资源中;
{ ... require => Type['A'], ... }
示例:不定义依赖,应用资源清单,看看tom用户是否会被创建?
[root@node12 ~]# cat user.pp user{"tom": groups => ["mygrp","testgrp"], comment => "this is create test user", system => no, ensure => present, # require => [Group["mygrp"],Group["testgrp"]] } [root@node12 ~]# puppet apply -v --noop user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.06 seconds Info: Applying configuration version '1606832440' Notice: /Stage[main]/Main/User[tom]/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@node12 ~]# puppet apply -v user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.06 seconds Info: Applying configuration version '1606832447' Error: Could not create user tom: Execution of '/usr/sbin/useradd -c this is create test user -G mygrp,testgrp -M tom' returned 6: useradd: group 'mygrp' does not exist useradd: group 'testgrp' does not exist Error: /Stage[main]/Main/User[tom]/ensure: change from absent to present failed: Could not create user tom: Execution of '/usr/sbin/useradd -c this is create test user -G mygrp,testgrp -M tom' returned 6: useradd: group 'mygrp' does not exist useradd: group 'testgrp' does not exist Notice: Finished catalog run in 0.03 seconds [root@node12 ~]# id tom id: tom: no such user [root@node12 ~]#
提示:在puppet资源清单中“#”号代表注释;可以看到创建用户时,指定一个不存在的组给对应用户做附加组,它会提示我们对应的组不存在;当然对应的tom也不会被成功新建;
示例:定义依赖关系,再次执行资源清单,看看tom是否会被新建呢?
[root@node12 ~]# [root@node12 ~]# cat user.pp user{"tom": groups => ["mygrp","testgrp"], comment => "this is create test user", system => no, ensure => present, require => [Group["mygrp"],Group["testgrp"]] } [root@node12 ~]# puppet apply -v --noop user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.10 seconds Error: Could not find dependency Group[mygrp] for User[tom] at /root/user.pp:7 [root@node12 ~]#
提示:这里虽然定义了依赖的资源,但是它这里提示我们为在当前资源清单中找到对应的依赖资源定义内容;这里需要注意一点引用资源的方式是Type["resouce name"],其中type指资源类型,并且首字母必须大写;
在资源清单中定义被依赖的资源,再次执行资源清单,看看tom用户是否被创建?
[root@node12 ~]# cat user.pp user{"tom": groups => ["mygrp","testgrp"], comment => "this is create test user", system => no, ensure => present, require => [Group["mygrp"],Group["testgrp"]] } group{"mygrp": ensure => present, } group{"testgrp": ensure => present, } [root@node12 ~]# puppet apply -v --noop user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.10 seconds Info: Applying configuration version '1606833022' Notice: /Stage[main]/Main/Group[mygrp]/ensure: current_value absent, should be present (noop) Notice: /Stage[main]/Main/Group[testgrp]/ensure: current_value absent, should be present (noop) Notice: /Stage[main]/Main/User[tom]/ensure: current_value absent, should be present (noop) Notice: Class[Main]: Would have triggered 'refresh' from 3 events Notice: Stage[main]: Would have triggered 'refresh' from 1 events Notice: Finished catalog run in 0.02 seconds [root@node12 ~]# puppet apply -v user.pp Notice: Compiled catalog for node12.test.org in environment production in 0.10 seconds Info: Applying configuration version '1606833042' Notice: /Stage[main]/Main/Group[mygrp]/ensure: created Notice: /Stage[main]/Main/Group[testgrp]/ensure: created Notice: /Stage[main]/Main/User[tom]/ensure: created Notice: Finished catalog run in 0.08 seconds [root@node12 ~]# id tom uid=1214(tom) gid=1216(tom) groups=1216(tom),1214(mygrp),1215(testgrp) [root@node12 ~]#
提示:可以看到在定义了依赖关系以后,被依赖的资源要先执行;简单讲定义依赖关系就是指定资源执行的先后顺序;
除了以上方式定义资源执行的先后顺序,还可以使用以下方式定义资源执行的先后顺序
在被依赖的资源中使用before属性指定要优先那个资源执行
[root@node12 ~]# cat user.pp user{"tom": groups => ["mygrp","testgrp"], comment => "this is create test user", system => no, ensure => present, # require => [Group["mygrp"],Group["testgrp"]] } group{"mygrp": ensure => present, before => User["tom"], } group{"testgrp": ensure => present, before => User["tom"], } [root@node12 ~]#
单独定义资源执行顺序
[root@node12 ~]# cat user.pp user{"tom": groups => ["mygrp","testgrp"], comment => "this is create test user", system => no, ensure => present, } group{"mygrp": ensure => present, } group{"testgrp": ensure => present, } Group["testgrp"] -> Group["mygrp"] -> User["tom"] [root@node12 ~]#
提示:以上清单内容表示Group["testgrp"]要优先于Group["mygrp"]优先于User["tom"]资源;
删除testgrp,mygrp组和tom用户
[root@node12 ~]# groupdel mygrp [root@node12 ~]# groupdel testgrp [root@node12 ~]# userdel tom
不定义资源执行顺序,应用资源清单的顺序是
提示:默认在一个资源清单中的资源会自动解决依赖关系,通常被依赖的资源会从上至下依次执行;
定义资源执行顺序,应用资源清单,看看对应资源执行顺序是否是我们定义的资源顺序呢?
提示:可以看到定义了资源执行顺序以后,资源的执行顺序就是我们定义的顺序;
3、package:该资源类型用于管理被控端的包资源;
主要属性
name:包名称,namevar;
ensure:目标状态,取值有installed/present/latest,absent/purgud;
source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg;
provider:指定安装方式;
示例:安装redis服务
[root@node12 ~]# cat package.pp package{"redis": ensure => installed, } [root@node12 ~]#
应用资源清单
[root@node12 ~]# rpm -q redis package redis is not installed [root@node12 ~]# puppet apply -v --noop package.pp Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false. (at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default') Info: Applying configuration version '1606835569' Notice: /Stage[main]/Main/Package[redis]/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.08 seconds [root@node12 ~]# puppet apply -v package.pp Notice: Compiled catalog for node12.test.org in environment production in 0.19 seconds Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false. (at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default') Info: Applying configuration version '1606835576' Notice: /Stage[main]/Main/Package[redis]/ensure: created Notice: Finished catalog run in 2.88 seconds [root@node12 ~]# rpm -q redis redis-3.2.12-2.el7.x86_64 [root@node12 ~]#
4、service:该资源类型用于管理被控端的服务;
主要属性
ensure:定义目标状态,取值有running/stopped或者true/false;
enable:是否设置为开机启动,取值true/false;
name:服务名称,namevar
path:脚本的搜索路径,默认为/etc/init.d/;
binary:二进制程序路径,主要用于指定编译后的二进制程序路径;
hasrestart:是否有重启命令;
hasstatus:是否有status命令;
start:手动定义启动服务命令;
stop:手动定义停止服务命令;
status:手动定义查看服务状态命令;
restart:手动定义重启服务命令;
示例:启动redis
[root@node12 ~]# cat redis.pp service{"redis": ensure => running, enable => true, } [root@node12 ~]#
应用资源清单
[root@node12 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 *:27017 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node12 ~]# puppet apply -v --noop redis.pp Notice: Compiled catalog for node12.test.org in environment production in 0.06 seconds Info: Applying configuration version '1606835960' Notice: /Stage[main]/Main/Service[redis]/ensure: current_value stopped, should be running (noop) Info: /Stage[main]/Main/Service[redis]: Unscheduling refresh on Service[redis] 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.04 seconds [root@node12 ~]# puppet apply -v redis.pp Notice: Compiled catalog for node12.test.org in environment production in 0.07 seconds Info: Applying configuration version '1606835968' Notice: /Stage[main]/Main/Service[redis]/ensure: ensure changed 'stopped' to 'running' Info: /Stage[main]/Main/Service[redis]: Unscheduling refresh on Service[redis] Notice: Finished catalog run in 0.09 seconds [root@node12 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:6379 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 *:27017 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node12 ~]# systemctl is-enabled redis enabled [root@node12 ~]#
提示:可以看到应用清单文件以后,对应redis服务已经正常启动,并设置开机启动;
示例:停止redis服务,并禁用其开机启动
[root@node12 ~]# cat redis.pp service{"redis": ensure => stopped, enable => false, } [root@node12 ~]# puppet apply -v --noop redis.pp Notice: Compiled catalog for node12.test.org in environment production in 0.07 seconds Info: Applying configuration version '1606836096' Notice: /Stage[main]/Main/Service[redis]/ensure: current_value running, should be stopped (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.04 seconds [root@node12 ~]# puppet apply -v redis.pp Notice: Compiled catalog for node12.test.org in environment production in 0.07 seconds Info: Applying configuration version '1606836102' Notice: /Stage[main]/Main/Service[redis]/ensure: ensure changed 'running' to 'stopped' Notice: Finished catalog run in 0.11 seconds [root@node12 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 *:27017 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node12 ~]# systemctl is-enabled redis disabled [root@node12 ~]#
提示:可以看到执行了资源清单以后,对应服务就停掉了并且也禁用了开机启动;