自动化运维工具之Puppet模块

  • A+
所属分类:linux技术
摘要

  前文我们了解来puppet的变量、流程控制、正则表达式、类和模板的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14079208.html;今天我们来了解下puppet中的模块相关概念;

  前文我们了解来puppet的变量、流程控制、正则表达式、类和模板的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14079208.html;今天我们来了解下puppet中的模块相关概念;

  什么是模块?

  在puppet中模块的概念有点类似ansible中的角色;在puppet中模块就是把定义在一个资源清单中的各个资源拆分到不同的资源文件中,然后把对应的文件放在特定的目录中;简单讲puppet中的模块就是一个按约定的、预定义的结构存放了多个文件或子目录的目录,目录里的文件或子目录必须遵循某种命名规范;puppet会按照此种规范在特定位置查找模块所需文件,不过这些特定的目录可以通过puppet配置参数modulepath来指定;

  模块的目录结构

自动化运维工具之Puppet模块

  提示:MODULE NAME是模块的名称,模块名称必须是小写字母开头,可以包含小写字母,数字,下划线;不能将“main”,“setting”作为模块名称;manifests是用来存在当前模块的所有资源清单文件,每个资源清单文件中必须包含一个类或一个定义的类,但init.pp这个文件中只能包含一个单独的类定义,且类名必须同模块名相同;资源清单文件访问路径格式遵循MOUDLE_NAME::[SubDirectoryName::]ManifastFileName;这里需要注意一点访问资源清单文件,不需要加后缀.pp;files目录主要用来存放静态文件,这些静态文件可被节点下载使用,每个文件的访问遵循puppet://modules/MODULE_NAME/filename的路径格式;templates目录主要用来存放模版文件其访问路径遵循template('ModuleName/TemplateFileName')格式;lib目录主要用来存放自定义fact和自定义资源类型等;tests目录主要用来存放当前模块的使用帮助或使用范例文件;类似如何声明当前模块中的类以及定义的类型等;spec目录类似tests目录,不同tests目录的是,该目录主要存放lib中存放的自定义fact和资源类型的帮助或使用范例文件;一个模块中如果没有自定义fact或资源类型,后面的lib,tests,spec这三个目录可以不用创建;

  示例:将以下资源清单更改为模块

[root@slave03 ~]# cat redis.pp  class redis{         package{"redis":                 ensure  => installed,         }         service{"redis":                 ensure  => running,                 enable  => true,                 hasrestart      => true,                 restart => 'service redis restart',         } }   class redis::master($masterport='6379',$masterpass='admin') inherits redis {         file{"/etc/redis.conf":                 ensure  => file,                 content => template('/root/redis-master.conf.erb'),                 owner   => 'redis',                 group   => 'root',                 mode    => '0644',         }         Service["redis"]{                 subscribe       => File["/etc/redis.conf"],                 restart => 'systemctl restart redis'         } }  class redis::slave($masterip,$masterport='6379',$masterpass='admin') inherits redis {         file{"/etc/redis.conf":                 ensure  => file,                 content => template('/root/redis-slave.conf.erb'),                 owner   => 'redis',                 group   => 'root',                 mode    => '0644',         }         Service["redis"]{                 subscribe       => File["/etc/redis.conf"],                 restart => 'systemctl restart redis'         } } [root@slave03 ~]#  

  创建目录结构

[root@slave03 ~]# mkdir -p /etc/puppet/modules/redis/{manifests,files,templates,lib,tests,spec} [root@slave03 ~]# tree /etc/puppet/modules/redis/ /etc/puppet/modules/redis/ ├── files ├── lib ├── manifests ├── spec ├── templates └── tests  6 directories, 0 files [root@slave03 ~]#  

  提示:puppet默认模块存放在/etc/puppet/modules或/usr/share/puppet/modules/目录下,可以通过puppet config print modulepath 命令查看;如果要修改其模块存放位置,可以使用puppet config set modulepath 'path/to/somewhere';

  移动模版文件到templates目录下

[root@slave03 ~]# mv redis-master.conf.erb redis-slave.conf.erb /etc/puppet/modules/redis/templates/ [root@slave03 ~]# ll /etc/puppet/modules/redis/templates/ total 8 -rw-r--r-- 1 root root 1247 Dec  4 16:20 redis-master.conf.erb -rw-r--r-- 1 root root 1276 Dec  4 16:18 redis-slave.conf.erb [root@slave03 ~]#  

  在manifests目录下创建init.pp

