2017/07/15 puppet类和模板(04)

不问归期 提交于 2019-11-29 04:56:39

之前讲了puppet当中的编程元素,包括变量,和流程控制语句,当中的条件判断,if unless,case和selector,这些流程控制语句可以在条件满足的时候,来完成流程控制事的所谓配置文件的编写
但是有时候我们需要用代码来完成重用,事实上对于configuration 而言,
支持另外两种编程元素,函数,类,用的最多是类
puppet的编程源支持两种编程方式,过程式编程和对象式编程,ruby本身就是对象式编程,在puppet代码中也支持类,要想能去配置nginx,nginx有两种功能,web server,反代reverse proxy(7层反代。,4层反代)
配置起来的步骤,无非就是安装程序包,提供配置文件,启动服务
无非就是配置文件不一样
安装程序包,和启动程序,这段配置是可以进行公用的,所以可以把安装包和启动程序定义成一个公共的模块,而后在定义,三个子功能都能调用这个公用的公共模块
而在类的架构当中,这种方式十分容易实现

先定义一个父类,父类其实有两个资源,1.安装程序包,2.启动服务
而后再定义三个子类分别去继承父类,而后在子类中定义一个新资源,比如提供配置文件A文件
再定一个子类,也添加一个文件资源,继承父类
从父类可以得到一部分定义,在本地直接调用使用

在这里插入图片描述
父类也叫做基类,这里类更像是过程式编程中的函数,所不同的是,比函数功能更强大,不但能继承,还能重载某些运算符,把某些对应的数据,在子类中额外补充一个功能也可以
父类的资源到子类里,子类觉得不适合,完全可以重写,把原来复制的资源覆盖掉,但是后面的两个子类可以不这么做
对象式编程是以数据为中心,围绕数据组织代码,代码服务于数据,用于改变数据状态

在这里插入图片描述
puppet的类:
类:puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;(不光是当前节点,整个puppet集群)
类可以被继承,也可以包含子类;

语法格式:
class NAME {可以想象成自定义类型
…puppet code…
}

class NAME(parameter1, parameter2) {可以给形参赋值,以在类中进行调用
…puppet code…
}
写完类,是不会运行的,等于写完函数,不调用是不会运行的 ,类定义好后,相当于自定义类型,直接拿自定义类型过来,定义成一个资源,才能运行
类代码只有声明后才会执行,调用方式:
类被定义成资源的方式有两种

(1) include CLASS_NAME1, CLASS_NAME2, …
(2) class{‘CLASS_NAME’:
attribute => value,属性=复制
}
定义一个安装nginx,启动服务
在这里插入图片描述
class取名=nginx
正常写的代码放到class内部即可

在这里插入图片描述
在这里插入图片描述
定义函数一样,是不会执行的
使用include调用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
没安装nginx,需要安装在这里插入图片描述
在这里插入图片描述
定义include,也可以在外面写在这里插入图片描述
加-e选项,表示执行,include nginx
在这里插入图片描述
当前主机找不到nginx类,因为默认在这里引用nginx类,需要找类的时候,是到模块文件中找的,而不是在manifest文件找的,
所以此时带不到后面的文件都没什么区别,必须把整个文件放置成模块才可以

在这里插入图片描述
在这里插入图片描述
现在必须定义这里,申明类,类还可以有参数(比如centos6是mysqlcentos7是mariadb)
在这里插入图片描述
facter-p 操作系统是7,主发行版本是7
在这里插入图片描述
这里可以用if条件嵌套以后判断
在这里插入图片描述
如果说操作系统的版本是centos,再嵌套进去判断,主版本号判定,如果是7就返回mariadb-server,6就返回mysqld-server
这串代码是真正执行时才写的,现在还没有类
创建一个dbserver类,传递参数,定义安装程序包
下面的先不管,上面的代码想要运行,必须要调用,如果要调用,必须要include dbserver

在这里插入图片描述
在这里插入图片描述
必须要给dbserver这个变量传一个值才可以,也不是没传值就不能运行,可以给一个默认值在这里插入图片描述
传了就是你传的值,没有传就时mariadb-server
在这里插入图片描述
在这里插入图片描述
就不报错,提示mariadb-server安装 过了,但是服务没启动起来
在这里插入图片描述
所以对于这种需要传参数的也可以使用include,如果没有默认值,就需要调用的时候传值,就不能使用include这种方式了 ,而是像申明资源一样来申明
把$pkgname当作属性来赋值
所以叫自定义类型

