puppet采用C/S星状的结构,全部的客户端和一个或几个服务器交互。每一个客户端周期的(默认半个小时)向服务器发送请求,得到其最新的配置信息,保证和该配置信息同步。每一个puppet客户端每半小时(能够设置)链接一次服务器端, 下载最新的配置文件,而且严格按照配置文件来配置客户端. 配置完成之后,puppet客户端能够反馈给服务器端一个消息. 若是出错,也会给服务器端反馈一个消息.html
~]# puppet descript [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type] //使用查询 -l:列出全部资源类型 -s:显示指定类型的简要帮助信息 -m:显示指定类型的元参数 Usage: puppet [subcommand] [options] [action] [options]
package {'nginx': name => 'nginx', ensure => latest, # before => Service['nginx'] } service {'nginx': name => 'nginx', enable => true, require => Package['nginx'] } 须要事先定义package资源,并且该资源必须是服务所依赖的资源,在表示须要依赖上面的package才能运行service.
在引用时,资源的首字母必须大写,如:java
Type['title'] 如 Service['nginx']
file {'/tmp/test': name => '/tmp/test', ensure => file, content => 'Hello World', # notify => Exec['monitor'] } exec {'monitor': name => 'monitor', command => 'echo "/tmp/test has changed" >> /tmp/change', subscribe => File['/tmp/test'], refreshonly => true, path => '/bin:/sbin:/usr/bin' } 每一次应用都会触发Exec['monitor']此处不写refresh,其也是能够执行的file每被应用一次,其就会往monitor中写入相应的文件。若加入此句refreshonly=true,其会只在file资源改变时写入内容(触发exec)
package {'nginx': name => 'nginx', ensure => latest, } -> file {'/etc/nginx/nginx.conf': path => '/etc/nginx/nginx.conf', source => '/root/puppet/nginx.conf', } -> service {'nginx': ensure => true, enable => true, } Package['nginx'] -> File['/etc/nginx/nginx.conf'] ~> Service['nginx'] ->:用于定义次序链,即nginx安装以后才会处理配置文件~>:用户定义通知链,配置文件处理好了以后会通知服务也能够在定义资源时直接定义
可用今生成密码:openssl passwd -1 -salt `openssl rand -hex 4`node
group {'mysqll': ensure => present, gid => 1200, } -> user {'ming': name => "ming", ensure => present, uid => 1200, groups => 'mysqll', home => "/home/dai", password => '$1$ce1a71ce$c05P/h2f9bwImXX0WILlU0', shell => "/bin/bash", comment => "You is my creat", }
package { 'nginx': provider => yum, name => 'nginx', ensure => latest }
file {'/test': ensure => file, content => "This is test", owner => 'ming', group => 'mysqll', mode => 777, } file {'/directory': ensure => directory, } file {'/test.link': ensure => link, target => '/test' } file { "jdk-8u25-linux-x64.rpm": ensure => file, path => '/tmp/jdk-8u25-linux-x64.rpm', source => 'puppet:///modules/jdk8/jdk-8u25-linux-x64.rpm'; "java.sh": ensure => file, path => '/etc/profile.d/java.sh', source => 'puppet:///modules/jdk8/java.sh'; } 建立文件建立目录建立连接可传送多个文件,可分开定义,但最后一个条件得是;结尾
exec {'clean log': command => "/bin/bash cleanning.sh", cwd => "/usr/local/cripts", provider => shell, logoutput => true, onlyif => "/usr/bin/test `du /var/log/message | cut -f1 -gt 102400`" } 执行命令的内容指定命令在哪一个目录下执行为true时,表示无论命令执行成功与否都输出日志onlyif参数控制了命令执行的条件,如上只有当message文件大小超过100M时,才执行command的参数指定的cleanning.sh脚本
未添加控制参数的exec资源将变得很是危险,由于它会在客户端每次从服务端更新资源时被执行。须要交互的命令一搬都不能执行成功mysql
cron{'timesync': command => '/usr/sbin/ntpdate 10.1.0.1 &> /dev/null', ensure => present, minute => '*/3', user => 'root', }
$variable_name=value:引用变量时能够直接 使用或者使用双引号linux
做用域:nginx
引用路径:web
变量的赋值符号:正则表达式
(?i-mx:PATTERN),不能赋值给变量,仅能用在接受=~或!~操做符的位置。-mx就是表示不使用m和xsql
if CONDITION { .... } else { .... } ex: if $osfamily =~ /(?i-mx:(debian|ubuntu))/ { $webserver = 'apache2' } else { $webserver = 'httpd' } package {"$webserver": ensure => latest, } file {'httpd.conf': path => '/etc/httpd/conf/httpd.conf', source => '/root/puppet/httpd.conf', ensure => file, require => Package["$webserver"], # notify => Service['httpd'] } service {'httpd': ensure => true, enable => true, restart => 'systemctl restart httpd.service', subscribe => File['httpd.conf'] } CONDITION的给定方式:变量,比较表达式,有返回值的函数只要当配置文件发生改变时,才会触发重启
case CONTROL_EXPRESSION { case1: { ... } case2: { ... } case3: { ... } default: { ... } } ex: case $osfamily { "Redhat": { $webserver='httpd' } /(?i-mx:debian)/: { $webserver='apache2' } default: { $webserver='httpd'} } CONTROL_EXPRESSION:变量,表达式,有返回值的函数各case的给定方式:直接字符串,变量,有返回值的函数,正则表达式模式,default
CONTROL_VARIABLE ? { case1 => value1, case2 => value2, ... default => valueN, } ex: $pkgname = $operatingsystem ? { /(?i-mx:(unbuntu|debian))/ => 'apache2', /(?i-mx:)(redhat|defora|centos))/ => 'httpd', defautl => 'httpd' } package{"$pkgname": ensure => installed, } CONTROL_VARIABLE的给定方法:变量,有返回值的函数各case的给定方式:直接字符串,变量,有返回值的函数,正则表达式模式,default注意:不能使用列表格式,但能够是其它的selector
为了实现通用目标或目的组织在一块儿的一个或多个资源,即命名为代码块shell
类的分类:
调用方式:
类的声明方式一:
class apache2 { $webserver = $operatingsystem ? { /(?i-mx:(centos|redhat|fedora))/ => 'httpd', /(?i-mx:(ubuntu|debian))/ => 'apache2', default => 'httpd' } package {'httpd': ensure => latest, before => File['httpd.conf'] } file {'httpd.conf': ensure => file, path => '/etc/httpd/conf/httpd.conf', source => '/root/puppet/httpd.conf', notify => Service['httpd'] } service {'httpd': ensure => true, enable => true, restart => 'systemctl restart httpd.service', } } include apache2 直接调用apache2类
类的声明方式二:
class apache2($webserver='apache2') { package {"$webserver": ensure => latest, before => File['httpd.conf'] } file {'httpd.conf': ensure => file, path => '/etc/httpd/conf/httpd.conf', source => '/root/puppet/httpd.conf', notify => Service['httpd'] } service {'httpd': ensure => true, enable => true, restart => 'systemctl restart httpd.service', } } class{'apache2': webserver => 'httpd' } 没有传递参数,将会使用默认httpd参数自定义实例变量结果,而且上变量得有默认值,不然不予执行
类的继承:
一般将公共功能定义为基类,须要增长的功能定义为子类,其继承一个已有的类,并实现覆盖资源属性,或向资源属性追加额外值
Type['title'] { attribute => value, ... } 引用并修改
Type['title'] { attribute +> value, ... } 添加新值
class apache2($webserver='apache2') { # $webserver = $operatingsystem ? { # /(?i-mx:(centos|redhat|fedora))/ => 'httpd', # /(?i-mx:(ubuntu|debian))/ => 'apache2', # default => 'httpd' # } package {"$webserver": ensure => latest, before => File['httpd.conf'] } service {'httpd': ensure => true, enable => true, restart => 'systemctl restart httpd.service', } } class apache2::web inherits apache2 { Service['httpd'] { subscribe => File['httpd.conf'] } file {'httpd.conf': ensure => file, path => '/etc/httpd/conf/httpd.conf', source => '/root/puppet/httpd.conf', notify => Service['httpd'] } } class {'apache2': webserver => 'httpd', } include apache2::web 子类继承父类的方式如上:父类::子类 inherits 父类
基于ERB(扩展ruby语言)模板语言,在静态文件中使用变量等编程元素生成适用于多中不一样环境的文本文件(配置文件),主要用于实如今文本文件中嵌入ruby代码,原来的文件信息不会被改变,但ruby代码会被执行,执行结果将直接替换原来代码
模板代码的添加方式:
其它更多添加方式请参考官方文档:
https://docs.puppet.com/puppet/latest/lang_template_erb.html在模板文件中可使用变量,包括puppet的任意可用变量,但变量名需以@开头。.erb可用可不用,在配置文件后加.erb只是为了好分辨
~]# mv nginx.conf nginx.conf.erb ~]# vim nginx.conf.erb worker_processes class nginx { package {'nginx': provider => yum, ensure => latest, } } class nginx::web inherits nginx { file {'nginx': ensure => file, content => template('/root/puppet/nginx.conf.erb'), path => '/etc/nginx/nginx.conf', require => Package['nginx'], notify => Service['nginx'] } service {'nginx': ensure => true, enable => true, restart => 'systemctl reload nginx.service', subscribe => File['httpd.conf'] } } include nginx::web <%= @processorcount %>若是定义好配置文件,使用了ERB的配置语法,文件复制不能用source,而是须要使用content参数,利用template函数生成对应的配置文件,此为固定格式用法(将使用template函数生成文本内容,再导入至对应的配置文件)
~]# tree /nginx/ /nginx/ ├── files ├── lib ├── manifests │ └── init.pp ├── spec ├── tempaltes │ └── nginx.conf.erb └── tests
puppet URL: puppet:///modules/MODULE_NAME/FILE_NAME
模块管理工具
注意:puppet3.8之后的版本中,资源清单文件名要与文件类名保持一致,例如某子类名为“nginx::web”,其文件名应该为web.pp。不在支持 import
~]# puppet apply -d -v -e 'include classes' --noop array 此处的-e后得是模块名,也就是在/etc/puppet/modules/下的模块名
master/agent强依赖于DNS服务(证书签署是对FQDN作证书颁发的),由master端定义好功能模块,再到/etc/puppet/manifests/定义site.pp文件,定义站点所须要的资源。master端经过自建CA并签发证书给各站点,使用证书验证客户端的身份,当站点发出请求时Master端将查找site.pp文件中定义的资源,编译成catalog,发送给客户端。 agent默认每隔30分钟向Master发送node_name和facts,并请求catalog,在本地执行catalog代码。master(监听8140端口)与agent(监听在8139)两者之间基于https协议通讯,其远程过程调用方式为xmlrpc机制。
Info: Creating a new SSL key for ca Info: Creating a new SSL certificate request for ca ... Notice: Signed certificate request for ca Info: Creating a new certificate revocation list Info: Creating a new SSL key for localhost Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml Info: Creating a new SSL certificate request for localhost ... Notice: localhost has a waiting certificate request Notice: Signed certificate request for localhost ...CertificateRequest localhost at '/var/lib/puppet/ssl/ca/requests/localhost.pem' ...CertificateRequest localhost at '/var/lib/puppet/ssl/certificate_requests/localhost.pem' Notice: Starting Puppet master version 3.6.2 ~]# puppet master --no-daemonize -v详细的初始化过程生成一个私钥生成一个证书请求自签证书生成吊销列表
Info: Creating a new SSL key for node6.iofunction.com Info: Caching certificate for ca Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml Info: Creating a new SSL certificate request for node6.iofunction.com ... ~]# puppet agent --server master --no-daemonize -v 引处的server用的主机名称,主机名不会变,ip地址会变,作实验我就直接写在/etc/hosts文件里的建立一个证书签署请求发往master端,等待签署完成的证书
一、配置master端 ~]# puppet master --no-daemonize -v #首次之前台模式启动,确认无误再运行为后端 ~]# systemctl start puppetmaster.service ~]# systemctl enable puppetserver.service ~]# ss -tnlp : 8140/tcp 二、定义站点配置文件 # cd /etc/puppet/manifests/ # vim site.pp #必须先为站点定义好站点文件,否则agent端启动时会报错 node /^centos7.pc\d+/ { include nginx::webserver } 三、配置agent端(发送证书签署请求给Master) # puppet agent --server=master_hostname --no-daemonize --noop --test -v #建议首次启动时之前台模式运行,确认OK后,再将运行为后端 ~]# systemctl start puppetagent.service 四、在master端为客户端签署证书 ~]# puppet cert list #首先查看未签署的证书列表 ~]# puppet cert sign node_name 或者 ~]# puppet cert sign -all 五、以守护进程方式启动agent ~]# systemctl start puppet ####必要是清除客户端请求 ~]# puppet cert list -all : 查看已经签署的客户端证书 ~]# puppet cert clean node_name : 清除一个Node的签署证书 rm -rf /var/lib/puppet/ssl : 移除ssl证书
~]# puppet help kick 虽然要被弃用了,但仍是有人在用 puppet kick [-a|--all] [-c|--class <class>] [--host <host>] ~]# vim /etc/puppet/puppet.conf [main] ... listen = true [agent] server = master ~]# tail -10 /etc/puppet/auth.conf path /run method save auth any allow master.iofunction.com # deny everything else; this ACL is not strictly necessary, but # illustrates the default policy. path / auth any agent端:master是谁容许主像agent推送消息
site.pp文件是puppet读取全部模块pp文件的开始
~]# vim /etc/puppet/manifests/site.pp node /^node\d+\.iofunction\.com/ { 主机名匹配 include chrony, jdk8 } 类名同module名相同,方可执行