標籤:AC 重新定義 命名方式 機器 加強 odi 環境 不同的 ext
puppet(4)-類、模版語言、模組代碼重用: class, module類
類是用於公用目的的一組資源,是命名的代碼塊,建立後可在puppet全域進行調用,類可以繼承類是我們構建模組的基本組件
類:命名的puppet代碼塊,好處就是可以重複調用,需要時可通過名稱進行調用; class my_class { ...puppet code... } puppet code: 包含變數賦值、各種條件判斷語句、資源聲明等等; 注意: 類的名字只能以小寫字母開頭 調用類: include class1, class2, ... class {‘classname‘: }
每個類都會引入一個新的變數scope(範圍),這意味著在任何時候訪問類的變數時,都得使用其完全限定名稱,不過,在本地scope可以重新為top scope中的變數賦於一個新值
寫法舉例一:
class apache{ package{‘httpd‘: ensure => installed, } file{‘httpd.conf‘: path => ‘/etc/httpd/conf/httpd.conf‘, ensure => file, require => Package[‘httpd‘], } service{‘httpd‘: ensure => running, require => Package[‘httpd‘], subsribe => File[‘httpd.conf‘], } }
寫法舉例二:
class nginx{ $webserver=‘nginx‘ package{$webserver: ensure => latest, } file{"/etc/$webserver/nginx.conf": ensure => file, source => "/opt/puppet/modules/$webserver/files/nginx.conf", require => Package[$webserver], # notify => Service[‘nginx‘], } service{$webserver: ensure => running, enable => true, hasstatus => true, hasrestart => true, # restart => ‘systemctl reload nginx.service‘, require => [ Package[$webserver], File["/etc/$webserver/nginx.conf"]], subscribe => File["/etc/$webserver/nginx.conf"], } } class {‘nginx‘: }
類的聲明有四種方法:
1.使用include 2.使用require 3.像聲明一個資源一樣聲明類 4.使用ENC的風格來聲明一個類 1&3是最常用的 第一種:include base::linux,apache 可以用逗號隔開聲明多個類 include nginx 第二種: require apache這種方式很少用 第三種: class {‘nginx‘: version => ‘2.2.21‘ } 可以傳入參數,所以很常用 注意:類只有在聲明後方才執行
定義帶參數的類:
class my_class ($para1=value1, $para2=value2) { ...puppet code... }
調用時,傳遞參數:
class {‘class_name‘: para1 => new_value1, para2 => new_value2, }
寫法舉例一:
class createuser ($grpname=testgrp,$username=testuser) { group{"$grpname": ensure => present, } user{"$username": ensure => present, gid => $grpname, } } class {‘createuser‘: grpname => mageedu, username => mageedu, }
寫法舉例二:
class nginx ($webserver=‘nginx‘){ package{$webserver: ensure => latest, } file{"/etc/$webserver/nginx.conf": ensure => file, source => "/opt/puppet/modules/$webserver/files/nginx.conf", require => Package[$webserver], # notify => Service[‘nginx‘], } service{$webserver: ensure => running, enable => true, hasstatus => true, hasrestart => true, # restart => ‘systemctl reload nginx.service‘, require => [ Package[$webserver], File["/etc/$webserver/nginx.conf"]], subscribe => File["/etc/$webserver/nginx.conf"], } } class {‘nginx‘: $webserver = ‘nginx’, }
-
類的繼承:
定義方式:
class base_class_name { ... puppet code ... } class base_class_name::class_name inherits base_class_name { ...puppet code... }
base_class_name::class_name 這是繼承類命名的一種規範,讓你一眼就知道這是繼承某個類的子類(它只是一個名字,沒有任何作用,不這樣寫你會以為它沒有繼承其他類,這種命名方式叫做完全限定名稱)
inherits base_class_name 表示繼承哪個類
類的繼承這種寫法的作用:繼承一個已有的類,並實現覆蓋資源屬性,或向資源屬性追加額外值
比如說我之前定義了一個類,這個類就定義了一個package資源-安裝了nginx, 然後我現在又想定義一個類 有修改設定檔和 啟動服務的資源,這時候就可以繼承類。
(1) 繼承資源屬性;
(2) 覆蓋資源屬性;
=>
(3) 追加資源屬性;
+>
類在實現繼承時有幾個要點:
(1) 聲明子類時,其基類會被首先聲明; (2) 基類成為子類的父範圍,因為基類變數和屬性預設值會被子類直接複製一份 (3) 子類可以覆蓋父類中同一資源的相同屬性值
繼承類的執行個體:
class nginx { package {‘nginx‘: ensure => latest, } -> service {‘nginx‘: enable => true, ensure => running, hasrestart => true, hasstatus => true, restart => ‘service nginx reload‘ } } class nginx::webserver inherits nginx { file{‘/etc/nginx/nginx.conf‘: source => ‘/opt/puppet/modules/nginx/files/nginx_web.conf‘ ensure => file, notify => Service[‘nginx‘], } } class nginx::haproxy inherits nginx { file{‘/etc/nginx/nginx.conf‘: source => ‘/opt/puppet/modules/nginx/files/nginx_proxy.conf‘ ensure => file, notify => Service[‘nginx‘], } }
以上puppet code 定義了一個基類實現程式包的安裝,此外我們額外定義了兩個子類,分別實現 webserver 和 proxy功能。
但是一台機器上怎麼聲明呢?一個節點不能帶兩種角色,什麼時候用呢?
將來我們做master/agent模型,兩個node ,第一個node include nginx::webserver這個類,另外一個node include nginx::haproxy
可以引用測試:include nginx::webserver
進階繼承:
繼承後子類改父類資源中屬性的值:
class nginx { package {‘nginx‘: ensure => latest, } -> service {‘nginx‘: enable => true, ensure => running, hasrestart => true, hasstatus => true, restart => ‘service nginx reload‘ } } class nginx::webserver inherits nginx { Package[‘nginx‘]{ ##這裡是資源引用 大寫[‘tittle‘] name => ‘tengine‘, } file{‘/etc/nginx/nginx.conf‘: source => ‘/opt/puppet/modules/nginx/files/nginx_web.conf‘ ensure => file, notify => Service[‘nginx‘], } } class nginx::haproxy inherits nginx { file{‘/etc/nginx/nginx.conf‘: source => ‘/opt/puppet/modules/nginx/files/nginx_proxy.conf‘ ensure => file, notify => Service[‘nginx‘], } }從新定義父資源中的屬性時要使用資源引用 即 Package[‘nginx‘]{ name => ‘tengine‘, }在子類總不僅可以修改屬性,還可以加 比如: Package[‘nginx‘]{ name +> ‘varnish‘, }
有了類我們就可以組織模組了,不過為了讓模組功能更加強大,我們可以在puppet中使用模版,那麼我們就要學習puppet的模版語言。
學習模版語言之前我們先想下,模版語言有什麼作用?
舉個例子,前面我們 定義了nginx類,類中定義了package資源,file資源,service資源。 其中file資源定義的是 nginx的設定檔,設定檔裡有一個配置項需要根據伺服器的cpu個數,如何靈活的根據伺服器cpu的個數來配置nginx中的這一項參數呢?寫死是一種方式,然後在拷貝多個設定檔,定義不同的子類,子類在重新定義file資源中的source屬性,也可以實現,但是不是很繁瑣,所以我們可以想象有這麼一種方式,在nginx.conf檔案中定義一個變數,變數的值就是取伺服器的cpu個數,那麼靜態檔案中定義變數,用什麼來解釋呢。在puppet中當然就由puppet來解釋,而這種在靜態檔案中定義變數以及寫邏輯判斷的做法就叫做模版語言。所以我覺得模版語言 其實就是針對file資源使用的語言。puppet是ruby語言開發的,所以puppet 模版檔案中嵌套的語言也是ruby語言。
模版:基於ERB嵌入式的ruby模版語言,他表示在靜態檔案中使用變數等編程元素產生適用於多種環境的文字檔(設定檔)。Embedded Ruby簡稱ERB,它主要用於實現在文字檔嵌入ruby代碼。原來的文本資訊不回被改變,但是ruby代碼會執行。執行的結果將直接替換原來的代碼處:
文法: <%= Ruby Expression %>: 替換為運算式的值; <% Ruby Expression %>: 僅執行代碼,而不替換。 <%# comment %>: 文本注視 <%% 表示轉義符 輸出為<%這個符號,一般用不到 %%> 輸出為 %> ,用不到 <%- Ruby code %>, 忽略空白字元 <% Ruby code -%> ,忽略空白行。 能夠用到的只有第一種 模版語言中可以使用puppet中的任意可用變數,但是變數名要以@符號開頭。 在模版中還可以使用迴圈 ,條件判斷等各種複雜文法格式。 條件判斷: <% if condition -%> some text <% else %> some other text <% end %> 迭代,像for迴圈 <% @ArrayName.echo do | variable_name %> some text with <%- variable_name %> <% end %> 這裡ArrayName是 puppet的一個陣列變數。 variable_name 為賦值給的變數,相當於 for i in list ,list是ArrayName , i是 variable_name條件和迭代 不要求會,能看懂別人寫的代碼就行 了,關鍵我們會使用變數就行了。比如上面說到nginx的設定檔問題。
如何在資源定義中引用模版?
首先我們把file檔案的source 改成關於啟動進程的部分改成如下:
user nginx; worker_processes <%= @processorcount %>; error_log /var/log/nginx/error.log; pid /run/nginx.pid;
對於這種含有模版語言的檔案,我們應用到file資源屬性要改變一下用法了,不能用source 屬性,改用 content屬性以及 puppet內建的模版函數template() ,具體如下:
class nginx { package {‘nginx‘: ensure => latest, } -> service {‘nginx‘: enable => true, ensure => running, hasrestart => true, hasstatus => true, restart => ‘service nginx reload‘ } } class nginx::webserver inherits nginx { Package[‘nginx‘]{ name => ‘tengine‘, } file{‘/etc/nginx/nginx.conf‘: source => ‘/opt/puppet/modules/nginx/files/nginx_web.conf‘, ensure => file, notify => Service[‘nginx‘], } } class nginx::haproxy inherits nginx { file{‘/etc/nginx/nginx.conf‘: #source => ‘/opt/puppet/modules/nginx/files/nginx_proxy.conf‘ content => template(‘/opt/puppet/modules/nginx/files/nginx_proxy.conf‘), ensure => file, notify => Service[‘nginx‘], } } include nginx::haproxy
以上就是模版語言,以及模版語言是如何調用的。
modules
puppet模組:為了實現某種完備功能而組織成的一個獨立的、自我包含的目錄結構
模組名:目錄名
目錄結構:
modules/ module_name/: manifests/ init.pp: 必須聲明一個類,類名與模組名相同; *.pp: MODULE_NAME::[SUBDIR_NAME]::MANIFESTS_FILE_NAME files/: 靜態檔案 puppet url: puppet:///modules/MODULE_NAME/[SUBDIR_NAME]/FILE_NAME file{‘nginx.conf‘: source => puppet:///modules/nginx/nginx.conf } templates/: 模板檔案:*.erb template(‘MODULE_NAME/TEMPLATE_FILE_NAME‘); file{‘nginx.conf‘: content => template(‘模板檔案‘), } lib/: 外掛程式 tests/: 模組使用說明文檔,以及案例example spec/: lib目錄下的外掛程式使用說明文檔
puppet model
ACTIONS: build Build a module release package. changes Show modified files of an installed module. generate Generate boilerplate for a new module. install Install a module from the Puppet Forge or a release archive. list List installed modules search Search the Puppet Forge for a module. uninstall Uninstall a puppet module. upgrade Upgrade a puppet module.
puppet(4)-類、模版語言、模組