puppet 配置 3.4 文件管理与自定义模块

作用

利用 puppet 对文件, 配置文件等进行管理
常见管理办法

1.  新增文件并定义文件中内容
2.  修改已经存在的文件中的配置
3.  通过模板管理方式进行配置文件定义

模块

这里介绍 puppet 自带的 file 模块及第三方模块 stdlib

stdlib 模块下载地址

使用方法

下载 stdlib.tar.gz 软件包并解压至 /etc/puppet/modules/stdlib

文件结构

[root@terry-test-uq2pu ~]# ls /etc/puppet/modules/stdlib/
CHANGELOG.md     Gemfile  LICENSE    metadata.json  pkg       README_DEVELOPER.markdown  README_SPECS.markdown     spec
CONTRIBUTING.md  lib      manifests  Modulefile     Rakefile  README.markdown            RELEASE_PROCESS.markdown  tests

参考 README.markdown 查询使用方法
stdlib 包含了很多资源, 这里我们只介绍 file_line 的使用, 其他资源请自行参考帮助文件

puppet 调用顺序

/etc/puppet/puppet.conf
 |-> /etc/puppet/manifests/main-site.pp
        |-> /etc/puppet/manifests/terry/terry-parameter.pp
        |-> /etc/puppet/manifests/terry/terry-site.pp
                |-> /etc/puppet/manifests/terry/terry-files.pp

说明:

1. /etc/puppet/puppet.conf 中通过下面配置执行下一个文件

    manifest = /etc/puppet/manifests/main-site.pp

2.  /etc/puppet/manifests/main-site.pp 通过下面配置执行下一个文件

    import 'terry/terry-parameter.pp'
    import 'terry-site.pp'

3.   /etc/puppet/manifests/terry/terry-parameter.pp  (用于定了了全局变量)  下一章说明
     /etc/puppet/manifests/terry/terry-site.pp 定义了主机需要执行那些自定义行为, 使用那些资源, 当前以调用了 sysctl 模块与 hosts 模块
        import  'terry/terry-sysctl.pp'
        import 'terry/terry-files.pp'

4.   /etc/puppet/manifests/terry/terry-files.pp 定义了文件管理方法(增删改)

文件管理说明

文件与目录管理

1.  假如需要创建一个文件, 这个文件的父级目录必须先存在, 否则文件创建失败
2.  创建文件目录时候, 必须分配合法的 owner 与 group, 否则创建失败

创建目录

假设我们需要同时创建三个目录

file { [ '/tmp/test', '/tmp/test/new', '/tmp/test/old' ] :
        owner => 'root', group => 'daemon',    <- owner, group 定义
        mode => 0755,                          <- 权限
        ensure => directory,                   <- 定义为目录
}

创建文件

file { '/tmp/test/new/example.ini':
        owner => 'root', group => 'apps',      <- 用户组定义
        mode => 0644,                          <- 权限
        ensure => file,                        <- 说明这是一个文件
        content => '[this is an example file]  <- 文件内容
# this is comment
date = 20170126
time = 12:00
tel = 123456789',
        require => File['/tmp/test/new'],     <- 确保父级目录先存在
}

参考创建后的文件内容及属性

[root@terryzeng-gz-qa-dns-d4yzu ~]# ls -l  /tmp/test/new/example.ini
-rw-r--r-- 1 root apps 88 Jan 26 11:37 /tmp/test/new/example.ini
[root@terryzeng-gz-qa-dns-d4yzu ~]# cat /tmp/test/new/example.ini
[this is an example file]
# this is comment
date = 20170126
time = 12:00
tel = 123456789

说明:

1.  假如父级目录也是由 puppet 管理,  那么必须利用 require 定义父级目录与文件的先后顺序
2.  ensure 定义了文件属性, 如 directory(目录),  file(文件), link(链接, 需要加 target 参数),  absent(删除)
3.  content 用于定义文件内容, 并覆盖原来文件中所有内容,  文件内容与 content 后定义的一样
4.  owner, group 中的用户组必须已经存在在系统中

修改内容

