> 文档中心 > PUPPET配置进阶

PUPPET配置进阶

PUPPET配置进阶

文章目录

      • 一、简介
      • 二、目录结构
      • 三、一个helloworld
        • 3.1 创建module
        • 3.2 配置入口
        • 3.3 验证
      • 四、常用资源列表
        • 4.1 user
        • 4.2 group
        • 4.3 package
        • 4.4 file
        • 4.5 service
        • 4.6 exec
        • 4.7 cron
        • 4.8 notify
      • 五、变量与作用域
        • 5.1 数据类型
        • 5.2 变量赋值
        • 5.3 作用域
      • 六、条件语句与函数
        • 6.1 条件语句
        • 6.2 表达式
        • 6.3 函数
      • 七、模块、类、模板
        • 7.1 模块
        • 7.2 类
        • 7.3 模板
      • 八、节点管理

一、简介

Puppet是开源的基于Ruby的系统配置管理工具,依赖于C/S的部署架构。主要开发者是Luke Kanies,遵循GPLv2版权协议。从1997年开始Kanies参与UNIX的系统管理工作,Puppet的开发源于这些经验。因为对已有的配置工具不甚满意,从2001年到2005年间,Kanies开始在Reductive实验室从事工具的开发。很快,Reductive实验室发布了他们的旗舰产品——Puppet

二、目录结构

PUPPET配置进阶

puppet遵循定义-模拟-执行-报告的工作流程

PUPPET配置进阶

(a) agent把节点名与facts信息发送给master
(b) master通过site.pp中包含的node名称匹配agent相关的资源路径,将所需要的class类信息编译后存入catalog并发送给agent
© agent对catalog进行代码验证(检测语法及错误)并执行,执行信息、结果写入日志
(d) agent完成执行,系统达到预期状态,把结果及执行数据返回给master

客户端与服务器端的安全认证

  • Puppet通信都采用SSL安全加密协议,以保障所有数据传输的安全性
  • Puppet Master 在启动后会向自己签发证书和key。可以在/var/puppet/ssl或/var/lib/puppet/ssl目录下看到它们
  • Puppet Agent 在运行puppet apply–test 时添加参数–verbose 可以在客户端终端看到申请证书的详细过程
  • Puppet Master 同样可以使用puppetcert list查看申请证书的客户端列表。使用命令puppetcert sign agent_name来签发证书
  • 如果Master一直不签发证书,客户端会每2分钟请求一次

三、一个helloworld

3.1 创建module

module的目录结构是固定的,目录的结构一般如下所示:
├── files
├── manifests
└── templates

  • files: 属于模块的文件
  • manifests: 脚本文件
  • templates:模板文件
mkdir -p /etc/puppet/modules/helloworld/{files,templates,manifests}

新建模块的init.pp文件

vi /etc/puppet/modules/helloworld/manifests/init.ppclass helloworld{  file { '/tmp/hello.txt': owner => 'root', group => 'root', mode => '0440', source => 'puppet:///modules/helloworld/hello_old.txt'}}
  1. 配置file

在 /etc/puppet/modules/helloworld/files 预先新建hello_old文件

echo 'helloworld' >  /etc/puppet/modules/helloworld/files/hello_old.txt

3.2 配置入口

编辑入口文件 vi /etc/puppet/manifests/site.pp ,无则新建

node 'Hostname(agent端的主机名)' {include helloworld}

3.3 验证

客户端执行 puppet agent -t --summarize

PUPPET配置进阶

测试查看

PUPPET配置进阶

四、常用资源列表

资源依赖四大元参数:

资源依赖:

require:配置当前资源中,指向被引用的资源, 且被引用的资源的资源类型需要首字母大写

PUPPET配置进阶

before:配置在被引用的资源中,指向当前资源

PUPPET配置进阶

资源通知:

subscribe:订阅,配置在被引用资源,文件发生变化即可执行

PUPPET配置进阶

notify:通知,配置在当前资源,文件发生变化通知执行

