Puppet —自動化部署工具詳解

Puppet —自動化部署工具詳解

一個集羣的自動化部署過程可以分爲三個階段:供應階段(操作系統部署階段)、初始化配置階段、命令和管控階段。

操作系統部署階段常用的工具有:pxe , cobbler 等

初始化配置階段工具 :ansible(agentless) , puppet(master/agent) (ruby), saltstack (python) 等

命令和管控階段工具 :ansible(playbook) , fabric(fab) , func 等

Puppet 是一款應用非常廣泛的高性能環境自動化部署工具,本文以 puppet-3.8.7-1.el7.noarch 版本爲例來了解下這款程序的工作機制和應用方法。

與 Ansible 程序利用 ssh 遠程協議與從節點主機通信不同的是,Puppet 中的 Master 和 Agent 間採用 https 協議通信,Puppet 的執行效率更高。

這裏寫圖片描述

puppet 的兩種工作模型

  1. Standalone (單機)模型:手動應用清單

  2. Master/Agent (主從)模型:由agent週期性地向Master請求清單並自動應用於本地

puppet 程序介紹

Master端主機需要安裝的程序包:facter,puppet,puppet-server

Agent端主機需要安裝的程序包:facter,puppet

  1. 程序配置文件路徑 :/etc/puppet
  2. puppet主程序路徑 :/usr/bin/puppet

puppet 程序的工作架構分級

查看puppet的程序目錄,其中的每個文件或目錄都有其重要功用

ls /etc/puppet
auth.conf  environments  fileserver.conf  manifests  modules  puppet.conf

配置類文件

  1. puppet.conf :puppet程序的通用主配置文件,其中定義了 “[main]” , “[agent]” 兩個配置段,定義了部分 puppet 程序的初始化默認配置,可使用 “puppet config print” 命令查看 puppet 程序的所有配置項的默認值

  2. auth.conf :認證信息文件,其中定義了主節點和各個從節點主機的各類權限,可在此處設置主從間通信的訪問權限

  3. fileserver.conf :文件系統配置文件,可在此文件中定義新的掛載點,供主從間通信使用

Master/Agent 模型

  1. environments :環境,指將要部署的環境

    • 在實際應用中,一般有 development , testing , production 等幾種常見部署環境
  2. manifests :主機清單,此目錄下應存在一個 site.pp 文件,該文件定義了集羣中的每臺主機的主機名和每臺主機要執行的動作(引用的模塊名、類名),每臺主機連接

Standalone 模型

  1. manifests :主機清單存放目錄,用於本地編輯 site.pp 文件,將所有附屬的Agent的主機信息都放在主機清單中

  2. modules :模塊存放目錄,可以在此處開發modules,開發完成後放置於environments的對應環境下

Puppet中的 modules 開發

1.resource (資源)

  • 資源的格式示例:
type{'title':
    attribute_1 =>  'value_1',
    attribute_2 =>  'value_2',
    ...
}
  • 資源引用:Type[‘title’]

注意:資源中的 “type” 必須要小寫,在被引用時,資源中的 “Type” 首字母大寫,其餘字母小寫;title是一個字符串,在同一類型中必須惟一。

2.資源類型:

常用的資源有8個 :group, user, package, service, file , exec, cron, notify,每個資源中都含有不同的屬性

資源有三個的特殊屬性
- Namevar, 可簡稱爲name;name可省略,此時將由title表示
- ensure:資源的目標狀態;
- Provider:指明資源的管理接口

資源間關係的元參數metaparameters:

  • 前置/依賴關係:before/require
A before B: B依賴於A,定義在A資源中;
    {
        ...
        before  => Type['B'],
        ...
    }

B require A: B依賴於A,定義在B資源中;
    {
        ...
        require => Type['A'],
        ...
    }
  • 通知/訂閱關係:notify/subscribe
notify 

A notify B:B依賴於A,且A發生改變後會通知B;
    {
        ...
        notify => Type['B'],
            ...
    }

subscribe

B subscribe A:B依賴於A,且B監控A資源的變化產生的事件;
    {
        ...
        subscribe => Type['A'],
        ...
    }
  • 關係元參數也可以用符號表示 :->, ~>
