设为首页 收藏本站
查看: 662|回复: 0

[经验分享] puppet基础(一)

[复制链接]

尚未签到

发表于 2018-8-2 10:09:27 | 显示全部楼层 |阅读模式
  puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。
  特点:
  (1)puppet的使用模型:
  单机环境运行
  master/agent环境运行
  (2)puppet的运行具有幂等性:
  也就是只要agent加入master,无论命令发送给agent执行多少次,其结果都是一样的。
  (3)puppet的运行基本原理:
  资源类型(resource):用来定义agent(模糊的去除了单机环境)最终需要完成的任务,注意:不是定义agent使用什么具体的命令来执行。比如定义用户增加、删除、其他属性的"user 资源类型"。安装服务软件的"package 资源类型"。传递配置文件的"file 资源类型"。启动、停止、重启服务的"service 资源类型"。以及执行自定义命令的"exec 资源类型"。等等。。。
  类(class):用来定义一组具有关联的、可以流程化执行的"资源类型的集合"。比如我们可以先定义"package 安装软件",接着定义"file 传递配置文件",最后定义"service 启动服务"。
  模块(moudle):包含了多个类文件的目录。模块是为了实现预定义配置信息的复用,将类组成了模块。可以运行在不同的节点上,这些模块可以自动判断agent node的不同。模块才是puppet的核心。
  master端在发送命令到agent端前,先将需要运行的指定的命令编译成catalog的格式,然后再发送给agent执行。这类似于tomcat或者变异PHP,需要在执行前需要先编译成为二进制格式。但是当agent的操作系统、版本号、甚至软件是标准或编译版本(nginx/tengine),nginx是正向代理还是反向代理的呢?facter这个软件给我们提供了尽可能多的信息,可以使用"facter -p"命令得到我们想要几乎全部信息。这也类似于ansible啊!好多类似!!!
  而master与agent之间的通信是基于SSL协议进行,所以必须使用FQDN(所以不能使用IP了)进行连接。但是具体的传输配置时通过XMLRPM(模糊的讲可以是xml文件)通过httpd服务进行通信,但是agent却不需要安装浏览器。
  所以具体执行过程如下:
  master[moudle{class(resource)}] ==>  master[使用FQDN得到agent的facter信息,选择合适class]  ==>  master[生成适合agent node的catalog]  ==>  agent[执行]
  puppet的工作流程:
  1、define:使用puppet语言定义资源的状态
  2、模拟:根据资源关系图,puppet可以模拟部署(无损运行测试代码)
  3、强制:比对客户端状态和定义的资源状态是否一致,自动强制执行
  4、report:通过puppet api,可以讲日志发送到第三方监控工具。
  puppet的抽象工作模型:
  第一层:configuration language
  配置语言层
  第二层:transactional layer
  事务层:管理具有依赖关系资源间的联动顺序
  第三层:resource abstraction layer
  资源抽象层,管理资源对象的,比如给具体的对象赋值。
  以上这些都是简单模糊的介绍,下面先从单机环境开始实操!
  资源清单(mainfest):
  资源清单包含了很多(可以执行的)资源类型或者class,这些文件都以".pp"结尾,所以模块就是包含了一堆".pp"文件的目录。
  资源申报:
  资源清单中"每一个"被定义的资源类型,也叫做资源申报。
  安装:
  2.6版本:太老,epel的默认提供
  2.7版本:兼容性较好
  3.x版本:引入新特性
  puppet使用ruby语言开发,而ruby又是一种解释型语言,所以puppet安装与平台无关,也就是noarch。
  puppt-2.7.23-el6.noarch.rpm
  agent端的服务,puppet所有的东西都在这里,而master端反而很小,可能会依赖于facter-1.7.3.1.el6.x86_64.rpm,epel中的老版本facter可以满足需求。
  如果是单机环境,就不需要启动agent了。
  puppt-dash-1.2.23-1.el6.noarch.rpm
  master上的gui访问接口
  puppet-server-2.7.23-1.el6.noarch.rpm
  master上的服务
  帮助信息的使用:
  puppet apply name.pp  :执行这个类或资源申报
  puppet apply -d -v name.pp:执行显示详细的调试信息
  puppet describe --help:查看如何使用describe帮助信息的
  puppet describe --list:列出所有资源类型及简要描述
  puppet describe resource_type:列出指定资源类型的详细帮助
  再插入一个"资源定义"(也叫资源申报)的简要语法:
resource_type {"resource_title":  
               这里后面必须有冒号,而且必须有引号,可以进行变量替换。
  
               所以双引号可以变量替换,而单引号不可以。
  
               一般title对用户而言就是name。
  
               而对文件而言,一般表示文件名称及路径。
  
        resource_attribute  =>  values,
  
               这里最后的","可有可无,一般都有。
  
               如果开头出现"#",则表示注释
  
}
  继续讲帮助信息:
# puppet describe package  
name  :需要安装的软件名字,比如nginx,这里的一般就是指resource_tile了,
  
ensure:"present"、"installed"都表示安装
  
        "absent"表示卸载
  
        "latest"安装最新版本
  
比如安装nginx的资源申报这可以这么定义:
  
package {"vsftpd":
  
    ensure  =>  "install",
  
}
  

  
# puppet apply vs.pp
  
notice: /Stage[main]//Package[vsftpd]/ensure: created  返回装态,以创建
  
notice: Finished catalog run in 9.12 seconds
  
        由于需要yum和编译catalog,所以时间较长。
# puppet describe service  
name  :同title
  
ensure:stop=false停止服务
  
        true=running开启服务
  
下面定义vsftpd服务的启动
  
service {"vsftpd":
  
    ensure => running,
  
}
  
# puppet apply vs.pp
  
notice: /Stage[main]//Service[vsftpd]/ensure: ensure changed 'stopped' to 'running'
# puppet describe file  
path   :一般和title同名,所以可以不指定
  
ensure :指定title的文件类型,值有link,directory,file,present,absent
  
         其中present会检查文件是否存在,不存在就会创建一个空文件。
  
         absent会删除文件或者目录,如果是目录需要指定recurse参数指定是否允许递归
  
target :如果ensure为link,那么这里就必须为link指定agent的源文件或目录
  
force  :该参数强制执行文件操作,当遇到"purge 子目录","用文件或者链接文件替换目录"、
  
         "使用ensure => absent参数删除目录"时,就需要用到该参数。
  
content:文件内容,由于很难进行格式控制,所以一般不用
  
source :指定要文件路径,这个文件会被传送到agent端的目标位置。也就是title
  
         也就是将source中的文件复制到title。
  
         可以指定多个,但是和content、target冲突。
  
         source => "puppet:///modules/ssh/etc/ssh/sshd_config" ,
  
         source => "/etc/passwd",
  
mode   :权限,如0644
  
owner  :属主
  
group  :属组
  
file {"/etc/vsftpd/vsftpd.conf":
  
    ensure => file,
  
    source => "/root/vsftpd.conf",
  
    mode   => 0644,
  
    owner  => root,
  
    group  => root,
  
}
在很多语言中及工具都会有允许我们执行shell脚本命令的工具,比如ansible,python、  
capistrano等等,puppet同样不例外:
  
# puppet describe exec
  
path   :定义环境变量
  
command:可以是命令,多条的话使用";"隔开,也可以是一个脚本。
  
creates:在agent运行脚本时,可以创建临时的文件或目录
  
user   :以哪个用户的身份去执行命令
  上面已经完整的定义了vsftpd从安装、启动、到传送自定义配置文件的过程,但是依然有很多问题等待解决:
  (1)当agent没有安装vsftpd,我们却传递了复制配置文件,然后重启的指令,怎么办?
  (2)我们如何使得在传递完配置文件后重启服务vsftpd呢?
  puppet早已想到上面的问题,这就是为什么不使用我们自己写的shell脚本去批量执行命令,因为puppet具有足够的统一性,防止每个人都使用不同风格脚本,因为一个很大脚本,写起来容易,维护起来难,而且如果作者一旦闪人,那么后面的人很难继续维护。而且puppet具有足够的稳定性。这里不多解释!
  对于问题(1),puppet中使用before、require定义资源间的依赖关系。比如在推送配置文件前一定要确定软件已经安装。
package {"vsftpd":  
    ensure  =>  "installed",
  
    before  =>  File["/etc/vsftpd/vsftpd.conf"],
  
    这里表示在推送配置文件之前,先安装vsftpd
  
}
  
file {"/etc/vsftpd/vsftpd.conf":
  
    ensure  => file,
  
    source  => "/root/vsftpd.conf",
  
#   require => Package["vsftpd"],
  
    这里表示要推送配置文件需要agent已经安装vsftpd,与before二选一即可
  
}
  
service {"vsftpd":
  
    ensure => running,
  
}
  当我们定义的服务是成流水线方式的往下走时,那么使用before、require就显的不是很直观了,所以puppet又有"->","~>":
  ->:用于定义次序链
  ~>:用于定义通知链
package {"vsftpd":  
    ensure  =>  "installed",
  
} ->
  
# -> 当安装完成后再推送配置文件
  
file {"/etc/vsftpd/vsftpd.conf":
  
    ensure => file,
  
    source => "/root/vsftpd.conf",
  
} ~>
  
# ~>当推送完配置文件就重启服务。
  
service {"vsftpd":
  
    ensure => running,
  
}
  

  
当然,"->"与"~>"也可以使用下面的方式进行更形象的定义,与上面的次序只能二选一:
  
Package["vsftpd"] -> File["/etc/vsftpd/vsftpd.conf"] ~> Service["vsftpd"]
  可以看到,当我们引用上一个类型的时候明显发生了变化:资源类型的第一个字母要大写,而且后面需要使用中括号。
  条条大路通罗马,这句话在软件中非常适用,也就是一个功能,可以通过多个途径达到目的。比如你在春节开车回家时,可以使用可乐瓶,也可以使用矿泉水瓶。而puppet的通知机制也有多种比如还有常用的notify,subscribe。
  notify   :在file中配置,表示推送完配置文件,我就会通知后面的service资源类型重启服务。
  subscribe:表示订阅一个信息,比如你订阅的杂志,只要一发新版,就会发快递给你。
  在service中定义,表示只要file资源发生改变,service就能收到其变化,自己也变化
package {"vsftpd":  
    ensure  =>  "installed",
  
}
  
file {"/etc/vsftpd/vsftpd.conf":
  
    ensure => file,
  
    source => "/root/vsftpd.conf",
  
    notify => Service['vsftpd'],
  
}
  
service {"vsftpd":
  
    ensure => running,
  
#   subscribe => File["/etc/vsftpd/vsftpd.conf"],
  
#   与notify的二选一即可
  
}
  puppet定义了内容后为了方便修改,使用了变量,但需要注意的是,这个变量时变态的:
  (1)变量必须以"$"开头,无论是定义,还是引用。
  (2)任何正常数据类型的值都可以定义在变量中,比如字符串、数值、布尔值、数组、hash。
  另外还有一个特殊的undef,表示变量为空值,即未被赋值。
  (3)每个变量都有2个名字,简短名称和长格式的完全限定名称。
  完全限定名称(FQN,不是FQDN)格式是"$scope::variable"。
  (4)使用FQN的原因是因为puppet的变量是由作用域的。就像bash shell中定义函数时使用local,表示只对此函数生效。但是puppet的本地变量通过FQN可以被其他的模块、class引用。
  (5)top scope(顶级作用域) :直接使用"$"表示,比如"$::abc"。
  node scope(节点作用域):只能在当前节点使用。
  使用变量时,只能直接使用当前作用域的变量、父作用域的变量还有顶级作用域的变量。
  不能直接使用父作用域内其他的子作用域的变量,也不能直接使用子作用域的变量。
  (6)puppet的2类独特变量:
  内置变量:master端、agent端
  facter -p变量:这里出现的变量都可以直接使用,比如"$operatingsystem".
  数据类型:
  上面提到了puppet变量支持的数据类型,所以这里得再提一下。
  (1)布尔型: true和false,不能加引号;
  if语句的测试条件和比较表达式都会返回布尔型值;
  另外,其它数据类型也可自动转换为布尔型,如空字符串为false等;
  (2)undef : 从未被声明的变量的值类型即为undef(即空值);
  也可手动为某变量赋予undef值,比如$ERR=undef,注意undef不要加引号。
  还比如先前定义过一个$abc="hello",后来不想使用了,可以使用$abc=undef
  (3)字符型: 非结构化的文本字符串,可以使用引号,也可以不用;
  单引号中的变量不会替换,而双引号中的能够进行变量替换;
  字符型值也支持使用转义符;
  (4)数值型: 可为整数或浮点数,不过,puppet只有在数值上下文才把数值当数值型对待,
  其它情况下一律以字符型处理;
  (5)数组  : 数组值为中括号“[]”中的以逗号分隔的项目列表,最后一个项目后面可以有逗号;
  数组中的元素可以为任意可用数据类型,包括hash或其它数组;
  数组索引为从0开始的整数,也可以使用负数索引;
  (6)hash  : 即为外键值数据类型,
  (a) 键和值之间使用"=>"分隔,键值对儿定义在“{}”中,彼此间以逗号分隔;
  其键为字符型数据,而值可以为puppet支持的任意数据类型
  (b) 访问hash类型的数据元素要使用"键"当作索引进行。
  比如定义{ key1 => hello, key2 => world },如果想引用key1,
  那么可以使用hash[key1]
  (7)正则表达式:属于puppet的“非标准”数据类型,不能直接赋值给变量,
  仅能用于有限的几个接受正则表达式的地方,即接受使用“=~”及“!~”匹配操作符的位置,
  通常包括case语句中的selector,以及节点名称匹配的位置;
  它们不能传递给函数或用于资源属性的定义;
  puppet中的正则表达式支持使用(?<ENABLED OPTION>:<SUBPATTERN>)和
  (?-<DISABLED OPTION>:<SUBPATTERN>)两个特殊的符号。
  例如下面的示例表示做正则表达式匹配时启用选项“i”(忽略字符大小写),
  但不支持使用“m”(m表示把.当作换行符)和“x”(忽略模式中的空白字符和注释)。
  而使用"-"表示不使用那个标识。
  一般这3个都要使用表示"忽略大小写,而且把点号当做换行符,
  而且忽略模式中的空白字符和注释",但是一般不使用m,所以就加上了-m
  由于puppet的正则表示式比较另类,不好理解,所以我们对比bash的正则,比如替换操作中:
/^(CentOS|RedHat)/linux/ig  

  
^(CentOS|RedHat)查找标准,也是查找模式
  
linux是替换后的串
  
ig叫标识
$packages = $operatingsystem ? {  
       /(?i-mx:ubuntu|debian)/        => 'apache2',
  
       /(?i-mx:centos|fedora|redhat)/ => 'httpd',
  
}
  

  
对比bash正则,这里在查找时,首先来个小括号并在里面先写一个问好"(?)",
  
然后再在里面使用puppet自己的"标识符imx",在用":"隔开,接着就开始写查找内容了。
  
这里没有写替换。
  

  
最后的意思是:看看$operatingsystem中的内容符合那个条件,如果匹配第一个条件,
  
           那么$packages就等于apache2
  

  
下面是具体的例子
  
# cat web.pp
  
$package = $operatingsystem ? {
  
      /(?i-mx:^(centos|fedora|redhat))/ => 'httpd',
  
      /(?i-mx:^(debian|ubuntu))/    => 'apache2',
  
}
  

  
notify {'tixing':
  
  message   => "Install $package"
  
}
  
运行:
  
# puppet apply web.pp
  
notice: Install httpd  这里就是显示的内容
  
notice: /Stage[main]//Notify[tixing]/message: defined 'message' as
  
'Install httpd'
  
notice: Finished catalog run in 0.02 seconds
  终于讲完一堆变量了,那么也可以利用变量进行条件判断了!
  if条件判断:
单分支if:  
if CONDITION {
  
    statement
  
    ...
  
}
  

  
双分支if:
  
if CONDITION {
  
    statement
  
    ...
  
} else {       #注意这里else前面也需要"}"
  
    statement
  
    ...
  
}
  

  
多分枝if:
  
if CONDITION {
  
    statement
  
    ...
  
}
  
elsif CONDITION {  #注意这里是elsif
  
    statement
  
    ...
  
}
  
else {
  
    statement
  
    ...
  
}
  

  
if语句中CONDITION(S)如何写呢?
  
    这个CONDITION(S)的结果肯定是一个布尔值,也就是结果不是1,就是0。
  
    但是这个内容可以是多种多样的的:
  
        (1)变量
  
        (2)表达式,比如可以是and/or/not的逻辑运算表达式
  
        (3)函数,但是必须有返回值
  
    表达式中能够使用的比较符号有:
  
        ==  !=  <  >  =~   !~  in
  

  
简单例子:
  
如果$test值大于30就显示"I am success!"
  
# cat test1.pp
  
$test=100
  
if $test > 30 {
  
  notice("I am success!")
  
} else {
  
  notice("I am loser!")
  
}
  
# puppet apply test1.pp
  
notice: Scope(Class[main]): I am sucess!
  

  
使用if判断操作系统类型:
  
判断facter -p中$operatingsystem的值符合那种条件,
  
如果符合centos或者rhel,就安装httpd这个软件
  
如果符合ubuntu就安装Apache2这个软件,
  
之所以需要判断,是因为同一种软件,在不同的操作系统上名字不一样。
  
# cat webserver1.pp
  
