puppet基础进阶

===============================================================================

概述:


===============================================================================

puppet variable:

 1.变量的格式:

puppet的变量名必须以“$”开头,f赋值操作符为“=”:$variable_name=value 

任何正常数据类型(非正则)的值都可以赋予puppet中的变量,如字符串、数值、布尔值、数组、hash以及特殊的undef值(即变量未被赋值)

puppet的每个变量都有两个名字:简短名字和长格式完全限定名字(FQN)完全限定名称的格式:“$scope::variable”

 2.数据类型:

数据类型:

  • 字符型:引号可有可无;但单引号为强引用,双引号为弱引用;

  • 数值型:默认均识别为字符串,仅在数值上下文才以数值对待;

  • 数组:[]中以逗号分隔元素列表;

  • 布尔型值:true, false;

  • hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;如:{ 'mon' => 'Monday', 'tue' => 'Tuesday', };

  • undef:未赋值型 ;

 3.正则表达式:

    是一种特殊的数据类型,只能用在特殊的环境当中,不能赋值给变量。

语法格式:

  • (?:)

  • (?-:)

选项:

  • i:忽略字符大小写;-i 表示不忽略字符大小写;

  • m:把.当换行符;

  • x:忽略中的空白字符

注意:

  • 通常书写为 < i-mx >

  • 不能赋值给变量 ,仅能用在接受=~或!~操作符的位置;

 4.puppet的变量类型:

facts:

  • puppet使用了一个称作Facter的工具来搜集系统信息,规范化后将其放进一系列变量中,并传递给puppet;

  • Fact的各变量是Top scope的变量,这意味着可以在个manifest中直接通过${fact name} 访问所需的fact变量;

  • facter -p

内建变量:

  • master端变量 :$servername,$serrverip,$serverversion

  • agent端变量 :$environment,$clientcert,$clientversion

  • parser变量:$module_name

用户自定义变量:

==========================================================================

变量的作用域:scop

作用:

  • scop是一个特定的代码区域,用于同程序中的其他代码隔离开来;

  • 在puppet中,scope可用于限定变量及资源默认属性的作用范围,但不能用于限定资源名称及资源引用的生效范围;

scop分类:

深入浅出puppet(二)_第1张图片

  • 任何给定的scope都可以访问自己的内容,以及接受来自于其父scope、节点scope及top scope的内容;

  • 如图所示:top scope仅能访问自己变量和属性默认值;

  • 节点scope能访问自己的及top scope的变量和属性默认值;

  • example::parent,example::other和example::four能访问自己的以及节点scope和top scope的变量和默认值;

  • 如果访问非当前scope中的变量,则需要通过完全限制名称进行,如:$vhostdir=$apache::params::vhostdir

  • 需要注意的是,top scope的名称空间为空,此时,如若要引用其变量,则需要使用类似“$::osfamily”的方式进行。

 5.puppet流程控制语句:

if语句:

深入浅出puppet(二)_第2张图片

CONDITION的给定方式:

  • 变量

  • 比较表达式

  • 有返回值的函数

演示:

[root@centos7 manifests]# cat if.pp 
if $osfamily =~ /(?i-mx:debian)/ {    # if条件判断语句 
       $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'], # 订阅File资源,也可以在file中使用notify通知机制
}

case语句:

深入浅出puppet(二)_第3张图片

CONTROL_EXPRESSION:

  • 变量

  • 表达式

  • 有返回值的函数

各case的给定方式:

  • 直接字串;

  • 变量 

  • 有返回值的函数

  • 正则表达式模式

  • default 

演示:

[root@centos7 manifests]# cat case.pp 
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'],
}

selector语句:

深入浅出puppet(二)_第4张图片

CONTROL_VARIABLE的给定方法:

  • 变量

  • 有返回值的函数

各case的给定方式:

  • 直接字串;

  • 变量 

  • 有返回值的函数

  • 正则表达式模式

  • default 

注意:不能使用列表格式;但可以是其它的selecor;

演示:

[root@centos7 manifests]# cat selector.pp 
$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'],
}

puppet的类:

 1.类的定义,语法格式及调用方式

定义:

  • puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;

  • 类可以被继承,也可以包含子类

语法格式:

深入浅出puppet(二)_第5张图片

类代码只有声明后才会执行,调用方式:

wKioL1h61Fqi5JEtAAARNonUnps558.png

示例1:

[root@centos7 manifests]# cat class1.pp
class webservice {
     $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'],
     }
}

include webservice

示例2:在外部向类传递变量

[root@centos7 manifests]# cat class2.pp
class web($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'],
     }
}

class{'web':
       webserver     => 'apache2' # 差UN地参数apache2
}

 2.类继承的方式:

语法格式:

wKioL1h65NGT6XXRAAAMAa4r_wo196.png

演示:

# 编辑类继承方式的文件如下:
[root@centos7 manifests]# vim class3.pp 
class nginx {
      package{'nginx':
           ensure   => installed,
	   provider => 'rpm',
	   source   => '/root/nginx/nginx-1.10.0-1.el7.ngx.x86_64.rpm',
      }

      service{'nginx':
           ensure   => running,
	   enable   => false,
	   restart  => '/usr/sbin/nginx -s reload',
	   require  => Package['nginx'],
      }
}

class nginx::web inherits nginx {
      file{'ngx-web.conf':
           path     => '/etc/nginx/conf.d/ngx-web.conf',
	   ensure   => file,
	   require  => Package['nginx'],
	   source   => '/root/manifests/nginx/ngx-web.conf',
      }
      
      Service['nginx'] {
            subscribe  => File['ngx-web.conf'],
      }

}

include nginx::web

#=======================================================================================
# 提供file资源的源文件
[root@centos7 manifests]# mkdir nginx
[root@centos7 manifests]# cp /etc/nginx/conf.d/default.conf ./nginx/ngx-web.conf

# 运行类文件
[root@centos7 manifests]# puppet apply --verbose  class3.pp 
Notice: Compiled catalog for centos7 in environment production in 0.89 seconds
Info: Applying configuration version '1484478306'
Info: Computing checksum on file /etc/nginx/conf.d/ngx-web.conf
Info: /Stage[main]/Nginx::Web/File[ngx-web.conf]: Filebucketed /etc/nginx/conf.d/ngx-web.conf to puppet with sum 1d2348ea2b39fef56fcf4431b767fa34
Notice: /Stage[main]/Nginx::Web/File[ngx-web.conf]/content: content changed '{md5}1d2348ea2b39fef56fcf4431b767fa34' to '{md5}4dce452bf8dbb01f278ec0ea9ba6cf40'
Info: /Stage[main]/Nginx::Web/File[ngx-web.conf]: Scheduling refresh of Service[nginx]
Notice: /Stage[main]/Nginx/Service[nginx]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.55 seconds

深入浅出puppet(二)_第6张图片

puppet模板:

 1.类的定义,语法格式及调用方式

erb:

  • 模板语言,embedded ruby;

puppet兼容的erb语法:

  • https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html

wKioL1h7Y-7TMolcAAAMsExKvtU109.png 

文本文件中内嵌变量替换机制:

  • <%= @VARIABLE_NAME %>

示例1:

# 编辑模板文件
[root@centos7 manifests]# vim tem.pp 
file{'/tmp/template.txt':
	content    => template('/root/manifests/test.erb'),
	mode       => '0640',
}

# 提供内嵌变量的替换文件
[root@centos7 manifests]# vim test.erb 
Operating System: <%= @operatingsystem %>
Version: <%= @operatingsystemrelease %>

# 运行文件tem.pp
[root@centos7 manifests]# puppet apply --verbose  tem.pp 
Notice: Compiled catalog for centos7 in environment production in 1.21 seconds
Info: Applying configuration version '1484481315'
Notice: /Stage[main]/Main/File[/tmp/template.txt]/ensure: defined content as '{md5}9f762979c3dc552a63a74c715a40ae53'
Notice: Finished catalog run in 0.03 seconds

# 查看执行后的结果可以看到内嵌变量替换为相应的系统和版本
[root@centos7 manifests]# cat /tmp/template.txt 
Operating System: CentOS
Version: 7.2.1511

示例2:使nginx的配置文件中worker_processes的值为当前主机的cpu核心数

# 编辑temp2.pp的配置文件如下:
[root@centos7 manifests]# vim temp2.pp 
class nginx {
      package{'nginx':
           ensure   => installed,
	   provider => 'rpm',
	   source   => '/root/nginx/nginx-1.10.0-1.el7.ngx.x86_64.rpm',
      }

