先讲讲shell 与puppet的不同。
shell 脚本是过程式的,里面描述的是命令执行的过程,shell 通常很短,可以很快写出来,但是很快又会被抛弃,它常常依赖于特定操作系统环境。
puppet 语言是结果式的,使用者将自己想要达到的目的通过puppet语法描述给puppet,puppet去完成它,使用者不需要关心过程,整个过程完全被抽象化了。譬如安装一个软件包,只需要ensure => present ,不需要关心操作系统是debian还是redhat 。
个人总结看来,puppet语言形式上的特点就是“花括号分类,冒号声明,逗号结束”。
接下来讲puppet的语法,主要是举例(持续完善中,,,)
1、软件包管理
安装
package {"vim": ensure => present, }
多个软件包也可以一起写,用中括号和逗号
package { ["httpd","mysql-server","php","php-mysql"]: ensure => present, }
卸载
package {"vim": ensure => absent, }
2、权限管理
file { "/etc/sudoers": owner => root, group => root, mode => 400, }
权限递归
file { '/some/dir': mode => 644, recurse => true, }
目录里的所有文件会变成644,目录就会755
3、服务
service {"sshd": hastatus => true, harestart => true, ensure => running, enable => true, }
4、文件管理
文件托管
file {"/etc/my.cnf": ensure => present, source => "puppet:///modules/mysql/my.cnf" owner => mysql, group => mysql, }
这里有个地方比较蛋疼,文件路径是/etc/puppet/modules/mysql/files/my.conf,写成puppet规则时files会被省略,写成puppet:///modules/mysql/my.cnf
链接
file { "/etc/inetd.conf": ensure => link, target => "/etc/inet/inetd.conf", }
5、监视和审计
file { "/etc/passwd": audit => [ owner, mode ], }
(当文件的权限属性发生变化时发出消息,而不修正权限)
6、执行命令
exec { "reload nginx": command => "/usr/sbin/nginx reload", require => Package["nginx"], refreshonly => true, } file { "/etc/nginx/nginx.conf": source => "puppet:///modules/nginx/nginx.conf", notify => Exec["reload nginx"], }
(notify表示配置文件发生更改,就触发nginx平滑重启)
7、定时任务crontab
cron { ntpdate: command => "/usr/sbin/ntpdate 192.168.1.3", user => root, hour => '*/4', minute => '1', ensure => present, }
(这样会导致流量瞬间拥挤,puppet很周到,提供一个伪随机的办法)
cron { ntpdate: command => "/usr/sbin/ntpdate 192.168.1.3", user => root, hour => '*/4', minute => fqdn_rand( 60 ), ensure => present, }
(尽管是每四个小时运行一次,但是不同的机器还是会在不同的时刻去执行命令【分钟数为0-60随机】,将流量分散开来。)
8、删除
tidy { clean_temp: path => "/tmp/temp", type => "ctime", recurse => true, rmdirs => true, age => "1d", backup => false, }
(recurse表示递归)
高级用法之class
单独的class
class ssh { package {"openssh-server": ensure => present, } file {"/etc/ssh/sshd_config": ensure => present, owner => root, group => root, source => "puppet:///files/sshd_config", notify => Service ["sshd"], } service {"sshd": ensure => running, hasstatus => true, hasrestart => true, enable => true, } }
合并的class(class可以被引用,成为另一个class的子集,用逗号分隔,结尾没有逗号)
class basic { include ssh, httpd }
节点的语法和引用class一样
node "apache01.test.org" { include httpd,mysql,php }
用户管理
user { "root": ensure => present, name => "root", password => "SomeAlreadyEncryptedPassword"; } user {"admin": name =>"admin", ensure => present, shell => "/bin/bash", home => "/home/admin", groups => "admin,wheel", uid => 500, gid => 500, password => '$1$Nnh0M0$t9s7Bbwx2fFer6IP/QGdA0', require => Group["admin"], } group {"admin": ensure =>present, }
(password也就是/etc/shadow中的已经加密的密码,把它复制出来就好了,密码中包含 $ 的话,一定要记得加单引号。)
puppet还可以独立于master单独运行,功能也足够强大,几乎所有能写成puppet规则的语句,都可以直接在puppet命令行执行,例如:
1、安装软件包
puppet resource package httpd ensure=present
puppet 可以识别常见的linux发行版,自动调用yum或者apt去安装软件。
2、管理服务
puppet resource service httpd ensure=running enable=true
puppet会调用/etc/init.d/下的启动脚本,这个比常见的监控脚本强太多了。(puppet 2.7以上)
3、将规则写入本地文件来执行
puppet apply /opt/puppet/rules/init.pp