if $operatingsystem =~ /(?i-mx:^(CentOS|RedHat))/ {
  $webserver="httpd"
  
}
  
elsif $operatingsystem =~ /(?i-mx:^(debian|ubuntu))/ {
  $webserver="apache2"
  
}
  
else {
  $webserver=undef
  notice("unknown OS")
  
}
  

  
package {"$webserver":
  ensure => installed,
  
}
  

  
# puppet apply webserver1.pp
  
notice: /Stage[main]//Package[httpd]/ensure: created
  
这里如何httpd,就安装了。
case表达式  
case CONTROL_EXPRESS {
  
    case1,...:  {statement...}
  
    case2,...:  {statement...}
  
    ...   ...
  
      default:  {statement...}
  
}
  

  
在bash shell中case1,case2,...可以使用多种变化的形式,puppet也支持:
  
(1)纯粹直接的字符(a literval value)
  
(2)变量
  
(3)具有返回值的函数调用
  
(4)正则表达式
  
(5)其他不常用条件!!!
  

  
# cat webserver2.pp
  
case $operatingsystem {
  /^(debian|ubuntu)$/: { $webserver="apache2" }
  /^(RedHat|CentOS)$/: { $webserver="httpd" }
  default:     { $webserver="vsftpd" }
  
}
  

  
package {"$webserver":
  ensure => installed,
  
}
  

  
# puppet apply webserver2.pp
  
notice: /Stage[main]//Package[httpd]/ensure: created
  
其实,case的statement可以直接执行一个动作,比如notice
  

  
case与selector还是有区别的:
  上面说的都是单个的"资源申报"如何定义的,可以直接执行。但是为了使得各种"资源申报"更具有结构化,我们就将具有关联关系的"资源申报"组织在了一起,也就是类(class)。
class的定义语法:  
class class_name {
  
    ...resoure_type...
  
}
  
class_name只能以小写字母开头,可以包含小写字母、数字、和下划线
  
另外,从这里开始就开始使用FQN来访问变量了。
  

  

  

  
直接的方式是直接将上面提到内容复制到里面:
  
# cat vsftpd.pp
  
class vsftpd {
  
    package {"vsftpd":
  
        ensure  =>  "installed",
  
    }
  
    file {"/etc/vsftpd/vsftpd.conf":
  
        ensure => file,
  
        source => "/root/vsftpd.conf",
  
        notify => Service['vsftpd'],
  
    }
  
    service {"vsftpd":
  
        ensure => running,
  
    }
  
}
  

  
# puppet apply vsftpd.pp  -v
  
返回值为空,
  
在bash中定义函数时,函数内的命令如果单独提出来也是可以执行的,
  
而如果只是定义了函数,后面并没有调用此函数,那么函数内的命令根本不会执行
  

  
而puppet的class一样,如果只是定义class,而不调用,其中的"资源申报"也不会执行了
  
但是class的调用在puppet中叫做"class的声明"
  

  
"类的声明"有2中方式:
  
include  class_name 不能参数参数
  
class {'class_name':} 作用同上
  
        当上面的class是用来定义安装nginx时,那么nginx也会有很多变种
  
        比如tengine,如果我们想传递tengine到里面,那么就可以安装
  
        如果yum源中没有tengine那么,没办法演示效果。
  
        在centos5.7中base中mysql的版本有多个,比如mysql51,mysql55
  
# yum list mysql*
  
mysql.x86_64                   5.0.95-5.el5_9      base
  
mysql-server.x86_64            5.0.95-5.el5_9      base
  
mysql51.x86_64                 1-9.el5             base
  
mysql51-mysql-server.x86_64    5.1.70-1.el5        base
  
mysql55.x86_64                 1-12.el5            base
  
mysql55-mysql-server.x86_64    5.5.40-2.el5        update
  

  
先演示include:
  
直接在上面的类后面添加"include vsftpd"或者"class {'vsftpd':}"。
  
# puppet apply vsftpd.pp
  
notice: /Stage[main]/Vsftpd/Package[vsftpd]/ensure: created
  
notice: /Stage[main]/Vsftpd/File[/etc/vsftpd/vsftpd.conf]/content:
  
content changed '{md5}0a5b80d33d6b0f90c357f250f202749a' to
  
'{md5}c44596e3ee488523646739704ef0834f'
  
notice: /Stage[main]/Vsftpd/Service[vsftpd]/ensure: ensure changed
  
