Puppet基础之单机模型

来源:互联网 发布:微信分享淘宝优惠券 编辑:程序博客网 时间:2024/05/29 10:04

Puppet基础之单机模型

    puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。puppet的工作模型:    apply:单机模型:手动应用清单;    master/agent:由agent周期性地向Master请求清单并自动应用于本地;安装:]# Yum -y install puppet facterapply单机模型:程序环境:    配置文件:/etc/puppet/puppet.conf     主程序:/usr/bin/puppet使用方法: puppet <subcommand> [options] <action> [options]<subcommand>:help:显示帮助信息              Apply:本地使用清单              Describe:显示有关资源类型的帮助              agent:agent daemon              master:master daemon              module:安装,搜索,查看模块apply使用方法:puppet apply  [-d|--debug] [-v|--verbose] [-e|--execute] [--noop] <file>puppet资源:    具有类似属性的组件,例如package、service、file可抽象为资源,    支持资源之间的关系配置是puppet的关键特性之一, 一个资源的变更可以对另一个资源产生一个动作。    例如 /etc/apache.conf这个资源有改动,可以让/etc/init.d/apache 这个资源 reload一下,    假如一个资源依赖另一个资源,那么puppet会优先配置被依赖的资源,因此如果你的配置文件没有准备好,对应的服务是不会先启动的。puppet describe:打印有关Puppet资源类型,提供程序和元参数的帮助puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type]    -l:列出所有资源类型;    -s:显示指定类型的简要帮助信息;    -m:显示指定类型的元参数,一般与-s一同使用;Exp:puppet describe –l 列出puppet的所有资源类型向资源类型的属性赋值来实现,可称为资源类型实例化;定义了资源实例的文件即清单,如下:type {'title':    attribute1  => value1,    atrribute2  => value2,    ……}注意:type必须使用小写字符;title是一个字符串,在同一类型中必须惟一;资源属性中的三个特殊属性:    Namevar, 可简称为name;    ensure:资源的目标状态;     Provider:指明资源的管理接口;常用的8种资源类型:puppet describe –l 可列出所有资源类型User、group、file、service、package、exec、cron、notify1、  User属性:name:用户名;      uid: UID;      gid:基本组ID;      groups:附加组,不能包含基本组;      comment:注释;       expiry:过期时间 ;      home:家目录;       shell:默认shell类型;      system:是否为系统用户 ;      ensure:present/absent;      password:加密后的密码串;示例:新建编辑user.pp文件