[root@slave03 ~]# cat /etc/puppet/modules/redis/manifests/init.pp class redis{         package{"redis":                 ensure  => installed,         }         service{"redis":                 ensure  => running,                 enable  => true,                 hasrestart      => true,                 restart => 'service redis restart',         } } [root@slave03 ~]#  

  提示:通常这个init.pp这个文件主要用来定义基类;其他子类需要单独定一个文件;

  在manifests目下创建master.pp和slave.pp资源清单文件

[root@slave03 ~]# cat /etc/puppet/modules/redis/manifests/master.pp class redis::master($masterport='6379',$masterpass='admin') inherits redis {         file{"/etc/redis.conf":                 ensure  => file,                 content => template('redis/redis-master.conf.erb'),                 owner	=> 'redis',                 group   => 'root',                 mode    => '0644',         }         Service["redis"]{                 subscribe       => File["/etc/redis.conf"],                 restart => 'systemctl restart redis'         } } [root@slave03 ~]# cat /etc/puppet/modules/redis/manifests/slave.pp class redis::slave($masterip,$masterport='6379',$masterpass='admin') inherits redis {         file{"/etc/redis.conf":                 ensure  => file,                 content => template('redis/redis-slave.conf.erb'),                 owner	=> 'redis',                 group   => 'root',                 mode    => '0644',         }         Service["redis"]{                 subscribe       => File["/etc/redis.conf"],                 restart => 'systemctl restart redis'         } } [root@slave03 ~]#  

  提示:如果复制文件是一个模版需要将模版文件放在templates目录下,使用template内建函数访问时需要遵循template('ModuleName/TemplateFileName')的格式引用;如果是复制文件是一个普通文件(非模版格式文件)在对应的files目录要存在对应的文件;其次在用source属性指定访问文件时,需要使用puppet:///modules/ModuleName/filename的格式;

  最终redis模块目录结构

[root@slave03 ~]# tree /etc/puppet/modules/redis/ /etc/puppet/modules/redis/ ├── files ├── lib ├── manifests │   ├── init.pp │   ├── master.pp │   └── slave.pp ├── spec ├── templates │   ├── redis-master.conf.erb │   └── redis-slave.conf.erb └── tests  6 directories, 5 files [root@slave03 ~]#  

  查看puppet现有的模块

[root@slave03 ~]# puppet module list /etc/puppet/modules └── redis (???) /usr/share/puppet/modules (no modules installed) [root@slave03 ~]#  

  提示:可以看到redis模块已经可以看到,其实我们在对应的模块存放路径下创建目录就可以看到对应的名称;后面的问号是因为我们自定义的模块没有写说明信息,它这里可能是没有获取到指定的信息,所以显示问号;但这不影响我们使用模块;

  单机模型下使用模块

  调用模块(调用基类)

[root@slave03 ~]# rpm -q redis package redis is not installed [root@slave03 ~]# 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      80                                 [::]:3306                                           [::]:*                   LISTEN     0      128                                [::]:22                                             [::]:*                   LISTEN     0      100                               [::1]:25                                             [::]:*                   [root@slave03 ~]# puppet apply -v --noop -e 'include redis' Notice: Compiled catalog for slave03 in environment production in 0.49 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 '1607074610' Notice: /Stage[main]/Redis/Package[redis]/ensure: current_value absent, should be present (noop) Notice: /Stage[main]/Redis/Service[redis]/ensure: current_value stopped, should be running (noop) Info: /Stage[main]/Redis/Service[redis]: Unscheduling refresh on Service[redis] Notice: Class[Redis]: Would have triggered 'refresh' from 2 events Notice: Stage[main]: Would have triggered 'refresh' from 1 events Notice: Finished catalog run in 0.29 seconds [root@slave03 ~]# puppet apply -v -e 'include redis' Notice: Compiled catalog for slave03 in environment production in 0.49 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 '1607074622' Notice: /Stage[main]/Redis/Package[redis]/ensure: created Notice: /Stage[main]/Redis/Service[redis]/ensure: ensure changed 'stopped' to 'running' Info: /Stage[main]/Redis/Service[redis]: Unscheduling refresh on Service[redis] Notice: Finished catalog run in 3.66 seconds [root@slave03 ~]# rpm -q redis  redis-3.2.12-2.el7.x86_64 [root@slave03 ~]# 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      80                                 [::]:3306                                           [::]:*                   LISTEN     0      128                                [::]:22                                             [::]:*                   LISTEN     0      100                               [::1]:25                                             [::]:*                   [root@slave03 ~]#  

  提示:单机模型下调用模块中的类,需要使用-e选项来声明类;以上信息可以看到redis安装好了,并以默认配置启动起来,监听在127.0.0.1的6379端口;这里只是调用了init.pp中的代码;

  调用子类