'stopped' to 'running'
  

  
声明带参数的类,那么类在定义的时候也需要加上才行。所以类的定义格式稍有改动:
  
    也就是在在class_name后添加一个小括号"()",里面就是自己要定义的参数,
  
    如果有多个参数需要用逗号分隔。而且参数还有可以默认值,也就是后面的值
  
clas class_name ($bianliang1="zhi1",$bianliang2="zhi2") {
  
    ...puppet resoure_type...
  
}
  

  
在声明类的时候则是这个样子:
  
class {"class_name":
  
    bianliang1 => "zhi3",
  
    bianliang2 => "zhi4",
  
}
  
注意:这里在给bailiang1等赋值时不能再加"$",因为这里表示的不是变量,而是属性。
  

  
比如我们定义在centos5.7中安装mysql5.5(5.7系统直接yum安装puppet即时2.7.5):
  
# cat mysql.pp
  
class mysql_install ($ver="mysql55-mysql-server" ) {
  package {"$ver":
  ensure => "installed",
  notify => Service["$ver"],
  }
  service {"$ver":
  ensure => running,
  }
  
}
  

  
class {"mysql_install":
  ver => "mysql55-mysql-server"
  
}
  

  
运行:
  

  
# puppet apply mysql.pp
  
notice: /Stage[main]/Mysql_install/Package[mysql55-mysql-server]/
  
ensure: created
  
err: /Stage[main]/Mysql_install/Service[mysql55-mysql-server]/
  
ensure:change from stopped to running failed: Could not start
  
Service[mysql55-mysql-server]: Execution of '/sbin/service
  
mysql55-mysql-server start' returned 1:  at /bak/mysql.pp:8
  
notice: /Stage[main]/Mysql_install/Service[mysql55-mysql-server]:
  
Triggered 'refresh' from 1 events
  
notice: Finished catalog run in 378.77 seconds
  

  
将上面的class声明重新定义:
  
class {"mysql_install":
  ver => "mysql51-mysql-server"
  
}
  

  
# puppet apply mysql.pp
  
notice: /Stage[main]/Mysql_install/Package[mysql51-mysql-server]
  
/ensure: created
  
err: /Stage[main]/Mysql_install/Service[mysql51-mysql-server]/
  
ensure:change from stopped to running failed: Could not start
  
Service[mysql51-mysql-server]: Execution of '/sbin/service
  
mysql51-mysql-server start' returned 1:  at /bak/mysql.pp:8
  
notice: /Stage[main]/Mysql_install/Service[mysql51-mysql-server]:
  
Triggered 'refresh' from 1 events
  类的继承:
上面带参数的类的声明解决了我们需要安装同一个性质的软件名称不同、软件版本不同的问题。  
但是如果我们已经安装好了某一类软件,比如nginx,但是我们却需要其工作在不同状态,
  
比如一个是webserver提供web服务,另一个是反向代理proxy。这就使的puppet在配置时,
  
具有更加灵活的特性,这就有了类的继承。下面是列子和定义方法,以及声明方法:
  

  
# 首先定义一个基础安装类
  
class nginx {
  
    package {"nginx":
  
        ensure => installed,
  
    }
  
}
  

  
# 接着定义一个可以推送web服务的配置文件,名称为webserver的继承类,这里就是定义方法:
  
class nginx::webserver inherits nginx {
  
    file {"/etc/nginx/nginx.conf":
  
        ensure  => file,
  
        mode    => 0644,
  
        user    => root,
  
        group   => root,
  
        source  => "/root/nginx_server.conf",
  
        require => Package["nginx"],
  
    }
  
    service {"nginx":
  
        ensure    => running,
  
        subscribe => File["/etc/nginx/nginx.conf"],
  
    }
  
}
  
# 下面是推送反向代理的配置文件,并重启服务的名称为proxy的继承类:
  
class nginx::proxy inherits nginx {
  
    file {"/etc/nginx/nginx.conf":
  
        ensure  => file,
  
        mode    => 0644,
  
        user    => root,
  
        group   => root,
  
        source  => "/root/nginx_proxy.conf",
  
        require => Package["nginx"],
  
    }
  
    service {"nginx":
  
        ensure    => running,
  
        subscribe => File["/etc/nginx/nginx.conf"]
  
    }
  
}
  

  
include nginx  # 这样声明只会执行基础安装类
  
include nginx::proxy  # 这样才会执行反向代理的类

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-545174-1-1.html 上篇帖子: CentOS6.6+Puppet3.7.4分布式部署Nagios监控系统 下篇帖子: 自动化配置和部署工具--puppet(1)--什么是puppet
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表