      service{'nginx':
           ensure   => running,
	   enable   => false,
	   require  => Package['nginx'],
      }
}

class nginx::web inherits nginx {
      file{'ngx-web.conf':
           path     => '/etc/nginx/conf.d/ngx-web.conf',
	   ensure   => file,
	   require  => Package['nginx'],
	   source   => '/root/manifests/nginx/ngx-web.conf',
      }
      
      file{'nginx.conf':
           path     => '/etc/nginx/nginx.conf',
	   ensure   => file,
	   content  => template('/root/manifests/nginx/nginx.conf.erb'), # 使用模板文件
	   require  => Package['nginx'],
      }

      Service['nginx'] {
            subscribe  => [  File['ngx-web.conf'],File['nginx.conf'] ],
      }

}

include nginx::web
----------------------------------------------------------------------------------------
# 编辑nginx.conf的模板文件
[root@centos7 manifests]# cat nginx/nginx.conf.erb 

user  nginx;
worker_processes  <%= @processorcount %>; # 进程数使用内置变量替换

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
# 运行temp2.pp
[root@centos7 manifests]# puppet apply --verbose  temp2.pp 
Notice: Compiled catalog for centos7 in environment production in 1.11 seconds
Info: Applying configuration version '1484483076'
Info: Computing checksum on file /etc/nginx/nginx.conf
Info: /Stage[main]/Nginx::Web/File[nginx.conf]: Filebucketed /etc/nginx/nginx.conf to puppet with sum f7984934bd6cab883e1f33d5129834bb
Notice: /Stage[main]/Nginx::Web/File[nginx.conf]/content: content changed '{md5}f7984934bd6cab883e1f33d5129834bb' to '{md5}43af14050809e44e3af2515762545a50'
Info: /Stage[main]/Nginx::Web/File[nginx.conf]: Scheduling refresh of Service[nginx]
Notice: /Stage[main]/Nginx/Service[nginx]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.71 seconds

#查看nginx的进程数可以看到为4个
[root@centos7 manifests]# ps aux |grep  ^nginx
nginx      4614  0.0  0.3  50276  3768 ?        S    20:24   0:00 nginx: worker process
nginx      4615  0.0  0.3  50276  3768 ?        S    20:24   0:00 nginx: worker process
nginx      4616  0.0  0.3  50276  3768 ?        S    20:24   0:00 nginx: worker process
nginx      4617  0.0  0.3  50276  3768 ?        S    20:24   0:00 nginx: worker process

puppet模块:

 1.类的定义,语法格式及调用方式

定义:

  • 模块就是一个按约定的、预定义的结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范;

  • puppet会在配置的路径下查找所需要的模块;

模块名:MODULES_NAME

manifests/

  • init.pp:必须一个类定义,类名称必须与模块名称相同;

files/:静态文件;

  • puppet URL:puppet:///modules/MODULE_NAME/FILE_NAME

templates/:

  • tempate('MOD_NAME/TEMPLATE_FILE_NAME')

lib/:插件目录,常用于存储自定义的facts以及自定义类型;

spec/:类似于tests目录,存储lib/目录下插件的使用帮助和范例;

tests/:当前模块的使用帮助或使用范例文件;

示例:

 1.首先在/etc/puppet/modules下创建固有的目录,如下:

[root@centos7 ~]# mkdir -pv /etc/puppet/modules/mariadb/{manifests,files,templates,lib,tests,spec}
mkdir: created directory ‘/etc/puppet/modules/mariadb’
mkdir: created directory ‘/etc/puppet/modules/mariadb/manifests’
mkdir: created directory ‘/etc/puppet/modules/mariadb/files’
mkdir: created directory ‘/etc/puppet/modules/mariadb/templates’
mkdir: created directory ‘/etc/puppet/modules/mariadb/lib’
mkdir: created directory ‘/etc/puppet/modules/mariadb/tests’
mkdir: created directory ‘/etc/puppet/modules/mariadb/spec’