在这里插入图片描述
在这里插入图片描述
这是第二种方法,需要传参数时使用这种方法
在这里插入图片描述
在这里插入图片描述
但是依然做不到,不同的操作系统版本传不同的值,就需要使用下面的代码,先判断值是什么
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以有了代码编程功能以后,对应的代码,对于的配置文件,可以写的更有适用性,不能写一个代码只适用于一种场景
puppet的类:
类:puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;
类可以被继承,也可以包含子类;

	语法格式:
		class NAME {
			...puppet code...
		}
		
		class NAME(parameter1, parameter2) {
			...puppet code...
		}
		
	类代码只有声明后才会执行,调用方式:
		(1) include CLASS_NAME1, CLASS_NAME2, ...
		(2) class{'CLASS_NAME':
			attribute => value,
		     }
		  
		示例1:
			class apache2 {
				$webpkg = $operatingsystem ? {
					/(?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		
			
		示例2:
			class dbserver($pkgname) {
				package{"$pkgname":
					ensure  => latest,
				}

				service{"$pkgname":
					ensure  => running,
					enable  => true,
				}
			}

			#include dbserver


			if $operatingsystem == "CentOS" {
				$dbpkg = $operatingsystemmajrelease ? {
					7 => 'mariadb-server',
					default => 'mysqld-server',
				}
			}

			class{'dbserver':
				pkgname => $dbpkg,
			}

刚才定义的内容还有问题,如果期望适用于不同的场景,你的nginx,要么做web,要么做7层反代,4层,应该使用不同的配置文件,怎么让它通过类来继承适用于不同的配置
在这里插入图片描述
类继承的方式:
class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {定义一个类但是叫inherits继承哪个父类
一个子类从哪个父类来继承
…puppet code…
}
而后就能实现拥有父类的代码
这个名称是用了完全限定格式来定义,前面是父类,后面是子类 inherites 继承了nginx

在这里插入图片描述
可以把刚才的配置文件再进化一版
在这里插入图片描述
**定义三个子类,nginx::web inherits 继承自nginx
nginx::7proxy 7层代理 inherits 继承自nginx
nginx::webproxy inherits 继承自nginx
nginx:: mysqlproxy mysql代理 inherits 继承自nginx
这四个子类每一个都天然拥有父类代码 **
在这里插入图片描述
在这里插入图片描述
告诉你nginx还没安装需要安装
服务还没启动,需要启动
子类中再加一个资源,自己新增内容

在这里插入图片描述
一旦文件发生更改,就需要通知service资源,可以自己在下面重新定义service资源
在这里插入图片描述
在这里插入图片描述
提示找不到源文件
在这里插入图片描述
先手动装上去试试
在这里插入图片描述在这里插入图片描述
这个原本就是web服务的不用去修改
在这里插入图片描述
再次修改名字,名字应该对应起来
在这里插入图片描述
在location中加proxy
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
配置文件没有什么改变,所以没报什么错
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这次就提示配置文件不一样了,服务应该重调之类的
在这里插入图片描述
假如在第二个子类中,不期望这个service enable =true,从父类继承到子类就是为true,现在想在webproxy中不为true,可以覆盖父类的值,或者在父类中新增属性,可以覆盖父类资源中某个属性值,或者是增加父类的属性
在这里插入图片描述
在子类中为父类的资源新增属性或覆盖指定的属性的值:
Type[‘title’] {
attribute1 => value,

}

在子类中为父类的资源的某属性增加新值:
Type[‘title’] {
attribute1 +> value, 有些属性可以带多个参数

}
子类中为父类资源新增属性或覆盖属性,如果修改
1.现在子类中引用父类的资源
其他值不变,只是把enable改成false

在这里插入图片描述
在这里插入图片描述
可以真正跑一遍,查看对应状态是什么
在这里插入图片描述
nginx装上了,配置文件也提供了反代的,当前状态,应该是启用状态
在这里插入图片描述
但是当前并不是开机就启动的,为disabled
在这里插入图片描述
这就是覆盖父类中指定资源的属性值
在这里插入图片描述
换一个依赖关系,服务依赖包,在子类中,这个service不仅依赖package还依赖file,+> nginx。conf,这个+号,代表不是要覆盖前面的,而是要追加,依赖于这个包,还要依赖于这个文件
表示为父类中的某个属性,新增额外的值

在这里插入图片描述
在这里插入图片描述
不同的服务程序,他们的配置文件有可能不一样(nginx启动进程应该小于等于cpu核心数,但是不同的agent主机可能不一样),workprocess 可以实现auto,但是想要核心数-1,但是不同主机cpu可能不同,所以不可能给固定值放那里,所以这个时候就需要我们的facts变量来获取到指定主机的物理核心数以后,再去做算术运算-1来实现,这个时候配置文件就需要内嵌代码
ruby的内嵌式模板语言叫erb embedded ruby

文本文件中内嵌变量替换机制:
<%= @VARIABLE_NAME %> @+变量名 %=的方式来进行定义
process count就是cpu核心数

在这里插入图片描述
这个文件定义了两个资源,1.包package,ensure =latest
file 主配置文件
path 放在哪里
content 直接生产,内容从内建的templete 函数,加载指定路径下的erb模板文件来实现,这个文件内建了代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
会告诉你配置文件不一样了
在这里插入图片描述
现在打开配置文件看看
在这里插入图片描述
在这里插入图片描述
这就叫做模板,对应的代码可以直接写在一个静态的文件中
在这里插入图片描述
变量替换就是%=

在这里插入图片描述
通常情况下只是一个变量替换,而有些场景中,可能需要做条件判断
在这里插入图片描述
each就是迭代变量中的每一个元素,把每一个元素赋值给val变量,内部执行代码,调用val变量
end结束这个循环

在这里插入图片描述
在这里插入图片描述
puppet模板:

erb:模板语言,embedded ruby;

puppet兼容的erb语法:
	https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html
	
file{'title':
	ensure	=> file,
	content	=> template('/PATH/TO/ERB_FILE'),
}

文本文件中内嵌变量替换机制:
	<%= @VARIABLE_NAME %>
	
示例:
	class nginx {
		package{'nginx':
			ensure  => installed,
		}

		service{'nginx':
			ensure  => running,
			enable  => true,
			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.conf.erb'),
			require => Package['nginx'],
		}

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

	include nginx::web

有了模板就可以按照需要生成配置文件

在模块当中,关键就是定义类,自包含的定义的代码结构
ansible定义role任务,

在这里插入图片描述
最好把每一组资源文件所依赖的文件都放在一个独立的目录下。将来运行就放在一个目录下运行
模块有特定的放的位置,

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!