PUPPET配置进阶

4.1 user

定义:管理系统上的用户

#title:用户名user{'testuser': #present/absent,删除用户使用absent ensure => present, #是否为系统用户 system => false, #注释 comment => 'Test User', #默认是shell类型 shell => '/bin/bash', #用户的home目录 home => '/home/testuser', #是否创建家目录,默认为false managehome => true, #附加组,不包含基本组 groups => 'testuser', #用户的UID uid => 3000, #用户组gid gid => 3000, #用户加密的密码 password => '$1$2xm5sJf2$IaidZnkoU5gY23sccEimT0',}

4.2 group

定义: 管理系统上的用户组

#组名group{'testgroup': #组名 name    => 'testgroup', #用户组的gid,不指定将自动设置大于500的随机值 gid     => 1212, #默认为false,允许使用同一个gid allowdupe => false, #默认为false,系统平台默认创建uid为0-500的系统用户 system  => false, #默认属性,创建present,删除absent ensure  => present, #组成员管理 menbers => ['zhangsan','lisi']}

4.3 package

定义: puppet的管理软件包

安装软件包

package{'redis':    #包名,可以省略,如果省略,将继承title的值    name  =>  'redis',    #ensure:installed, present, latest, absent, any version string (implies present)    ensure  => installed,    #程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg    #source  => '/tmp/redis.rpm'    #指明安装方式    provider  =>  yum}

4.4 file

定义: 管理文件、目录、软链接

同步服务器文件至客户端

file{'test':  #目的路径   path  => '/tmp/test',  #源路径    source  => 'puppet:///modules/testfile/test',    #定义文件属主    owner => 'zhangsan',    #定义文件属组    group  => 'zhangsan',    #定义文件的权限    mode  => '755',}

创建目录,文件,符号链接

file {'/tmp/test'#ensure可设置为file,directory,link#分别表示文件、目录和软链接ensure => link,#软链接需要指定目标文件target => /opt/test}

4.5 service

定义: 定义服务的状态

#监听nginx.conf文件的变化,若发生改变则重启nginxservice{'nginx':    #服务的状态,运行为true,停止为false     ensure  => true,     #开机启动设置    enable  => true,    #是否支持restart属性值    hasrestart => true,    #是否支持status属性值    hasstatus => true,    #监听文件改动    subscribe => File["/usr/local/nginx/conf/nginx.conf"],    restart => "nginx -s reload",}file {"/usr/local/nginx/conf/nginx.conf":notify => Service["nginx"]}

4.6 exec

定义:**执行外部命令,慎用 **

exec{'cmd':    command => 'mkdir /data/testdir',    path => ['/bin','/sbin','/usr/bin','/usr/sbin'],}

当命令返回0才执行exec

exec{'nginx -s reload'#命令的搜索路径path => '/usr/bin:/usr/sbin:/bin',#true表示命令仅刷新触发refreshonly => false,#命令返回0才会执行onlyif => '/usr/local/nginx/sbin/nginx -t',#尝试执行次数tries => 3,#重试期间的等待时间try_sleep => 5,}

4.7 cron

定义: 定义周期性任务

cron{'timesync':    command => 'ntpdate 10.27.126.249',    ensure  => present,    minute  => '*/3',    user    => 'root',}

4.8 notify

定义: 调试输出

notify{"I am running!"}

五、变量与作用域

PUPPET变量:由字母[a-z]、[A-Z]、[0-9]和下划线(_)组成,且大小写敏感,puppet中变量必须以"$“为前缀后接”="进行赋值,变量可以保存字符串、数值、布尔型、数组、哈希和特殊的undef值

5.1 数据类型

  • 字符串类型

字符串类型需要以双引号或单引号进行声明。puppet默认的数据类型就是字符串类型,不能使用Puppet关键字。这里有几个特殊的符号作为变量值时,需要进行转义:

\$ : $符号\”: 双引号\' : 单引号\\ : 反斜杠\n : 回车换行符\r : 回车换行\t : tab键,一个tab键默认是7个空格\s : 空格
  • 数值类型(很少用)

数值类型是指定义成的数值形式的数据,这种数据可以直接进行加、减、乘、除等数学运算。

#下面是puppet运算符的优先级从高到底排序:! : 取反In : 范围\* 和 / : 乘和除\- 和 + : 减和加<<>> : 左移和右移== 和 != :等于和不同于\>= <=>< :大于等于、小于等于和大于、小于And : 与Or : 或
  • 正则表达式

在前面我们也简单用了下正则表达式,正则表达式我们在node哪里正则定义多主机的时候是很有用的,因为随着主机的众多不可能一个个的node定义下去。

[] : 用于描述范围(如[A-Z],表示范围在A~Z之间的大写字母)(): 用于包含正则表达式\w:用于描述字母或数字,相当于[0-9a-zA-Z]\W : 非字母或数字。\s: 匹配[\t\n\r\f],其中(\t)为制表符、(\r)为回车符、(\n)为换行符、(\f)为换页符、(\s)表示匹配这些符号的简写方式。\S : 匹配非空字符。\d:匹配[0-9]数字。\D : 匹配非数字。\b : 匹配退格符\B : 非字边界*:前面元素出现0次或多次+:前面元素出现1次或多次{m,n}:前面匀速最少出现m此,最多出现n次?: 前面元素最多出现1次,等价于{0,1}|:与前面或后面表达式匹配i :表示忽略大小写

5.2 变量赋值

class apache ($sta = "present") {  package {"httpd":    ensure=> $sta,  }}

注意:PUPPET不支持重复赋值,也就是一个变量只可以被赋值一次

特殊的变量:Facter变量

定义:Facter是一款扩展性强且功能强大的跨平台的系统性能分析收集工具,它可以收集Agent的信息,并将收集到的Agent信息作为变量传给master使用

PUPPET配置进阶

5.3 作用域

根据大括号范围区分:

#$content变量分别定义于top域、node域和local域.#示例:$content="top"node base {    include admin    $content="node"}#继承了base节点node /sh-(proxy|web)\d+/ inherits base {  case $::hostname {    /sh-proxy\d+/: {  include apache  user {"test1":     ensure => present,     }      }     "sh-web1": { include nginx::nginxconf $content="sh-web1" notify {"this value is $content":}  }    }}

本示例会输出sh-web1,因为局部变量的优先级最高,{}包裹的区间之间作用域不共享,仅全局变量可被子括号区间读取

六、条件语句与函数

6.1 条件语句

  • if语句

    if $operatingsystem == "CentOS"{notify{ "This is CentOS!" }}elsif $operatingsystem in ["RedHat", "Fedora"]{notify{ "This is RedHat, Fedora!" }}else{notify{ "This is other linux release!" }}
  • case语句

    case $operatingsystem{'Solaris': { include role::solaris }'RedHat','CentOS': { include role::redhat }/^(Debian|Ubuntu)$/: { include role::debian }default: { include role::default }}
  • selector

    $rootgroup = $osfamily ? {'Solaris'   => 'whell',/(Darwin|FreeBSD)/ => 'whell',default     => 'root',}file { '/etc/passwd'ensure => file,owner => 'root',group => $rootgroup,}

6.2 表达式

定义:由两个操作数和一个运算符组成,! 操作除外,表示非操作

运算符

比较操作符:==!= ,< , >, <= ,=> , !~ 不能被模式匹配, =~能被模式匹配, in逻辑操作符: and ,or ,|算数操作符: +, - ,*,/, %, << , >>布尔运算符:and  or  !

6.3 函数

puppet函数是在编译过程中运行的预定义Ruby代码块,puppet中包含了大量可调用的内置函数

注:函数只会在编译中运行,过程变量只能是master节点中的内容

  • create_resources(资源类型,一组资源的哈希描述):创建资源

    $myuser = {    'nick' => { uid => '1300', group => allstaff, groups => ['root', 'nick']    }}create_resources(user, $myuser)
  • require:添加依赖关系

  • tag:表示标签

  • tagged:表示标记,是一个boolean类型的函数

  • template:表示模板

七、模块、类、模板

7.1 模块

模块清单:

PUPPET配置进阶

创建模块:

mkdir -p /etc/puppet/modules/{模块名称}/{files,templates,manifests}

创建模块配置文件:

vi /etc/puppet/modules/{模块名称}/manifests/init.pp

编写templates的ERB模板

vi /etc/puppet/modules/{模块名称}/templates/tmp.erb

创建说明文件

vi /etc/puppet/modules/{模块名称}/Modulefilevi /etc/puppet/modules/{模块名称}/README

7.2 类

定义:由一个关键字与一个代码块实现

class class_name {...}

若存在多个类,采取双冒号定义

class class_name {...}class class_name::newclass1 {...}class class_name::newclass2 {...}

类的继承

#定义父类class nginx {    service { 'nginx': name => nginx, ensure => running, enable => true, requireb => File['nginx.conf']    }}#定义继承的类class nginx::foo inherits nginx {    service{ 'nginx': ensure => running, enable => false    }}

7.3 模板

ERB模板:全称是Embedded RuBy,意思是嵌入式的Ruby,是一种文本模板技术,用过JSP的话,会发现两者语法很像。我们项目中一般用ERB来产生各模块的配置文件。ERB模板也可以用来产生Web页面(之前搞过一段时间ROR开发,模板用的haml),也可以用来产生其他文件。

与区别:

,一般是Ruby的逻辑脚本,但是不会写入到目标文件中。
,脚本的执行结果会写入到目标文件中。

define testingsite($cgidir, $tracdir) { file { "testing-$name": path => "/etc/tomcat/testing/$name.conf", owner => superuser, group => superuser, mode => 644, require => File[tomcatconf], content => template("testsite.erb"), notify => Service[tomcat]     }  symlink { "testsym-$name":    path => "$cgidir/$name.cgi",    ensure => "/usr/share/test/cgi-bin/test.cgi" }     }
<Location "/cgi-bin/ .cgi"> SetEnv TEST_ENV "/export/svn/test/" </Location>  # You need something like this to authenticate users <Location "/cgi-bin/.cgi/login"> AuthType Basic AuthName "Test" AuthUserFile /etc/tomcat/auth/svn Require valid-user </Location>

组合模板

template('/path/to/template1''/path/to/template2')

迭代模板

$values = [val1,val2,otherval]<% values.each do |val| -%> Some stuff with <%= val %> <% end -%>

模板条件

<% if broadcast != "NONE" %> broadcast <%= broadcast %> <% end %>

模板变量:

#编写模板变量testvariable = template('/var/puppet/template/testvar')#未定义变量,检测变量生效情况<% if has_variable?("myvar") then %> myvar has <%= myvar %> value <% end %>#超范围变量<%= scope.lookupvar('apache::user') %>

八、节点管理

定义:puppet的每个客户端被称为节点,所有节点定义在site.pp文件中,可使用import()进行引用,因此服务器上线前需规范主机名的书写格式,在puppet0.25之后的版本可用正则匹配主机名

PUPPET配置进阶

# 1.定义通用目的节点node 'base' {    include ntp    include iptables    include zabbix_agent}node 'node1.magedu.com' inherits base { # 节点node1继承基础节点的类    include nginx}# 2.节点名称支持使用正则表达式node /^node[1234]\.lamp\.com$/ {}# 3.定义节点的配置文件规划:/etc/puppet/manifests/site.pp    import "nginx/*.pp" # 导入各类应用的节点定义文件    import "tomcat/*.pp"    import "varnish/*.pp"base.ppnginx/    node1.magedu.com.pp # 内部类继承于basetomcat/varnish/# 4.使用外部的节点分类器ENC使用yaml语法,PyYAMLldap: