運維學習筆記-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.www58058.com/22350

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

相關推薦

  • LVM邏輯卷管理器(Logical Volume Manager)

    邏輯卷管理器(Logical Volume Manager) 簡介      LVM的做法是將幾個物理的分區通過軟件組合成為一塊看起來是獨立的大磁盤(VG),然后將這塊大磁盤再分成可以使用的分區(LV),最終就能夠掛載使用了。內部通過PE來進行擴展或縮小。 PV(PhysicalVolume)物理卷 用fdisk命令調整系統標識…

    Linux干貨 2016-09-01
  • centos7或centos6中如何編譯安裝源碼程序包

    yum倉庫配置、程序的編譯安裝

    2017-12-02
  • 初涉Linux基本要點概括(2)

    linux上的文件查看與管理類命令 mkdir 作用: 創建目錄 語法: mkdir [OPTION]… DIRECTORY… 示例: mkdir -p /tmp/x/y/z             &nb…

    Linux干貨 2016-10-15
  • 馬哥教育網絡21期+第十三周練習博客

        馬哥教育網絡21期+第十三周練習博客 1、建立samba共享,共享目錄為/data,要求:(描述完整的過程) 1)共享名為shared,工作組為magedu; 在服務器上安裝samba ]# yum install samba 創建共享目錄/data 啟動samba的nmb和smb…

    Linux干貨 2016-10-31
  • linux基礎練習

    馬哥教育23期網絡班+第6周課堂練習 Linux 基礎練習 一、linux基礎練習題 1、復制/etc/rc.d/rc.sysinit 文件至/tmp 目錄,將/tmp/rc.sysinit 文件中的以至少一個空白字符開頭的行的行首加#; 2、復制/boot/grub/grub.conf 至/tmp目錄中 刪除/tmp/grub.conf 文件中的行首的空白…

    Linux干貨 2016-11-01
  • 學習宣言

    已經虛度了第一個關鍵的10年,不能再失去下一個10年,3年內年薪20w,5年內年薪30w。

    Linux干貨 2016-12-26
欧美性久久久久