Puppet file 指令删除目标目录中的不在源目录中的文件

file {‘/home/op/open-falcon-agent/plugin’:
path => ‘/home/op/open-falcon-agent/plugin/’,
source => ‘puppet:///modules/sre-scripts/’,
recurse => true,
ignore => ‘.git’,
group => root,
owner => root,
mode => 755,
purge => true,
force => true,
require => Package[‘open-faclon-agent’]
}

这段配置,把 puppet:///modules/sre-scripts/ 中的目录和文件同步到 /home/op/open-falcon-agent/plugin,如果想把 /home/op/open-falcon-agent/plugin 中不在 puppet:///modules/sre-scripts/ 中的文件和目录删除掉,可以使用:

purge => true,
force => true,

purge => 默认会删除文件,不会删除目录,再配合使用 force => true,可以把不存在的目录删掉。

2F7828D7-1698-4746-A268-0D7C3965B027

 

参考:

https://docs.puppet.com/puppet/latest/reference/type.html

 

搭建 Puppet dashboard 来监测 Puppet 更新失败的问题

最近花了几天搞了一下 Puppet 更新失败的问题,总结了一下遇到的问题,问题还挺多的,这就是开发有登陆机器权限的恶果,问题列表:

1.crontab 任务被注释(我们使用 crontab 来更新 Puppet);

2.证书问题,基本上都是证书已经存在,证书申请失败,此时需要到 Puppet ca 删掉原有证书,并清空本机证书,重新申请;

这种情况 Puppet Master 是拿不到更新信息的,所以 Puppet Dashboard 看不到这种机器。

一般是由改主机名引起,可以通过修改改名脚本彻底解决:

1). 改名之前去 Puppet ca 删除原主机名的证书;

2). 删除本机的证书文件;

3). 查看 Puppet ca 中是否已经存在新主机名的证书;

4). 如果存在,删除 Puppet ca 中的新主机名证书;

5). 真正改名。

3.Puppet 依赖的 ruby 环境被损坏;

4.升级 Python 导致 yum 不可用;

5.普通用户进程数达到上限导致 lighttpd(Nginx 七层检测用) 起不来;

6.升级 Python 导致 supervisor 启动不了;

7.一些自定义 rpm 包不支持 Centos7,启动失败;

8.mysql-libs 和 Percona-Server-server 冲突;

解决方法:
安装 Percona-Server-shared-compat 代替 mysql-libs 。

9.Puppet 忽略此节点,返回400;

通过修改 puppet_node_classifer.py 解决,忽略的节点也返回执行 Puppet 主任务的 crontab配置。

10.机器死机。

 

 

问题多多,所以安装 Puppet Dashboard 来观察哪些机器更新失败。

1.安装:

yum install rubygem-rake ruby-mysql mysql-server puppet-dashboard

2.修改 /etc/my.conf,在 [mysqld] 内加入
max_allowed_packet = 32M

然后 在 [mysqld] 和 [client ]内加入
defalut-character-set = utf8

3.创建mysql数据库和用户

create database dashboard;
grant all on dashboard.* to puppet@’10.%’ identified by ‘puppetdashboard’;
flush privileges;

4.修改 /usr/share/puppet-dashboard/config/database.yml

production:
database: dashboard
username: puppet
password: dashboard
encoding: utf8
adapter: mysql

5.导入表结构

cd /usr/share/puppet-dashboard
rake gems:refresh_specs
rake RAILS_ENV=production db:migrate

6.测试 puppet-dashboard 能否工作,端口起在 3000

/usr/share/puppet-dashboard/script/server -e production

7.启动

/usr/share/puppet-dashboard/script/server -e production -d
env RAILS_ENV=production /usr/share/puppet-dashboard/script/delayed_job -p dashboard -n 4 -m start
/etc/init.d/mysql.server start

8.访问。

通过 http://puppetdashboard:3000

 

额外要注意的几点:

1.Puppet client 更新 Puppet 的时候需要指定 report 参数,比如:
/usr/bin/puppet agent –onetime –no-daemonize –server=puppetlb.corp.nosa.me –ca_server=puppetca.corp.nosa.me report

2.要在 Puppet master 的 [main] 下面增加两行:
reports = http,store
reporturl = http://puppetdashboard:3000/reports/upload

3.默认是 UTC 时区,修改成北京时间,编辑文件 /usr/share/puppet-dashboard/config/settings.yml,修改 time_zone:

time_zone: ‘Beijing’

4.dashboard 的数据库文件增加很快,如果不清理,很快就会占满硬盘,最好每天清理一次,清理脚本可如下(保留一天):

cd /usr/share/puppet-dashboard
env RAILS_ENV=production rake reports:prune upto=1 unit=day
env rake RAILS_ENV=production db:raw:optimize

 

 

最后,要通过 api 获取更新失败的机器列表 和 通过 api 查询、删除 证书 可以参考 这里,查询和删除证书要认证,如果怕麻烦 可以修改 Puppet ca 的 /etc/puppet/auth.conf ,增加 allow *,只是不太安全。

 

如何动态获取 Puppet node 指令定义的机器列表

我的需求是这样的,比如我这 Puppet 配置文件里面定义下面的配置来配置 NTP Server :

node "ntp0.hy01.nosa.me", "ntp2.hy01.nosa.me" {
    class { ‘::ntp':
        servers => [
            ‘0.pool.ntp.org’,
            ‘1.pool.ntp.org’,
            ‘stdtime.gov.hk’
        ],
        }
}

ntp0.hy01.nosa.me 和 ntp1.hy01.nosa.me 是写死的,如果机器变化需要手动修改,很麻烦,所以想动态获取。


Puppet 里面有一个功能叫做 ENC(全称是 External Node Classifiers ,网址 ) 可以变相实现这个功能。

先说下怎么用 ENC,需要在 puppet.conf 的 [master] 里面 加上类似 :

node_terminus = exec
external_nodes = /etc/puppet/puppet_node_classifer.py

然后 /etc/puppet/puppet_node_classifer.py (路径可改) 要有执行权限,这个脚本需要有一个参数,就是 「来请求 Puppet 的 主机名(FNDQ)」,然后这个脚本的输出需要是 yaml 格式,比如

$ ./puppet_node_classifer.py ntp0.hy01.nosa.me
—
classes:
– ntp_server

那么,当 ntp0.hy01.nosa.me 来请求 Puppet 的时候 Puppet 会执行 ./puppet_node_classifer.py ntp0.hy01.nosa.me,Puppet 拿到 yaml 格式的配置之后 做一个转换,上面的 yaml 配置相当于如下:

node "ntp0.hy01.nosa.me"  {
    include ntp_server
}

此时 ntp_server 这个 class 可以这么定义 (我是定义在 /etc/puppet/manifests/site.pp 文件中):

class ntp_server {
    class { ‘::ntp':
        servers => [
            ‘0.pool.ntp.org’,
            ‘1.pool.ntp.org’,
            ‘stdtime.gov.hk’
        ],
    }
}

puppet_node_classifer.py 我是这么实现的,先从 「服务数节点」去抓所有 NTP server 的服务器列表,如果 「此台机器」在列表里,那么就返回相应的 yaml 配置。