利用stdlib 中 file_line 资源对文件内容进行修改, 不推荐在 puppet 中使用 sed 工具
参考需要修改的 example 文件

cat /tmp/test/old/example
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
%wheel        ALL=(ALL)       NOPASSWD: ALL
root    ALL=(ALL)       ALL

目标:

1.  我们现在计划把Defaults:  requiretty 替换成下面内容 Defaults: apps,root  !requiretty
2.  添加行, 内容如下 %apps  ALL=/sbin/shutdown -r now,  /usr/bin/reboot
3.  删除 %wheel        ALL=(ALL)       NOPASSWD: ALL 行内容

参考 puppet 语法

file_line { 'commente requiretty':
        path => '/tmp/test/old/example',
        match => '^Defaults.*requiretty$',
        line => 'Defaults: apps,root  !requiretty',
}

file_line { 'add apps reboot shutdown permission':
        path => '/tmp/test/old/example',
        line => '%apps ALL=/sbin/shutdown -r now, /usr/bin/reboot',
}


file_line { 'remove wheel permission':
        path => '/tmp/test/old/example',
        line => '%wheel        ALL=(ALL)       NOPASSWD: ALL',
        ensure => absent,
}

说明:
1. 需要使用 path 定义需要进行修改的文件绝对路径
2. 可以通过 match 进行匹配, 参考 ruby 正则语法 http://gnosis.cx/publish/programming/regular_expressions.html
3. line 表示需要修正的内容

验证结果

参考修改后的结果

Defaults: apps,root  !requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root    ALL=(ALL)       ALL
%apps ALL=/sbin/shutdown -r now, /usr/bin/reboot

文件复制

1.   利用 puppet:// 语法, 直接从 puppet master 中把文件复制到 puppet client 端指定位置
2.   利用模板  template 功能,  合理对文件进行复制与配置
3.   注意, 当调用到文件复制与模板功能时候,  建议为该该行为创建自定义模块

自定义模块

目标
1. 对 puppet client 进行 crond 任务管理,
2. 通过文件复制功能与模板方法, 对 crond 进行配置学习

对于自定义模块注意下面几点

1.  在调用自定义模块时候, 需要用到参数 Class
2.  创建自定义模块时候,  自定义模块主目录中, 必须具有 init.pp 文件, 并且该文件在调用模块时首先被调用
3.  建议在创建自定义模块时候,  按照功能区分,  把不同的功能分别写到不同的配置中, 方便维护
4.  自定义模块中,  manifests 目录用于定义模块功能 
5.  自定义模块中,  files 目录用于文件复制
6.  自定义模块中,  templates 目录用于调用文件模板

参考下面自定义模板目录与文件结构

/etc/puppet/modules/crond
├── files                 <- 文件复制, 复制过程中不会对文件进行修改
│   ├── sysstat
│   └── zabbix
├── manifests             <- 模块功能定义
│   ├── config.pp        <- 这里用于进行文件配置
│   ├── init.pp          <- 必须存在, 初始化调用
│   ├── package.pp       <- 这里用于定义软件包定义
│   └── service.pp       <- 这里用于服务管理
└── templates            <- 模板调用
    └── puppet

自定义模块配置

参考下面文件

/etc/puppet/modules/crond/manifests/init.pp

class crond (
        $package_name = 'crontabs',
        $package_ensure = 'present',
        $time = fqdn_rand(59),
){
        Class['crond'] -> Class['crond::package'] -> Class['crond::config'] -> Class['crond::service']
        include crond, crond::package, crond::config, crond::service
}

说明:

1.  每个模板中, 都必须包含 init.pp 文件
2.  class crond 用于表示当前文件是属于那个模块
3.  $xxxx 用于进行变量定义,  变量可以用于传递
4.  fqdn_fand 是 puppet 内建函数,  那么当前以主机名作为随机数种子,  获得不大于 59 的随机值,  由于主机名是唯一不变的,  因此每次获得的值都一样
5.  利用  -> 符号定义了在当前模板中的文件的执行顺序 (假如具有安装, 配置的依赖关系),  即
6.  即先 package 安装软件,  然后,  config 进行 cron 配置,  最后 service,  管理 crond 服务