[root@centos7 ~]# cd /etc/puppet/modules/
[root@centos7 modules]# ls
mariadb
[root@centos7 modules]# cd mariadb/
[root@centos7 mariadb]# ll
total 0
drwxr-xr-x 2 root root 6 Jan 15 23:42 files
drwxr-xr-x 2 root root 6 Jan 15 23:42 lib
drwxr-xr-x 2 root root 6 Jan 15 23:42 manifests
drwxr-xr-x 2 root root 6 Jan 15 23:42 spec
drwxr-xr-x 2 root root 6 Jan 15 23:42 templates
drwxr-xr-x 2 root root 6 Jan 15 23:42 tests

 2.在manifests目录下定义一个和模块名称相同的类文件init.pp

[root@centos7 mariadb]# vim manifests/init.pp
 class mariadb($mysqldatadir='/var/lib/mysql') {       #类mariadb接受参数,默认参数为/var/lib/mysql
	package{'mariadb-server':
	       ensure    => installed,
	}

	file{'/etc/my.cnf':
	       ensure    => file,
	       content   => template('mariadb/my.cnf.erb'),  # 内容为模板my.cnf.erb中提供的
	       require   => Package['mariadb-server'],
	}

	file{"$mysqldatadir":          # 幂等性,如果/var/lib/mysql文件不存在就创建
	       ensure    => directory,
	       owner     => mysql,
	       group     => mysql,
	       require   => Package['mariadb-server'],
	}

	service{'mariadb':
	       ensure    => running,
	       enable    => true,
	       subscribe  => File['/etc/my.cnf'], # 订阅file文件
	}
 }	

 3.在mariadb/templates目录下创建my.cnf.erb文件

[root@centos7 ~]# cd /etc/puppet/modules/
[root@centos7 modules]# ls
mariadb
[root@centos7 modules]# cd mariadb/templates/
[root@centos7 files]# cp /etc/my.cnf my.cnf.erb
[root@centos7 files]# vim my.cnf.erb
[mysqld]
datadir=<%= @mysqldatadir %> # 修改为变量(即:默认变量'/var/lib/mysql')替换
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
skip_name_resolve = ON
innodb_file_per_table = ON

#log_bin=master-log
#server-id=1
#relay-log=relay-log
#relay-log-purge=0 
#read-only=1
#ssl
#ssl_ca = /var/lib/mysql/ssl/cacert.pem
#ssl_cert = /var/lib/mysql/ssl/master.crt
#ssl_key = /var/lib/mysql/ssl/master.key
#auto_increment_offset=1
#auto_increment_increment=2
#innodb_log_file_size = 50331648
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

 4.查看定义的mariadb模块,并调用

[root@centos7 mariadb]# puppet module list
/etc/puppet/modules
└── mariadb (???)
/usr/share/puppet/modules (no modules installed)

[root@centos7 mariadb]# puppet apply --verbose --noop  -e "include mariadb"
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults
Notice: Compiled catalog for centos7 in environment production in 1.18 seconds
Info: Applying configuration version '1484498009'
Notice: /Stage[main]/Mariadb/File[/etc/my.cnf]/content: current_value {md5}a9949c923d1ef818c4c848b1b48b52eb, should be {md5}218c5f66438bf813d07a251ad6939a43 (noop)
Info: /Stage[main]/Mariadb/File[/etc/my.cnf]: Scheduling refresh of Service[mariadb]
Notice: /Stage[main]/Mariadb/Service[mariadb]: Would have triggered 'refresh' from 1 events
Notice: Class[Mariadb]: Would have triggered 'refresh' from 2 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.47 seconds

# 也可以像class传递参数
[root@centos7 mariadb]# puppet apply --verbose --noop  -e "class{'mariadb': mysqldatadir => '/data/mydata'}"
Notice: Compiled catalog for centos7 in environment production in 1.12 seconds
Info: Applying configuration version '1484498184'
Notice: /Stage[main]/Mariadb/File[/etc/my.cnf]/content: current_value {md5}218c5f66438bf813d07a251ad6939a43, should be {md5}a9949c923d1ef818c4c848b1b48b52eb (noop)
Info: /Stage[main]/Mariadb/File[/etc/my.cnf]: Scheduling refresh of Service[mariadb]
Notice: /Stage[main]/Mariadb/Service[mariadb]: Would have triggered 'refresh' from 1 events
Notice: /Stage[main]/Mariadb/File[/data/mydata]/ensure: current_value absent, should be directory (noop)
Notice: Class[Mariadb]: Would have triggered 'refresh' from 3 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.39 seconds

深入浅出puppet(二)_第7张图片