類的簡單說明
類是用於公共目的的一組資源,是命名的代碼塊,建立後可在puppet全局進行調用,類能夠繼承類是咱們構建模塊的基本組件node
類:命名的puppet代碼塊,好處就是能夠重複調用,須要時可經過名稱進行調用; class my_class { ...puppet code... } puppet code: 包含變量賦值、各類條件判斷語句、資源聲明等等; 注意: 類的名字只能以小寫字母開頭 調用類: include class1, class2, ... class {'classname': }
類的寫法linux
寫法舉例一:nginx
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'], } }
寫法舉例二:web
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': }
類的聲明apache
有四種方法:編程
1.使用include 2.使用require 3.像聲明一個資源同樣聲明類 4.使用ENC的風格來聲明一個類
1&3是最經常使用的數組
第一種:include base::linux,apache 能夠用逗號隔開聲明多個類
include nginx
第二種: require apache這種方式不多用
第三種:ruby
class {'nginx': version => '2.2.21' }
能夠傳入參數,因此很經常使用服務器
注意:
類只有在聲明後方纔執行
每一個類都會引入一個新的變量scope(做用域),這意味着在任什麼時候候訪問類的變量時,都得使用其徹底限定名稱,不過,在本地scope能夠從新爲top scope中的變量賦於一個新值函數
定義帶參數的類:
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個數來配置運行nginx可使用的cpu數。如何靈活的根據服務器cpu的個數來配置nginx中的這一項參數呢?能夠拷貝多個配置文件定義不一樣的值,而後再定義不一樣的子類,子類在從新定義file資源中的source屬性,而後不一樣的節點定義聲明不一樣的子類,這種方式實現起來很繁瑣,因此咱們能夠想象有這麼一種方式,在nginx.conf文件中定義一個變量,變量的值就是取服務器的cpu個數,那麼靜態文件中定義變量,用什麼來解釋呢。在puppet中固然就由puppet來解釋,而這種在靜態文件中定義變量以及寫邏輯判斷的作法就叫作模版語言。因此我以爲模版語言 其實就是針對file資源使用的語言。puppet是ruby語言開發的,因此puppet 模版文件中嵌套的語言也是ruby語言。
puppet模板語言的寫法
模版:基於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模塊:爲了實現某種完備功能而組織成的一個獨立的、自我包含的目錄結構
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 模塊相關的命令
puppet model <action>命令 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.