[root@slave03 ~]# puppet apply -v -e 'include redis::master' Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults Notice: Compiled catalog for slave03 in environment production in 0.63 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 '1607074812' Info: FileBucket got a duplicate file {md5}d98629fded012cd2a25b9db0599a9251 Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Filebucketed /etc/redis.conf to puppet with sum d98629fded012cd2a25b9db0599a9251 Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: content changed '{md5}d98629fded012cd2a25b9db0599a9251' to '{md5}9bcaca33cf09d7cb0bb1beec2006a644' Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/mode: mode changed '0640' to '0644' Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis] Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis] Notice: /Stage[main]/Redis/Service[redis]: Triggered 'refresh' from 2 events Notice: Finished catalog run in 0.29 seconds [root@slave03 ~]# ss -tnl State      Recv-Q Send-Q                    Local Address:Port                                   Peer Address:Port               LISTEN     0      128                                   *:6379                                              *:*                   LISTEN     0      128                                   *:22                                                *:*                   LISTEN     0      100                           127.0.0.1:25                                                *:*                   LISTEN     0      80                                 [::]:3306                                           [::]:*                   LISTEN     0      128                                [::]:22                                             [::]:*                   LISTEN     0      100                               [::1]:25                                             [::]:*                   [root@slave03 ~]# cat /etc/redis.conf  bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile /var/log/redis/redis.log databases 16 requirepass admin save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/lib/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes [root@slave03 ~]#  

  提示:可以看到调用master子类,对应redis就监听在本机所有地址的6379端口上,并且在配置文件也变成了我们手动提供的配置文件,对应模版中的变量已经替换成变量默认值;

  redis-master.conf.erb模版文件内容

自动化运维工具之Puppet模块自动化运维工具之Puppet模块

[root@slave03 ~]# cat /etc/puppet/modules/redis/templates/redis-master.conf.erb  bind 0.0.0.0 protected-mode yes port <%= @masterport %> tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile /var/log/redis/redis.log databases 16 requirepass <%= @masterpass %> save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/lib/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes [root@slave03 ~]# 

View Code

  调用子类,并向子类中传递参数

  模版中需要传递的参数

[root@slave03 ~]# grep -Ei ^"slaveof|masterauth" /etc/puppet/modules/redis/templates/redis-slave.conf.erb slaveof <%= @masterip %> <%= @masterport %> masterauth <%= @masterpass %> [root@slave03 ~]#  

  声明slave子类,并应用对应的清单

[root@slave03 ~]# puppet apply -v -e 'class{"redis::slave": masterip  => "10.0.0.3"}' Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults Notice: Compiled catalog for slave03 in environment production in 0.66 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 '1607075455' Info: FileBucket got a duplicate file {md5}9bcaca33cf09d7cb0bb1beec2006a644 Info: /Stage[main]/Redis::Slave/File[/etc/redis.conf]: Filebucketed /etc/redis.conf to puppet with sum 9bcaca33cf09d7cb0bb1beec2006a644 Notice: /Stage[main]/Redis::Slave/File[/etc/redis.conf]/content: content changed '{md5}9bcaca33cf09d7cb0bb1beec2006a644' to '{md5}15f84c31c3f4582b526724da6ffd08d5' Info: /Stage[main]/Redis::Slave/File[/etc/redis.conf]: Scheduling refresh of Service[redis] Notice: /Stage[main]/Redis/Service[redis]: Triggered 'refresh' from 1 events Notice: Finished catalog run in 0.38 seconds [root@slave03 ~]# ss -tnl State      Recv-Q Send-Q                    Local Address:Port                                   Peer Address:Port               LISTEN     0      128                                   *:6379                                              *:*                   LISTEN     0      128                                   *:22                                                *:*                   LISTEN     0      100                           127.0.0.1:25                                                *:*                   LISTEN     0      80                                 [::]:3306                                           [::]:*                   LISTEN     0      128                                [::]:22                                             [::]:*                   LISTEN     0      100                               [::1]:25                                             [::]:*                   [root@slave03 ~]# grep -Ei ^"slaveof|masterauth" /etc/redis.conf slaveof 10.0.0.3 6379 masterauth admin [root@slave03 ~]#  

  提示:在slave.pp文件中masterport和masterpass这两个变量都有默认值,所以传递声明类可以只传递masterip这个变量的值即可;从上面的信息可以看到redis的配置文件中slaveof 的值就是我们传递的IP地址,对应端口和master密码都是使用的默认值;