user{'useradd':            name => 'puppetuser',            uid => 10010,            comment => 'test puppet user',            home => '/home/testpuppet',            ensure => present,    }    ]# puppet apply -v -d --noop user.pp 提前测试,没有问题后,直接应用清单    ]# puppet apply user.pp    ]# cat /etc/passwd | grep puppetuser    puppetuser:x:10010:10010:test puppet user:/home/testpuppet:/bin/bash
2、  Group属性:name:组名;      gid:GID;      system:是否为系统组,true OR false;      ensure:目标状态,present/absent;      members:成员用户;示例:新建group.pp文件
group{'gtest':    name => 'testpp',    gid => 10011,    system => false,    ensure => present,    members => 'mysql,redis',    }
测试,应用清单过程参考user操作,以下不再赘述,如有差异会做注释。3、  File属性:ensure: `present`, `absent`, `file`, `directory`, and `link`.    file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;    link:类型为符号链接文件,必须由target属性指明其链接的目标文件;    directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;      absent: 表示删除文件      path:文件路径;      source:源文件;      content:文件内容;      target:符号链接的目标文件;       owner:属主      group:属组      mode:权限;      atime/ctime/mtime:时间戳;      recurse : 是否递归 目录有效示例:
file{'filet':            path => '/tmp/testpuppetfile',            source => '/etc/fstab',            ensure => present,            owner => 'mysql',            group => 'testpp',            mode => 123,}]# ls -l /tmp/testpuppetfile ---x-w--wx 1 mysql testpp 465 Jul 19 22:14 /tmp/testpuppetfile
4、  Service属性:ensure: 服务状态stopped---false,running---true      enable:是否开机启动 `true`, `false`, `manual`.      name:服务名称      path: 脚本的搜索路径,默认为/etc/init.d/;      hasrestart:true|false, 指出管理脚本是否支持restart参数,如果不支持,就用stop和start实现restart效果.      hasstatus:true|false, 指出管理脚本是否支持status参数,puppet用status参数来判断服务是否已经在运行了,如果不支持status参数,puppet利用查找运行进程列表里面是否有服务名来判断服务是否在运行.      start:手动定义启动命令,测试时可以touch文件;      stop:同上      status:同上          restart:同上. 通常用于定义reload操作,例如nginx –s reload;
示例1:service{'mysql':    name => 'mariadb.service',    ensure => running,    enable => true,}
示例2:service{'nginx':    name => 'nginx.service',    ensure => running,    start => 'systemctl start nginx.service',#自定义启动命令, }
5、  Package属性:ensure:installed, present, latest, absent      name:包名;          source:本地程序包使用此选项,例如rpm或dpkg
示例1:package{'web':    name => 'nginx',    ensure => installed,}
示例2$web = $operatingsystem ? { #根据系统版本决定安装那款服务         CentOS => httpd,         default => apache2,}package { $web: #获取服务名称,进行安装          ensure => installed,          alias  => httpd,}
6、  Exec属性:command (*namevar*):要运行的命令,       cwd:在哪个工作目录执行命令      creates:此路径的文件不存在时,command方才执行;      user/group:运行命令的用户身份;      path:命令执行的搜索路径,没有指定路径,命令必须使用绝对路径.      onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;      unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;      refresh:重新执行当前command的替代命令;          refreshonly:仅接收到订阅的资源的通知时方才运行;注意:要执行的命令必须要有幂等性,可运行多次不会对系统造成损害
示例1:exec{'comm':    command => 'df',    path => '/usr/bin/',    user => 'root',    onlyif => 'whoami', #此命令执行ok,才执行command的命令}
示例2:exec{'comm':    command => 'touch /tmp/commtest',    path => '/usr/bin/',# command => /usr/bin/touch /tmp/comment    creates => '/tmp/commtest',#文件不存在时,才执行command命令}
7、  Cron属性:command:要执行的任务;      ensure:present/absent;添加/删除      hour:时      minute:分      monthday: 日      month:月      weekday:周      user:以哪个用户的身份运行命令      target:添加为哪个用户的任务          name:cron job的名称;
示例112小时更新一次时间cron{'ntp':    command => 'ntpdate 172.16.0.1',    ensure => present,    hour => '*/12',    user => 'root',    name => 'time update',}
示例2:清除示例的任务计划cron{'ntp':    command => 'ntpdate 172.16.0.1',    ensure => absent,    hour => '*/12',    user => 'root',    name => 'time update',}
示例3:每周5备份一下脚本目录cron{'copyfile':    command => 'tar -Jvcf /data/script.tar.xz /root/script',    weekday => 5,    ensure => present,    target => 'smartwy',    name => 'copy script',    user => 'root',} #查看结果需要登录smartwy执行crontab –l 查看任务计划
8、  Notify属性: message:信息内容      name:信息名称
示例:notify{'test':    message => 'test notify message !',    name =>  'notify message',}
关系元参数:before/require,通知元参数:notify/subscribe资源引用:    Type['title']        类型的首字母必须大写;1、  Before属于关系元参数使用方法:A before B: A被B依赖,定义在A资源中;    typy{A:        ...        before  => Type['B'],        ...        }只有应用完资源A,资源B才可被应用,否则独立应用资源B会出先error示例:停nginx服务,卸载服务
service{'nginx':        name => 'nginx.service',        ensure => stopped,                stop => 'systemctl stop nginx',                before => Package['nginxp'],#先执行service,后执行package}package{'nginxp':        name => 'nginx',        ensure => purged,}
也可 Service[‘nginx’] ->Package[‘nginxp’] 指定应用顺序2、  Require属于关系元参数使用方法:B require A: B依赖于A,定义在B资源中;    typy{B:        ...        require => Type['A'],        ...        }只有应用完资源A,资源B才可被应用,否则独立应用资源B会出先error
示例:安装服务,启动服务service{'nginx':        name => 'nginx.service',        ensure => running,        require => Package['nginxp'],#先执行package,后执行service}package{'nginxp':        name => 'nginx',        ensure => latest,}# Package[‘nginxp’] -> Service[‘nginx’]
3、  Notify属于通知元参数A notify B:A被B依赖,且A发生改变后会通知B;type{A        ...        notify => Type['B'],        ...    }
示例:安装nginx,提供配置文件,启动服务service{'nginx':            name => 'nginx',            ensure => running,}file{'copy':            path => '/etc/nginx/nginx.conf',            source => '/root/puppet/nginx.conf',            ensure => file,            notify => Service['nginx'],}package{'nginxinstall':            name => 'nginx',            ensure => installed,            notify => File['copy'],}# Package[‘nginxinstall’] -> File[‘copy’] -> Service[‘nginx’]
4、  subscribe属于通知元参数B subscribe A:B依赖于A,且B监控A,A发生变化,B也会应用        tpye{B                ...                subscribe => Type['A'],                ...        }
示例service{'nginx':    name => 'nginx',    ensure => running,    subscribe => File['copy'],}file{'copy':    path => '/etc/nginx/nginx.conf',    source => '/root/puppet/nginx.conf',    ensure => file,    subscribe => Package['nginxinstall'],}package{'nginxinstall':    name => 'nginx',    ensure => installed,} # Package[‘nginxinstall’] -> File[‘copy’] -> Service[‘nginx’]
Puppet 变量:定义方法:$variable_name=value数据类型:        字符型:引号可有可无;但单引号为强引用,双引号为弱引用;        数值型:默认均识别为字符串,仅在数值上下文才以数值对待;        数组:[]中以逗号分隔元素列表;        布尔型值:true, false;        hash:{}中以逗号分隔k/v数据列表; 键为字符型,值为任意puppet支持的类型;{ 'mon' => 'Monday', 'tue' => 'Tuesday', };        undef:未定义 ;正则表达式:        (?<ENABLED OPTION>:<PATTERN>)        (?-<DISABLED OPTION>:<PATTERN>)        OPTIONS:                i:忽略字符大小写;                m:把.当换行符;                x:忽略<PATTERN>中的空白字符        常用:(?i-mx:PATTERN)忽略大小写,不把.当换行符,不忽略<PATTERN>中的空白字符        不能赋值给变量 ,仅能用在接受=~或!~操作符的位置;Puppet流程控制语句:If语句:    If condition {        ....    }else {        .....    }Condition方式:1、  变量2、  比较表达式3、  又返回值的函数
示例1if $osfamily =~ /(?i-mx:debian)/ {        $webserver = 'apache2' #如果系统版本为debian系列,将apache2赋值给变量} else {        $webserver = 'httpd' #如果系统版本不是debian系列,将httpd赋值给变量}package{"$webserver":        ensure  => installed,        before  => [ File['httpd.conf'], Service['httpd'] ],#File和Service依赖package资源}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有变化,service也随变化}
Case语句:使用方法:case CONTROL_EXPRESSION {    case1: { ... }    case2: { ... }        ...    default: { ... }}    CONTROL_EXPRESSION:        (1) 变量        (2) 表达式         (3) 有返回值的函数    各case的给定方式:        (1) 直接字串;        (2) 变量         (3) 有返回值的函数        (4) 正则表达式模式;        (5) default

示例:

case $osfamily {    "RedHat": { $webserver='httpd' } #系统版本为RedHat将$webserver赋值为'httpd'    /(?i-mx:debian)/: { $webserver='apache2' } #系统版本匹配debian将$webserver赋值为apache2    default: { $webserver='httpd' } #其于版本,将$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语句:使用方法:CONTROL_VARIABLE ? {            case1 => value1,            case2 => value2,            ...            default => valueN,        }            CONTROL_VARIABLE的给定方法:                (1) 变量                (2) 有返回值的函数            各case的给定方式:                (1) 直接字串;                (2) 变量                 (3) 有返回值的函数                (4) 正则表达式模式;                (5) default                 注意:不能使用列表格式;但可以是其它的selecor;
示例1$pkgname = $operatingsystem ? {        /(?i-mx:(ubuntu|debian))/  =>  'apache2',# 匹配系统版本,则将apache2赋值给$pkgname变量        /(?i-mx:(redhat|fedora|centos))/  =>  'httpd', # 匹配系统版本,则将httpd赋值给$pkgname变量        default => 'httpd', # 不匹配以上两种模式,则将httpd赋值给$pkgname变量,冗余指令    }    package{"$pkgname": #安装对应web服务        ensure  => installed,    }
示例2$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类:可以把多个相关的资源定义在一起,组成一个类.可以在其他的代码段include这个类.puppet还支持有限制的类的继承,作用就是在子类里面的属性可以覆盖父类里面的属性.语法格式:class NAME {            ...puppet code...        }        class NAME(parameter1, parameter2) {            ...puppet code...        }类代码只有声明后才会执行,调用方式:        (1) include CLASS_NAME1, CLASS_NAME2, ...        (2) class{'CLASS_NAME':              attribute => value,           } #给CLASS_NAME传递参数
示例1class apache2 {    $webpkg = $operatingsystem ? { #selector语句,匹配模式的value赋值给$webpkg变量        /(?i-mx:(centos|redhat|fedora))/  => 'httpd',        /(?i-mx:(ubuntu|debian))/       => 'apache2',        default => 'httpd',        }    package{"$webpkg": #安装程序包        ensure  => installed,    }    file{'/etc/httpd/conf/httpd.conf': #提供配置文件        ensure  => file,        owner   => root,        group   => root,        source  => '/tmp/httpd.conf',        require => Package["$webpkg"],        notify  => Service['httpd'],    }    service{'httpd': #启动服务,开机启动        ensure  => running,        enable  => true,    }}include apache2  #调用apache2这个类
示例2class dbserver($pkgname) {        package{"$pkgname": # 安装相应程序包                ensure  => installed,        }        $ser = $pkgname ? { #使用selector转换变量值,因为$pkgname的值为包名而不是服务名称,                'mariadb-server' => 'mariadb.service',                'mysqld-server' => 'mysqld.service',        }        service{"$ser": #启动服务,开机启动                ensure  => running,                # start => 'systemctl start mariadb.service', 如果不转换变量值,此条指令需执行,且下面enable=> true参数存在问题                enable => true,        }}if $operatingsystem == "CentOS" { #判断系统版本,确定安装那款程序包        $dbpkg = $operatingsystemmajrelease ? {                7 => 'mariadb-server',                default => 'mysqld-server',        }}class{'dbserver':        pkgname => $dbpkg, # 调用类给类传递实参}
从上向下执行,因为最上面为类的定义,并没有声明调用,所以真正执行顺序为:类声明if判断调用类传参类执行类的继承方式:使用方法:class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {                ...puppet code...            }
示例:一个父类,俩个子类,调用一个子类class nginx { #父类nginx        package{'nginx':                ensure  => installed,        }               service{'nginx':                ensure  => running,                enable  => true,                restart => '/usr/sbin/nginx -s reload',        }       }       class nginx::web inherits nginx {  #子类nginx::web        Service['nginx'] {                subscribe => File['ngx-web.conf'],        }               file{'ngx-web.conf':                path    => '/etc/nginx/conf.d/ngx-web.conf',                ensure  => file,                source  => '/root/manifests/ngx-web.conf',        }       }       class nginx::proxy inherits nginx { #子类nginx::proxy        Service['nginx'] { #在父类的service[‘nginx’]资源添加一条指令,file应用后,此service应用                subscribe => File['ngx-proxy.conf'],        }               file{'ngx-proxy.conf': #配置nginx为反向代理服务器                path    => '/etc/nginx/conf.d/ngx-proxy.conf',                ensure  => file,                source  => '/root/manifests/ngx-proxy.conf',        }       }       include nginx::proxy #调用子类nginx::proxy,执行流程为:父类的package-->子类的file-->子类新增父类service参数的service。
在子类中为父类的资源新增属性或覆盖指定的属性的值:Type的首字母必须大写            Type['title'] {                attribute1 => value,                ...            }在子类中为父类的资源的某属性增加新值:Type的首字母必须大写            Type['title'] {                attribute1 +> value,                ...            }Puppet模版:模版语言:erb,embedded ruby使用方法:    file{'title':        ensure  => file,        content => template('/PATH/TO/ERB_FILE'),    }
示例:一个父类,一个子类class nginx {         package{'nginx':                ensure  => installed,        }               service{'nginx':                ensure  => running,                enable  => true,                require => Package['nginx'],#依赖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.conf.erb'),#一般模版文件使用.erb结尾,将模版内容的相关‘指令’替换成系统对应的变量值或语句结果等,再替换对应的path设定的文件                require  => Package['nginx'],        }        Service['nginx'] {                subscribe => [ File['ngx-web.conf'], File['nginx.conf'] ],        }       }       include nginx::web
erb语法:ServerName <%= @fqdn %> #插入变量fqdn的值       ServerAlias <%= @hostname %>#插入变量hostname的值这里不会详细讲解erb语法,可访问:https://docs.puppet.com/puppet/latest/reference/lang_template_erb.htmlPuppet模块:    模块就是一个按约定的、预定义的结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范。puppet会在配置的路径下查找所需要的模块;puppet config print modulepath    MODULES_NAME:            manifests/                init.pp            files/            templates/            lib/            spec/            tests/模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main"和"settings“;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、puppet 3.8及以后的版本中,资源清单文件的文件名要与文件类名保持一致,例如某子类名为“base_class::child_class”,其文件名应该为child_class.pp;2、无需再资源清单文件中使用import语句;3、manifests目录下可存在多个清单文件,每个清单文件包含一个类,其文件名同类名示例;制作nginx模块,提供配置文件(反代配置文件)、模版目录结构如下:nginx/├── files│     └── ngx_proxy.conf├── lib├── manifests│     └── init.pp├── spec├── templates│     └── nginx.conf.erb└── testsInit.pp文件内容如下:
class nginx {    package{'nginx-server':        name => 'nginx',        ensure => installed,    }    file{'conf-file':        path => '/etc/nginx/conf.d/ngx_proxy.conf',        ensure => file,        source => 'puppet:///modules/nginx/ngx_proxy.conf',        require => Package['nginx-server'],    }    file{'conf-erb':        path => '/etc/nginx/nginx.conf',        ensure => file,        content => template('nginx/nginx.conf.erb'),    }    service{'start':        name => 'nginx',        ensure => running,        require => [File['conf-file'],File['conf-erb']],    }}
Nginx.conf.erb文件修改如下(至修改了下面一条指令,其它没有变更)
worker_processes <%= @processorcount %>;#将nginx进程数量设置为运行服务系统的cpu核心数
代理文件配置如下
server {        listen 80;         root /web;        location / {            proxy_pass http://172.16.252.140:80;     }}
基础介绍完毕。下一篇为puppet-master-agent,    程序包下载路径:        https://yum.puppetlabs.com/    官方文档:        https://docs.puppet.com/puppet/3/reference/    内建函数:        https://docs.puppet.com/puppet/3/reference/function.html    配置参数列表:        https://docs.puppet.com/puppet/3/reference/configuration.html
原创粉丝点击