/etc/puppet/modules/crond/manifests/package.pp

class crond::package (
   $package_name = $crond::package_name,
   $package_ensure = $crond::package_ensure,
) inherits crond  {

   package { 'cronie':
      name => $package_name,
      ensure => $package_ensure,
   }
}

说明:

1.  class crond::package 用于表示当前文件是属于那个模块中的配置
2.  上面参数采用了参数传递方法, 即,  package_name,  package_ensure 参数赋值都来自于 init.pp 文件
3.  package 函数用于进行软件包管理

/etc/puppet/modules/crond/manifests/config.pp

class crond::config (
        $time =  $crond::time,
) inherits crond {

        file { '/etc/cron.d/puppet':
                owner => root, group => root,
                mode  => '0444',
                content => template("crond/puppet.erb"),
                notify => Service['crond'],
        }

        file { '/etc/cron.d/sysstat':
                owner => root, group => root,
                mode => '0444',
                source => "puppet:///modules/crond/sysstat",
        }

        file { '/etc/cron.d/zabbix':
                owner => root, group => root,
                mode => '0444',
                source => "puppet:///modules/crond/zabbix",
        }

}

说明:

1.  class crond::config  用于表示当前文件是属于那个模块中的配置
2.  $time =  $crond::time 表示指定了参数传递,  并取 init.pp 中 time 的参数赋值
3.  file 函数中,  content  => template 表示当前文件内容以模板为准
4.  file 函数中,  source => puppet://  表示当前文件直接从 puppet master 中进行复制
5.  在执行文件传输过程 (puppet://)  并没有 http 协议高效,  因此不建议进行大文件与大量文件利用 puppet:// 协议进行传输
6.  notify => Service['crond'] 表示, 当这个配置发生改变后,  自动重启 crond 服务(参考后面 crond 服务的配置) 

/etc/puppet/modules/crond/manifests/service.pp

class crond::service {
  service { "crond":
    enable => true,
    ensure   => 'running',
    start    => '/etc/init.d/crond start',
    restart  => '/etc/init.d/crond  restart',
    stop     => '/etc/init.d/crond  stop',
    require  => Package['cronie'],
  }
}

说明:

1.  class crond::service  用于表示当前文件是属于那个模块中的配置
2.  service 是 puppet 的内建函数,  用于进行服务管理
3.  rhel6, 通过 init.d 进行服务管理,   rhel7 通过 systemctl 进行管理,  自行修改 start, restart, stop 方法即可
4.  enable => true 意味着开机后服务自动启动
5.  ensure => running, 意味着执行 puppet 时候确保 crond 服务可以马上启动

template

template 用于进行配置定义
定义过程中,  可以利用参数,  进行配置

参考模板配置方法

/etc/puppet/modules/crond/templates/puppet.erb

*/<%= time %> * * * *  root  puppet agent -t

这里 <%= time %> 代表了直接套用了 time 的变量值

自定义模块调用

参考调用方法

/etc/puppet/puppet.conf
 |-> /etc/puppet/manifests/main-site.pp
        |-> /etc/puppet/manifests/terry/terry-parameter.pp
        |-> /etc/puppet/manifests/terry/terry-site.pp
                |-> /etc/puppet/manifests/terry/terry-files.pp
                |-> /etc/puppet/manifests/terry/terry-crond.pp   <- 这里进行自定义模块 crond 调用

调用自定义模板

/etc/puppet/manifests/terry/terry-crond.pp

class { 'crond': }

假如不进行参数修改或者功能修改, 直接通过上述方法则可以进行模板调用, 参考下面调用顺序

/etc/puppet/manifests/terry/terry-crond.pp
    |->  /etc/puppet/modules/crond/manifests/init.pp
            |->   /etc/puppet/modules/crond/manifests/package.pp
            |-> /etc/puppet/modules/crond/manifests/config.pp
            |-> /etc/puppet/modules/crond/manifests/service.pp
上一篇:“6·30”临近 多晶硅片、电池、组件价格速涨


下一篇:linux/unix下svn自动更新post-commit hook failed (exit code 255)