运维学习笔记-Puppet之Hiera初探

为什么使用Hiera?


Puppet中的manifest同时包含静态的代码(判断/循环逻辑,依赖关系,类定义,资源类型定义等等)和动态的数据(类声明时的参数值和资源声明时的属性值)。说代码是静态的是因为如果在设计阶段考虑比较全面,代码写成之后是很少变化的。但是数据要根据具体情况赋予不同的值。如果manifest设计的不是很灵活,比如某些数据被固化(hardcode)在文件中时,manifest就很难适用于新的场景,重用性就变差了。此外,为了追加/更新数据经常修改manifest也增加了出错的几率。

Puppet的解决方案是将动态的数据从manifest中剥离出来,这样manifest中只需留下代码,不必经常改动。

一种方式是我们要尽量使用Forge上的模块,或者将我们的manifest按同样方式设计,也就是将manifest内的资源的所有属性都通过类参数的形式暴露给用户,这样用户就可以通过传递不同的参数值来自由控制资源的最终状态。

另一种方式就是使用Hiera,也就是将manifest要使用的数据存储在外部的文件中,根据实际情况赋值。在编译catalog时,manifest向Hiera动态查询所需值的具体内容,然后加载到catalog中。

Hiera是如何存储数据的?


Hiera将数据以键/值对的方式存储在外部文件中。查询时,将键传给Hiera,然后Hiera返回对应值。

存储键/值对的文件被称作数据源(data source)文件。数据源文件可以是yaml或json格式,也可以自定义格式。下面是一个yaml格式的数据源的例子。每一行都是一个键/值对,值可以是数字,字符串,布尔值,数组或者hash,也支持数组和hash的嵌套。

# 值是数字

process_count: 10

# 值是字符串

apache-service: apache2

# 值是布尔

root_allowed: no

# 值是数组

apache-packages:

    – apache2

    – apache2-common

    – apache2-utils

# 值是hash

sshd_settings:

    root_allowed: "no"

    password_allowed: "yes"

# hash的另外一种写法

sshd_settings: {root_allowed: "no", password_allowed: "yes"}

json格式的数据源和其他细节请看这里

Hiera是如何组织数据源文件的?


