gy13100892256
作者gy131008922562021-06-04 17:06
系统管理员, 电信

Puppet之Hiera初探

字数 9837阅读 1180评论 0赞 0

为什么使用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"}

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内置函数可以在任意的manifest文件中调用或者在puppet apply -e中命令调用。

  • Hiera命令在Hiera安装好后,就可以从shell中使用。
  1. 使用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.演示环境

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键值所对应的数组内容。这个键可以是其他名字,只要在数据源文件中保持名字一致就可以
}

c. 配置所有节点的默认配置(/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配置并启动服务

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

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

e. 配置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源。

f. 配置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

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广