Package['httpd'] -> File['httpd.conf'] -> Service['httpd']
  1. user:Manage users.
屬性:
    name:用戶名
    uid: UID
    gid:基本組ID
    groups:附加組,不能包含基本組
    comment:註釋
    expiry:過期時間 
    home:家目錄
    shell:默認shell類型
    system:是否爲系統用戶 
    ensure:present/absent
    password:加密後的密碼串
  1. group:Manage groups.
屬性:
    name:組名
    gid:GID
    system:是否爲系統組,true OR false
    ensure:目標狀態,present/absent
    members:成員用戶
  1. package:Manage packages.
屬性:
    ensure:installed, present, latest, absent
    name:包名
    source:程序包來源,僅對不會自動下載相關程序包的provider有用,例如rpm或dpkg
  1. service:Manage running services.
屬性:
    ensure:Whether a service should be running. Valid values are `stopped` (also called `false`), `running` (also called `true`).
    enable:Whether a service should be enabled to start at boot. Valid values are `true`, `false`, `manual`.
    name:
    path:The search path for finding init scripts.  Multiple values should be separated by colons or provided as an array. 腳本的搜索路徑,默認爲/etc/init.d/
    hasrestart:
    hasstatus:
    start:手動定義啓動命令
    stop:
    status:
    restart:Specify a *restart* command manually.  If left unspecified, the service will be stopped and then started. 通常用於定義reload操作
  1. file:Manages files, including their content, ownership, and permissions.
屬性:                 
    ensure:Whether the file should exist, and if so what kind of file it should be. Possible values are `present`, `absent`, `file`, `directory`, and `link`.
        file:類型爲普通文件,其內容由content屬性生成或複製由source屬性指向的文件路徑來創建;
        link:類型爲符號鏈接文件,必須由target屬性指明其鏈接的目標文件;
        directory:類型爲目錄,可通過source指向的路徑複製生成,recurse屬性指明是否遞歸複製

    path:文件路徑;
    source:源文件;
    content:文件內容;
    target:符號鏈接的目標文件; 
    owner:屬主
    group:屬組
    mode:權限;
    atime/ctime/mtime:時間戳

可使用puppet URL :puppet:///modules/MODULE_NAME/FILE_NAME

  1. exec:Executes external commands. Any command in an exec resource must be able to run multiple times without causing harm — that is, it must be idempotent.
屬性:         
    command (namevar):要運行的命令
    cwd:The directory from which to run the command
    creates:文件路徑,僅此路徑表示的文件不存在時,command方纔執行
    user/group:運行命令的用戶身份
    path:The search path used for command execution. Commands must be fully qualified if no path is specified
    onlyif:此屬性指定一個命令,此命令正常(退出碼爲0)運行時,當前command纔會運行
    unless:此屬性指定一個命令,此命令非正常(退出碼爲非0)運行時,當前command纔會運行
    refresh:重新執行當前command的替代命令
    refreshonly:僅接收到訂閱的資源的通知時方纔運行
  1. cron:Installs and manages cron jobs. Every cron resource created by Puppet requires a command and at least one periodic attribute (hour, minute, month, monthday, weekday, or special).
屬性:         
    command:要執行的任務
    ensure:present/absent
    hourminute:
    monthday:
    month:
    weekday:
    user:以哪個用戶的身份運行命令
    target:添加爲哪個用戶的任務
    name:cron job的名稱
  1. notify:Sends an arbitrary message to the agent run-time log.
屬性:
    message:信息內容
    name:信息名稱

3.puppet 的 variable (變量)

FQN: $::scope1::scope2::variable

$variable_name=value

數據類型:字符串、數值、布爾型、數組、hash、undef

  • 字符型:引號可有可無;但單引號爲強引用,雙引號爲弱引用;
  • 數值型:默認均識別爲字符串,僅在數值上下文才以數值對待;
  • 數組:[]中以逗號分隔元素列表;
  • 布爾型值:true, false;
  • hash:{}中以逗號分隔k/v數據列表; 鍵爲字符型,值爲任意puppet支持的類型;{ ‘mon’ => ‘Monday’, ‘tue’ => ‘Tuesday’, };
  • undef:未定義 ;

  • 正則表達式:

(?<ENABLED OPTION>:<PATTERN>)
(?-<DISABLED OPTION>:<PATTERN>)

    OPTIONS:
        i:忽略字符大小寫;
        m:把.當換行符;
        x:忽略<PATTERN>中的空白字符

    示例:(?i-mx:PATTERN

4.變量類型

facts:
    由facter提供;top scope;
    內建變量:
        master端變量 
        agent端變量 
        parser變量
    用戶自定義變量:

變量有作用域,稱爲Scope;
    top scope:     如 $::var_name
    node scope
    class scope

5.puppet流程控制語句

if , case , selector , unless

  1. if 語句
if  CONDITION {
        ...
    } else {
        ...
    }

    CONDITION的給定方式:
        (1) 變量
        (2) 比較表達式 
        (3) 有返回值的函數
  • 示例:
vim /etc/puppet/modules/webserver.pp
#內容如下:
if $osfamily =~ /(?i-mx:debian)/ {
    $webserver = 'apache2'
} else {
    $webserver = 'httpd'
}

package{"$webserver":
    ensure  => installed,
    before  => [ File['httpd.conf'], Service['httpd'] ],
}

file{'httpd.conf':
    path    => '/etc/httpd/conf/httpd.conf',
    source  => '/root/manifests/httpd.conf',
    ensure  => file,
}

service{'httpd':
    ensure  => running,
    enable  => true,
    restart => 'systemctl restart httpd.service',
    subscribe => File['httpd.conf'],
}
  1. case 語句

    • 語法及格式
case CONTROL_EXPRESSION {
case1: { ... }
    case2: { ... }
    case3: { ... }
    ...
    default: { ... }
}

    CONTROL_EXPRESSION:
        (1) 變量
        (2) 表達式 
        (3) 有返回值的函數

    各case的給定方式:
        (1) 直接字串;
        (2) 變量 
        (3) 有返回值的函數
        (4) 正則表達式模式;
        (5) default
  • case 語句示例:
case $osfamily {
    "RedHat": { $webserver='httpd' }
    /(?i-mx:debian)/: { $webserver='apache2' }
    default: { $webserver='httpd' }
    }

package{"$webserver":
    ensure  => installed,
    before  => [ File['httpd.conf'], Service['httpd'] ],
}

file{'httpd.conf':
    path    => '/etc/httpd/conf/httpd.conf',
    source  => '/root/manifests/httpd.conf',
    ensure  => file,
}

service{'httpd':
    ensure  => running,
    enable  => true,
    restart => 'systemctl restart httpd.service',
    subscribe => File['httpd.conf'],
}
  1. selector 語句

    • 語法及格式
CONTROL_VARIABLE ? {
    case1 => value1,
    case2 => value2,
    ...
    default => valueN,
}

    CONTROL_VARIABLE的給定方法:
        (1) 變量
        (2) 有返回值的函數

    各case的給定方式:
        (1) 直接字串;
        (2) 變量 
        (3) 有返回值的函數
        (4) 正則表達式模式;
        (5) default 

    注意:不能使用列表格式;但可以是其它的selecor
  • 示例:
$webserver = $osfamily ? {
    "Redhat" => 'httpd',
    /(?i-mx:debian)/ => 'apache2',
    default => 'httpd',
}

package{"$webserver":
    ensure  => installed,
    before  => [ File['httpd.conf'], Service['httpd'] ],
}

file{'httpd.conf':
    path    => '/etc/httpd/conf/httpd.conf',
    source  => '/root/manifests/httpd.conf',
    ensure  => file,
}

service{'httpd':
    ensure  => running,
    enable  => true,
    restart => 'systemctl restart httpd.service',
    subscribe => File['httpd.conf'],
}

6.puppet的類

類:puppet中命名的代碼模塊,常用於定義一組通用目標的資源,可在puppet全局調用;類可以被繼承,也可以包含子類;

  • 語法格式:
class NAME {
    ...puppet code...
}

class NAME(parameter1, parameter2) {
    ...puppet code...
}
  • 類代碼只有聲明後纔會執行,調用方式:
    (1) include CLASS_NAME1, CLASS_NAME2, ...
    (2) class{'CLASS_NAME':
            attribute => value,
        }

子類

sub_class_name:
    base_class::sub_class_name

子類中引用父類的資源:
    Type['title'] {
        attribute => value,
        atrribute +> value,
    }

在子類中爲父類的資源新增屬性或覆蓋指定的屬性的值:
    Type['title'] {
        attribute1 => value,
        ...
    }

在子類中爲父類的資源的某屬性增加新值:
    Type['title'] {
        attribute1 +> value,
        ...
    }
  • 示例
#定義父類nginx
class nginx {
    package{'nginx':
    ensure  => installed,
    }

    service{'nginx':
        ensure  => running,
        enable  => true,
        restart => '/usr/sbin/nginx -s reload',
    }
}
#定義nginx的子類nginx::web
class nginx::web inherits nginx {
    Service['nginx'] {
        subscribe => File['ngx-web.conf'],
    }

    file{'ngx-web.conf':
        path    => '/etc/nginx/conf.d/ngx-web.conf',
        ensure  => file,
        source  => '/root/manifests/ngx-web.conf',
    }
}
#定義nginx的子類nginx::proxy
class nginx::proxy inherits nginx {
    Service['nginx'] {
        subscribe => File['ngx-proxy.conf'],
    }

    file{'ngx-proxy.conf':
        path    => '/etc/nginx/conf.d/ngx-proxy.conf',
        ensure  => file,
        source  => '/root/manifests/ngx-proxy.conf',
    }
}
#調用(聲明)nging的子類nginx::proxy
include nginx::proxy

7.puppet模板

erb:模板語言,embedded ruby;

  • 在資源中使用模板的格式
file{'title':
    ensure  => file,
    content => template('MOD_NAME/ERB_FILE'),
}
  • 文本文件中內嵌變量替換機制:
<%= @VARIABLE_NAME %>

8.puppet模塊

模塊就是一個按約定的、預定義的結構存放了多個文件或子目錄的目錄,目錄裏的這些文件或子目錄必須遵循一定格式的命名規範

  • puppet模塊的目錄結構
MODULES_NAME:
    manifests/
        init.pp:必須一個類定義,類名稱必須與模塊名稱相同
    files/:靜態文件
    templates/:
    lib/:插件目錄,常用於存儲自定義的facts以及自定義類型
    spec/:類似於tests目錄,存儲lib/目錄下插件的使用幫助和範例
    tests/:當前模塊的使用幫助或使用範例文件

模塊名只能以小寫字母開頭,可以包含小寫字母、數字和下劃線;但不能使用 “main” 和 “settings”

注意:
- puppet 3.8及以後的版本中,資源清單文件的文件名要與文件聽類名保持一致,例如某子類名爲“base_class::child_class”,其文件名應該爲child_class.pp
- 無需再資源清單文件中使用import語句
- manifests目錄下可存在多個清單文件,每個清單文件包含一個類,其文件名同類名

9.模塊執行測試

  1. standalone模式:測試命令如下
    puppet apply  [-d|--debug] [-v|--verbose] [-e|--execute] [--noop] <CLASS_NAME.pp>
  1. master/agent模式 :通過master節點的主機資源清單實現執行過程,agent每隔30分鐘到master端請求與自己相關的catalog
    master: site manifest
        node 'node_name' {
            ...puppet code...
        }

10.puppet的幫助文檔

程序包下載路徑:
        https://yum.puppetlabs.com/

    官方文檔:
        https://docs.puppet.com/puppet/3/reference/

    內建函數:
        https://docs.puppet.com/puppet/3/reference/function.html

    配置參數列表:
        https://docs.puppet.com/puppet/3/reference/configuration.html

    puppet兼容的erb語法:
        https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html
發佈了56 篇原創文章 · 獲贊 33 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章