Hiera的一个核心理念是重用数据,具体体现为对数据源文件的层次化分类管理(Hierarchy

    层次1: 所有节点通用的数据定义在一个公共数据源文件中,且只需定义一次

    层次2: 对节点分类(主要是依据facts)。一类节点的通用数据定义在一个公共数据源文件中,且只需定义与上面一层不同的部分

    层次3: 对每一个节点进行配置,每个节点一个数据源文件,且只需定义与上面几层不同的数据

数据源的配置被定义在Hiera的主配置文件(hiera.conf)中。下面是一个配置文件的例子。更多hiera.conf细节请看这里

:backends:                        #支持的数据源文件格式,默认是yaml和json

  – yaml                            #查找yaml格式数据源文件

  – json                             #查找json格式数据源文件

:yaml:                              #yaml格式数据源文件的根目录

  :datadir: "/etc/puppet/environments/%{::environment}/hieradata"            #%{::environment}是指facts中的environment变量。这行定义是说yaml格式的数据源文件的根目录是"/etc/puppet/environments/%{::environment}/hieradata"    

:json:                                #json格式数据源文件的根目录

  :datadir: "/etc/puppet/environments/%{::environment}/hieradata"            

:hierarchy:                        #分类和层次关系(hierarchy)

  – "nodes/%{::fqdn}"         #%{::fqdn}是指facts中的fqdn变量。按fqdn分类的数据源文件存在$datadir/nodes目录下,文件以agent节点的fqdn命名

  – "virtual/%{::virtual}"       #%{::virtual}是指facts中的virtual变量。按virtual值分类的数据源文件存在$datadir/virtual目录下,文件以virtual值命名

  – "common"                    #所有节点的默认配置都存在common.yaml或者common.json中

注意:如果修改了hiera.conf的内容,Puppet master进程必须重启才能生效

如果我的production环境中,server1和server2都是运行在xen上,而server3和server4都是在vmware上,那么根据上面的配置文件,我的数据源文件目录结构就很可能是这个样子

/etc/puppet/environments/production/hieradata

├── common.yaml                    #所有节点的通用配置

├── nodes                                #以fqdn分类的每个节点的配置

│   ├── server1.yaml                #server1的配置

│   ├── server2.yaml                #server2的配置

│   ├── server3.yaml                #server3的配置

│   └── server4.yaml                #server4的配置

└── virtual                                #以virtual分类的通用配置

    ├── xen.yaml                       #所有xen虚拟机的通用配置

    └── vmware.yaml                #所有vmware虚拟机的通用配置

对于server1 (xen虚拟机)来说,它的最终配置会是server1.yaml, xen.yaml 和common.yaml 中配置的组合。

如何从Hiera查询数据?


Hiera支持几种查询方式

1. 自动参数查询(automatic parameter lookup)

这种方式主要用于查询类的参数。

当Hiera配置好后,在manifest中声明类但不给指定参数赋值,比如使用include-like方式(无类参数),或者使用resource-like方式但不显性的给参数赋值,这两种情况下,Puppet都会自动使用<类名>::<参数名>作为键通过Hiera查询相应的参数值。详细信息请看这里

注意: * 不要在template中使用自动参数查询。

            * 如果想禁止这个功能,在master的puppet.conf设置data_binding_terminus = none

2. 使用Hiera内置函数或Hiera命令查询

数据类型 Hiera内置函数 Hiera命令
任何数据类型 hiera(<键>) hiera <键>
数组 hiera_array(<键>) hiera -a <键>
Hash hiera_hash(<键>) hiera -h <键>

注意:    * Hiera内置函数可以在任意的manifest文件中调用或者在puppet apply -e中命令调用。

                * Hiera命令在Hiera安装好后,就可以从shell中使用。

3. 使用Hiera内置函数hiera_include

hiera_include()专门用来在site.pp中查询哪些类分配给了指定节点,等同于在节点定义中使用include-like/resource-like来声明类,可以作为ENC的一个替代方案。

Hiera查询是如何工作的?


查询时,Hiera会按:hierarchy:下面定义的顺序遍历datadir子目录下的数据源文件,寻找匹配的键。

:hierarchy:

  – "nodes/%{::fqdn}"

  – "virtual/%{::virtual}"

  – "common"

如果:hierarchy:的定义是上面这样的,查询的顺序就是datadir下的nodes/%{::fqdn}子目录,然后是virtual/%{::virtual}子目录,最后是common.yaml文件。

如果你是使用以下的查询方式,那么在找到第一个匹配的键之后Hiera就返回了,不在继续查找

        * 自动参数查询(automatic parameter lookup)

        * Hiera内置的hiera函数

        * hiera命令(没有-a或-h)

如果你是使用以下的查询方式,那么Hiera会认为你在查找一个数组,它会遍历所有的数据源文件,然后将所匹配的所有数组值合并到一个数组中返回

        * Hiera内置的hiera_array函数

        * Hiera内置的hiera_include函数

        * hiera -a 命令

如果你是使用以下的查询方式,那么Hiera会认为你在查找一个hash,它会遍历所有的数据源文件,然后将所匹配的所有内容值合并到一个hash中返回。

        * Hiera内置的hiera_hash函数

        * hiera -h 命令

注意:如果这个hash又嵌套了其他的hash或者数组,且某个键在不同的数据源文件中被赋予了不同的hash或者数组,默认情况下,Hiera只会保留第一个匹配到的嵌套hash或者数组。如果你希望在这种情况下执行合并操作,请看这里

Hiera使用示例


我们通过一个例子来展示如何使用Hiera.

1. 演示环境

节点名 OS系统 Puppet组件
master-host CentOs7 Puppet 3.8开源版master,
agent-centos CentOs6 Puppet 3.8开源版agent和facter
agent-ubuntu Ubuntu14 Puppet 3.8开源版agent和facter

2. 实验目标

    * 所有agent节点的标准配置是安装ntp,使用节点系统自带的ntp设置,并启动ntp服务

    * 在且只在所有RedHat家族Linux上安装nginx,使用默认设置,并启动nginx服务(当前RedHat家族Linux上没有nginx

    * 在agent-centos节点上停止ntp服务

    * 在agent-ubuntu节点上使用外部ntp源0.au.pool.ntp.org和1.au.pool.ntp.org(当前agent-ubuntu节点上没有ntp

3. 安装所需模块

在这个演示中,会用到ntp和nginx模块(负责安装,配置并管理相关服务)。简单起见,我们从Forge上下载并安装相关模块到master-host上。当然,你也可以使用自己写的模块。

puppet module install puppetlabs-ntp         #安装ntp模块

puppet module install jfryman-nginx           #安装nginx模块

后面我们会用到puppetlabs-ntp模块中ntp类的两个参数,$::ntp::service_ensure和$::ntp::servers。如果你想了解其他参数的用途,可以查看模块的init.pp(/etc/puppet/modules/ntp/manifests/init.pp

4. 安装Hiera

一般在安装puppetserver的过程中,Hiera会被自动安装。如果你的master上没有Hiera软件包,请看这里了解安装过程。    

5. 配置

    a. Hiera主配置文件(/etc/puppet/hiera.yaml)

:backends:                                        

  – yaml                                             #告诉Hiera只查找yaml格式的数据源文件

:yaml:                        

  :datadir: "/etc/puppet/hieradata"    #yaml格式的数据源文件的根目录是/etc/puppet/hieradata

:hierarchy:                                       #定义数据源的分类和层次。

  – "nodes/%{::fqdn}"                        #按fqdn分类命名数据源文件并保存在/etc/puppet/hieradata/nodes目录下,比如agent-centos节点的文件名就是agent-centos.yaml

  – "osfamily/%{::osfamily}"                #在/etc/puppet/hieradata/osfamily目录下含有为以osfamily分类的数据源文件,例如RedHat家族Linux的数据源文件就是RedHat.yaml

  – common                                       #所有节点通用的默认配置

    b. 配置site.pp

node "agent-centos","agent-ubuntu" {       #节点定义

    hiera_include('classes')             #调用hiera_include函数向Hiera查询classes键值所对应的数组内容。这个键可以是其他名字,只要在数据源文件中保持名字一致就可以

}

    b. 配置所有节点的默认配置(/etc/puppet/hieradata/common.yaml)

classes:                                         #所有节点默认都调用ntp类。

    – ntp                            

ntp::service_ensure: running         #ntp::service_ensure是puppetlabs-ntp模块中,ntp类的service_ensure参数,是指服务的运行状态(也就是service资源中的ensure属性)这里给他赋值为 running

    上面定义是说每个节点默认都要安装ntp数据包,使用默认ntp配置并启动服务

    c. 配置agent-centos节点(/etc/puppet/hieradata/nodes/agent-centos.yaml)

ntp::service_ensure: stopped            #停止ntp服务

    d. 配置agent-ubuntu节点(/etc/puppet/hieradata/nodes/agent-ubuntu.yaml)

ntp::servers:                                  #ntp::service_ensure是puppetlabs-ntp模块中ntp类的参数,用来指定ntp源。

    – 0.au.pool.ntp.org                    #第一个ntp源是0.au.pool.ntp.org

    – 1.au.pool.ntp.org                    #第二个ntp源是1.au.pool.ntp.org

    做了以上配置后,agent-ubuntu节点会使用0.au.pool.ntp.org和1.au.pool.ntp.org作为ntp源。

    e. 配置RedHat家族Linux(/etc/puppet/hieradata/osfamily/RedHat.yaml)  

classes:                                     #配置所有RedHat家族Linux都调用nginx类

    – nginx                             

经过以上的配置,agent-centos的节点定义将会是agent-centos.yaml,RedHat.yaml和common.yaml整合后的内容,等同于以下设置。

node "agent-centos" {                 #agent-centos节点定义

        class { "ntp":                       #声明ntp类,来自common.yaml

            service_ensure => "stopped",     #停止ntp服务。高优先级的agent-centos.yaml覆盖了低优先级的common.yaml中的设置

        }

        include nginx                        #声明nginx类,来自于RedHat.yaml

}

而agent-ubuntu的节点定义是agent-ubuntu.yaml和common.yaml的内容整合后的结果,相当于下面的配置

node "agent-ubuntu" {                        #agent-ubuntu节点定义

       class { "ntp":                                #声明ntp类,来自common.yaml

                service_ensure => "running", #运行ntp服务,来自common.yaml

                servers=> ["0.au.pool.ntp.org", "1.au.pool.ntp.org"],#设置ntp源,来自于agent-ubuntu.yaml

        }

}

6. 检查配置

在应用前,可以使用hiera命令或者puppet apply命令来检查配置结果是否正确。

    a. 用hiera命令

    如果想检查agent-centos6(osfamily的值是RedHat)和agent-ubuntu(osfamily的值是Debian)上所分配的classes是哪些,可以使用下面的命令

[root@master-host~]hiera -a  'classes'  '::osfamily=RedHat' '::fqdn=agent-centos'  -c /etc/puppet/hiera.yaml

["ntp","nginx"]                             

[root@master-host~]hiera -a  'classes'  '::osfamily=Debian' '::fqdn=agent-ubuntu'  -c /etc/puppet/hiera.yaml

["ntp"]

    在上面命令中,-a说明被查询的classes是一个数组,如果它在不同数据源文件中都有定义,要求Hiera整合匹配的结果。如果不写-a,Hiera在找到第一个匹配classes的内容时就会立即返回。

    此外,'::osfamily=RedHat'和 '::fqdn=agent-centos6'是来告诉Hiera使用传入的facts值,如果没有指定,Hiera会使用当前系统的facts值。

    b. 用puppet apply命令 

    上面的检查也可以用puppet apply来执行

[root@master-host~]FACTER_fqdn=agent-centos FACTER_osfamily=RedHat puppet apply -e "notice(hiera_array('classes'))"

Notice: Scope(Class[main]): nginx ntp

Notice: Compiled catalog for master-centos6 in environment production in 0.05 seconds

Info: Applying configuration version '1467801050'

Notice: Finished catalog run in 0.11 seconds

[root@master-host~]FACTER_fqdn=agent-ubuntu FACTER_osfamily=Debian puppet apply  -e "notice(hiera_array('classes'))"

Notice: Scope(Class[main]): ntp

Notice: Compiled catalog for master-centos6 in environment production in 0.05 seconds

Info: Applying configuration version '1467801027'

Notice: Finished catalog run in 0.14 seconds

    上面命令中使用的FACTER_fqdn和FACTER_osfamily都是告诉puppet使用指定的fqdn和osfamily值。此外,hiera_array用来说明classes是一个数组,Hiera会将所有匹配结果整合后再返回。

7. 运行并检查结果

在agent节点上启动agent进程

puppet agent -v –no-daemonize

在agent将catalog应用完成后,检查agent-centos节点

[root@agent-centos~]# service ntpd status

ntpd is stopped                                     #ntp服务被停止了

[root@agent-centos~]# rpm -qa | grep nginx

nginx-1.10.1-1.el6.ngx.i386                  #nginx安装包已安装

[root@agent-centos~]service nginx status

nginx (pid  4531) is running…                #nginx服务已运行

检查agent-ubuntu节点

root@agent-ubuntu:~# dpkg -l ntp                                #ntp包已安装

||/ Name           Version      Architecture Description

+++-==============-============-============-=================================

ii  ntp            1:4.2.6.p5+d i386         Network Time Protocol daemon and

root@agent-ubuntu:~# service ntp status

 * NTP server is running                                                    #ntp服务已运行

root@agent-ubuntu:~# grep server /etc/ntp.conf        #ntp.conf中的ntp源与预期相符

server 0.au.pool.ntp.org iburst                 

server 1.au.pool.ntp.org iburst

原创文章,作者:MVP,如若转载,请注明出处:http://www.178linux.com/22350

(0)
MVPMVP
上一篇 2016-07-07
下一篇 2016-07-07

相关推荐

  • 抓包获取QQ好友IP地址

    作者:网海过客 原文连接:https://www.chinasa.net/archives/326.html 原理:通过抓包软件,抓取QQ进程,向QQ好向发送UDP数据包,获取QQ好友IP地址 抓包软件:科来网络分析系统 步骤: 1、打开抓包软件,选择网卡,本地进程分析。 2、向QQ好友发起语音通话 3、在抓包软件里,找到QQ进程,数据包,过滤UDP协议,在…

    Linux干货 2017-06-30
  • 软件包管理–rpm、yum

    rpm软件包管理,rpm命令的使用。yum命令使用,yum源的搭建,网络yum源的搭建方法。编译安装http

    Linux干货 2017-12-03
  • Linux系统操作练习-2

    1、显示当前系统上root、fedora或user1用户的默认shell: 2、找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello(): 3、使用echo命令输出一个绝对路径,使用grep取出基名;扩展:取出路径名: 扩展: 4、找出ifconfig命令结果中的1-255之间的数字: 5、挑战题:写一个…

    2017-11-25
  • Linux下搭建路由器

    客户端1:CentOS6.9 客户端2:CentOS7.3 路由器:router1(CentOS7.3)、router2(CentOS7.3) r router3(CentOS7.3) 1 准备工作 为了避免干扰,最好建立独立的网络。 打开VMvare的虚拟网络编辑器,点击添加网络按钮,添加VMnet11并且将左下角使用“本地DHCP服务将IP地址分配给虚拟…

    Linux干货 2017-08-20
  • 8.1_Linux习题和作业

    7.28 作业 1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中 1 # cat /etc/issue | tr 'a-z' 'A-Z'whoi > /tmp/issue.out 2、将当前系…

    Linux干货 2016-08-04
  • FHS文件系统各目录及Linux文件类型和颜色标识整理

    一.FHS (Filesystem Hierarchy Standard文件系统层级标准)   使用文件系统层级标准可以使软件和用户可以预测已安装文件和文件夹位置 文件系统各目录:   /boot     系统引导启动时要加载的静态文件,内核和ramdisk及grub等    (系统启动时…

    Linux干货 2016-10-17