module,grains,pillar_saltstack
http://www.sudops.com/another-tools-for-sa-of-saltstack.html
SaltStack是一个新的基础平台管理工具。很短的时间即可运行并使用起来, 扩展性足以支撑管理上万台服务器,数秒钟即可完成数据传递. 经常被描述为 Func加强版+Puppet精简版。
对系统工程师来说,配置管理已经向前跃进了一大步. 系统配置的自动化不仅可预测,可重复, 还具有可管理性. 配置管理工具通常使用版本控制化的配置模板来描述基础设施的目标状态。凭借版本控制化的配置,可以将环境回滚(或前滚)到前面(或后序)状态;环境配置文件的自动化管理也是持续性交付管道的必要特性。
CFEngine, Puppet和Chef(按年龄降序)是开源领域流行的配置管理工具。 我是一个Puppet的长期用户, 与自定义的配置脚本相比,它在系统自动化的组织性和可靠性方面带来了巨大的提升。(我是在2009年作出这一次飞跃,与此相比, 以前的日子简直是混乱不堪…).
虽然配置管理工具精于描述并达到想要的状态, 但并不擅长动态地查询或设置状态. 这一点在状态资源还没有被纳入配置管理时特别明显。Llinux系统管理员的传统解决办法是ssh循环登陆节点列表并执行一堆命令。这不仅容易出错, 且每一次循环都要打开新的ssh会话,效率低下。想像一下要在1000台机器上顺序执行命令!更不用说网络安全,ssh密钥和命令执行权限的问题。这当然是一种可行的办法,但缺少一种可管理的框架。
这就是命令编排工具产生的原因。这些工具旨在大量的节点上并行执行命令和实时操作。CFEngine, Puppet和Chef各自用不同的方法来解决命令编排问题。Puppet使用MCollective作为其武器,并将其集成到商业版中。
近来,我开始探索使用SaltStack来解决配置管理和命令编排这两个问题。SaltStack开始于2011年,是一个相对较新的项目,但在系统管理员和DevOps工程师中拥有越来越多的粉丝。我将在本文中探讨Salt作为前途光明的替代者,并与Puppet作比较以探索其特性。
安装
创世之初,满是空白和无序,黑暗笼罩着整个系统……然后神安装了配置管理器,于是阳光普照!唯一的麻烦是,我们还需要安装依赖……然后配置管理器本身还得被配置……并且有时事情会有那么一点丑陋。
Salt在Ubuntu和CentOS上的安装过程异常简单,我相信在有安装指南的别的系统也一样 (Arch Linux, Debian, Fedora, RedHat, CentOS, FreeBSD, Gentoo, Windows, Solaris). YMMV. 典型安装过程隐藏了不必要的细节配置,除非你需要修改他们。首先安装salt master,然后安装salt minions, 将minions指向master,安装完成。如果salt master的主机名是”salt”,都不需要将minions指向master,直接就可以运行。
然而, 如果你不是使用上面提到的发行版或操作系统, 你很可能需要卷起袖子自己手动安装一些依赖。包括Python (>= 2.6 < 3.0), ZeroMQ, pyzmq, PyCrypto, msgpack-python和YAML的Python绑定.
另一方面, Puppet在多数基础安装时只依赖Ruby和Facter, 依赖带来的麻烦显著减少. 然而,Puppet的依赖列表可以进一步增加,包括augeas-libs, dmidecode, hiera, libselinux-ruby, pciutils, ruby-augeas, ruby-irb, ruby-rdoc, rubygem-json, ruby-shadow, rubygems. 这取决于Puppet的版本和你想要使用的功能。
我喜欢Salt包安装的简单明了。For the cases mentioned it is trivial to set up and get going. 如果你想亲自安装和配置的繁过程, 跟着安装指南做即可。
If you are like me though and you prefer your provisioning and configuration all in one gift wrapped package, que Vagrant to the rescue and download this project by elasticdog on github.
配置管理
配置状态
配置管理对Puppet来说是小菜一叠,对Salt又如何呢。让我(高兴的)惊讶的是,这件事简单到令人发指。和Puppet一样,在Salt中可以描述系统的目标状态。. Salt将其称之为一个state, 配置模块是state模块。Salt的State模块文件用YAML写成,以.sls结尾。它们从功能上等同于Puppet模块的manifest文件,后者用Puppet DSL写成,以.pp结尾。
Salt在master的配置文件中指定"file roots", 类似于Puppet的"module path", 但同时包含了模块根目录和环境类型。举例来说,在Salt中我们可以分别指定development和test环境配置文件路径. 注意base环境是必须存在的。
1
2
3
4
5
6
7
|
file_roots:
base:
- /srv/salt/
dev:
- /srv/salt/dev
prod:
- /srv/salt/prod
|
base环境必须包含Salt的入口top文件(叫做top.sls).base定义了一个或多个环境,用正则来匹配节点,然后引用相应的Salt states. top文件与Puppet的nodes文件相似。(Puppet入口点是site文件,在Salt中不需要).
假设有一个Salt master和两个minions (由Elasticdog github提供),我想要在两个minions上安装mongodb。如果在默认的软件仓库中有mongodb包,只需要3步即可。
1, 在top.sls中指定节点。
1
2
3
|
dev:
'minion*.example.com':
- mongodb
|
2, 在dev/mongodb.sls中描述状态:
1
2
3
|
mongodb:
pkg:
- installed
|
3, 传递状态到salt minions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# salt 'minion*' state.highstate -v
Executing job with jid 20121218102842533621
-------------------------------------------
minion1.example.com:
----------
State: - pkg
Name: mongodb
Function: installed
Result: True
Comment: Package mongodb installed
Changes: libicu: {'new': '3.6-5.16.1', 'old': ''}
mongodb: {'new': '1.6.4-1.el5', 'old': ''}
boost: {'new': '1.33.1-15.el5', 'old': ''}
js: {'new': '1.70-8.el5', 'old': ''}
minion2.example.com:
----------
State: - pkg
Name: mongodb
Function: installed
Result: True
Comment: Package mongodb installed
Changes: libicu: {'new': '3.6-5.16.1', 'old': ''}
mongodb: {'new': '1.6.4-1.el5', 'old': ''}
boost: {'new': '1.33.1-15.el5', 'old': ''}
js: {'new': '1.70-8.el5', 'old': ''}
|
配置描述文件与Puppet非常相似。但格式差别很大。这是因为Puppet使用自己的ruby-like DSL, 而Salt使用YAML. 正是由于这点不同,造就了Salt state配置文件在视觉上的简洁性。YAML对人类可读也容易被映射到数据结构, 非常适合做配置管理中的资源描述。这不是说Puppet DSL不清晰或不结构化- it is neither - 但很难胜过YAML. YAML可以快速写成,在我的经验看,比Puppet DSL要容易生成.
注意: 配置管理社区关于声明配置的最佳方式一直存在争论。部分人青睐于利用编程语言(比如说Ruby)的灵活性。Chef是其中的代表。Puppet处于中间地段。当使用现成的功能时,Puppet DSL非常强大。但要给配置开发者更大的能力,就必须使用内部的Ruby DSL。在波谱的另一端,Salt的简单YAML状态描述非常结构化。然而,Salt也支持渲染诸如JSON, Mako, Wempy和Jinja来扩展其能力, 在将来还会支持XML,原生Python及其他。
内置的state模块
我知道Salt是比Puppet近的项目, 我完全可以预料到不会有太多可用的内置模块。我错了: Salt有大量的内置模块,包含Puppet中的大部分必要模块比如 cron, exec (Salt是cmd), file, group, host, mount, package (Salt中是pkg), service, ssh_authorized_key (Salt是ssh_auth)和user。
尽管如此, Puppet仍然具有部分优势。比如, 我非常喜欢Puppet的Augeas模块。Augeas把内容当作value树,允许你修改(而不是覆盖)一个已存在的配置文件。
虽然Salt有一个Augeas execution模块,但很不幸貌似没有Augeas的state模块。虽然这样,Salt也有一些自己特有的东西,比如针对git, hg和svn的内置state模块.
模板
Puppet具有开盒即用的模板系统。Puppet有file资源和template资源的概念,这些资源分布在模块目录结构的不同路径下。在Salt中, files和templates在同一个位置。通过为template指令指定type来区分是template还是普通文件资源, type可以是jinja, mako或wempy。好处是可以很容易为file资源增加逻辑。state文件可能看起来像下面这样:
1
2
3
4
5
6
7
|
/etc/myapp.conf:
file.managed:
- source: salt://files/myapp.conf
- mode: 644
- owner: root
- group: root
- template: jinja
|
注意最后一行, 指明被管理的文件是一个jinja模板。
配置文件可以使用jinja的语法来增加逻辑。举例来说, 假设你的应用程序配置文件中用到了主机名。再假设在Ubuntuh 只需要短主机名(hostname),在CentOS需要FQDN。这可以很容易地在模板文件myapp.conf中指定:
1
2
3
4
5
|
{% if grains['os'] == 'Ubuntu' %}
host: {{ grains['host'] }}
{% elif grains['os'] == 'CentOS' %}
host: {{ grains['fqdn'] }}
{% endif %}
|
在CentOS节点minion1上结果文件/etc/myapp.conf将包含以下内容
1
|
host: minion1.example.com
|
变量
Salt中的全局变量不能在使用时定义。在对变量的支持方面Puppet更加直观和灵活。在Salt中, 所有的变量保存在单独的位置。这样做不够灵活,但优势是更有秩序。用Salt的话讲,变量叫做"pillars"。pillars的位置在salt master的配置文件中指定:
1
2
3
|
pillar_roots:
base:
- /srv/salt/pillar
|
和state文件一样, 首先创建一个top文件,在其中可以引用相关的pillar模块。
1
2
3
|
base:
'*':
- packages
|
这个top文件引用了名为packages.sls的state文件, 其中包含将要安装的软件包的版本号的变量,如下所示:
1
2
|
mongodb: mongodb-1.6.4-1
httpd: httpd-2.2.3-65
|
声明了两个pillar, mongodb和httpd, 然后可以在state文件中用如下方式引用:
1
2
3
|
pillar['mongodb']
pillar['httpd']
模拟执行(Dry run)
|
管理系统有点像驾驶飞机。如果不小心谨慎,将会是高风险的事情。假设我是一个双翼飞机的驾驶员,将做一个危险的aerial manoeuvre, 我多半会希望能够先模拟飞行。除非我像Red Baron一样无所畏惧。无论如何,还好在执行Salt之前可以先做测试。你需要做的仅仅是将Test设置为True。
1
2
3
4
5
6
7
8
9
10
11
|
# salt 'minion1.example.com' state.highstate -v test=True
minion1.example.com:
----------
State: - file
Name: /etc/myapp.conf
Function: managed
Result: None
Comment: The following values are set to be changed:
newfile: /etc/myapp.conf
Changes:
|
总结
在配置管理方面,Salt在Puppet面前还是能够站稳脚跟的。Salt安装非常简单,属于简单主义的开发风格, 功能丰富。总的来说,不需要过多的操作就可以完成事情。我发现的唯一问题是salt-master和minion之间的连接有时会无故断掉。搜索一番后,我发现其他人在Salt 0.10.5这个版本上也遇到了同样的问题。希望这个问题在下一个版本中得到解决。
命令编排和远程执行
MCollective
MCollective是 Puppet的命令编排解决方案。由R.I.Pienaar在PuppetLabs那帮人引起重视之前独立开发完成。MCollective使用message broker (比如ActiveMQ)通过pub-sub总线来传递消息, 可以并行通信,这比用ssh快得多。这是一可以理解特定消息并产生响应的框架。Puppet和MCollective现在可以在同一个框架下工作,同时提供完成配置管理和命令编排的功能。
先不管MCollective的优势,有两个负担能够打击你的激情。第一,MCollective只是和Puppet松散集成,至少对社区版本来讲是这样 。MCollective有单独的安装包,独立的配置文件。另外你还需要安装配置broker(比如ActiveMQ),来与MCollective一起工作. 虽然不难,但很繁琐。最后,你还不得不自己解决生产环境中通信渠道的安全问题。不幸的是,这个就有点困难。
MCollective的第二个问题是相对来讲缺少一些自带的功能。有很多现成的插件可以下载安装(https://github.com/puppetlabs/mcollective-plugins), 用Ruby写自己的插件也不是很复杂-不过想要立即使用的话,障碍比想像得要大。Nevertheless, given that the framework is solid and extensible, dabbling in Ruby plugins soon makes the real power of MCollective apparent.
Salt
另一方面,Salt生来就有命令编排的功能。最先设想的就是远程执行技术,然后才添加的配置管理管理。Salt使用轻量的ZeroMQ来处理消息。结果就是不需要单独的安装。装好Salt后,配置管理和命令编排就可以工作了。毫不惊奇,Salt state模块和execution模块的命令在语法上类似,所以很直观。再看Puppet和MCollective组合,各自使用不同的工具和语法结构,需要额外的时间去学习。
Salt远程执行功能的可用性令人印象深刻。当前的在线文档列出了超过100个不同的内置excution模块-包括augeas!(所以augeas成为state模块只是时间上的问题).
举个简单的例子,看看通用的"cmd.run"模块和指令。这在你知道想要执行的命令却又没有现成的模块可用时非常有用,- 或者你仅仅想要快速地远程执行命令。假设我想在所有节点上检查运行的内核版本号:
[root@salt salt]# salt '*' cmd.run "uname -r"
minion1.example.com: 2.6.18-274.18.1.el5
minion2.example.com: 2.6.18-274.18.1.el5
salt.example.com: 2.6.18-274.18.1.el5
或者我想看看磁盘使用情况:
salt '*' cmd.run "df -h"
顺便说一下, Salt有一个模块用来查看磁盘用量以及其他磁盘相关的查询:
salt '*' disk.usage
使用内置模块而不用cmd.run发送shell命令的好处是,模块通常返回固定结构的数据。能够以编程的方式用在自动化处理上。
有很多现成的execution模块来满足通用的管理任务,比如apt, at, cp, cron, disk, extfs, file, hosts, iptables, mount, network, pam, parted, pkg, ps, selinux, shadow, ssh, and test. 也有大量的模块用于指定的软件包和应用程序,比如apache, cassandra, djangomod, git, mongodb, mysql, nginx, nova, postgres, solr, sqlite3, 和tomcat.
甚至支持执行Puppet程序。
总结
毫无疑问,Salt远程执行比Puppet加MCollective更优雅,附带可用的功能更多。支持动态查询和大规模的服务编排。要查看完整的功能,请参考salt execution模块的文档。
附加功能
Dashboard
Puppet使用Puppet dashboard. Salt目前没有图形化的界面。我知道,我们都大爱命令行。不过,有时看到满屏幕的绿色或是点点按钮也是很惬意的。 认真的讲,dashboard是获得你所管理的节点网络state概览的好工具。Salt的路线图中没有图形界面,希望最终会出现。
Returners
Returners是minion向master返回数据时调用的模块。不将返回数据传递给salt master,而是调用Returner模块来将数据发给其他服务,通常是数据库。Salt目前支持的returner,可以连接cassandra, mongo, redis和mysql. 也可以很容易的用Python脚本为其他服务写一个returner。
Salt Syndic
Salt文档将Salt Syndic描述为"一个可以构建Salt命令拓扑的强大工具“。实际意义上,Salt Syndic可以让一个运行Syndic服务的Salt master连接到更高层的master。
假设你有多个不同的Salt环境,每个环境都有一个master。这些环境可能是特的云或是有防火墙的网络。假设你想同时控制这几个环境中的minions。你可以在想要控制的master主机上安装Salt Syndic。Salt Syndic创建了传输接口,在最顶层的master看来,就像是控制了很多的minion,但配置状态实际上是传递给了多个master。可以将其想像为军队的命令传递系统。
集成测试
有两个采用现有测试框架的项目给Puppet增加测试功能,名字是cucumber-puppet (使用 Cucumber框架)和rspec-puppet (使用RSpec).
Salt采取的做法是通过一系列的集成类提供对集成测试的支持,roadmap中提到未来会使用Unittest2和pytest做单元测试。
自动化集成测试是持续性交付管道被忽视的领域,能有一些内建的支持是非常好的。这也是以后的博文中将探讨的有趣领域
结论
我的目的是看看Salt Stack是否能做为配置管理和系统命令编排的解决方案。我的方法是与Puppet中最常用的功能作比较,以探索Salt的功能。结论是很耀眼的。Salt Stack不仅自带了很多功能,且易于安装,使用,扩展。 很明显,Salt前途一片光明。
有用的链接
Saltstack主页: http://saltstack.org
Salt下载: http://saltstack.org/download/
Salt在GitHub: https://github.com/saltstack/salt
Salt开发者博客: http://red45.wordpress.com/
原文链接:opencredo.com
authoer: Maartens Lourens. 于1月10日发表在opencredo.
本文固定链接: http://www.sudops.com/another-tools-for-sa-of-saltstack.html | 运维·速度
http://www.opscoder.info/move_salt_master.html
一般在非不得已的情况下,我们都不会去干迁移salt master这种事的,因为这代价还是蛮大的,但之前还真坑爹的做了一回这事儿,在这儿记录下来,供大家参考。
其实现在已经有了salt ssh这种东西,它解决了salt中是先有鸡还是先有蛋的问题,运用在maste迁移上想必是极好的,但是我salt ssh还没有用起来,什么时候有空尝试一下,好,废话不说,言归正传。
我一开始是这么做迁移的:
1、搭建好新的salt master的环境,并启动;
2、批量修改minion端的配置文件,将master指向新的master,在老的master上运行:
salt cmd.run ” sed -i ‘s/master: old_master/master: new_master/g’ /etc/salt/minion”
多好,只要minion端不重启,那还是和老的master保持长连接的。
3、我们还得把老的master上的相关文件拷过来了,比如pillar什么的,我就直接把下面两个文件夹copy了:
/srv/salt/
/srv/pillar/
注:可能大家的地址不一样啦,看你们在配置文件中配的地址吧。
4、批量重启minion:
salt cmd.run "sudo /etc/init.d/salt-minion restart"
哈哈,转移阵地到新的master上去爽一把吧。
salt-key -A,把小弟拉过来,囧了,发现拉不过来。
才发现,在之中迁移的过程中有个很重要的操作没有执行,导致我们新的master无法正常连接到minion。
因为salt建立连接是要通过证书认证的,默认的配置是master端自动接收minion的证书,minion端存放的master相关的证书位置为:
/etc/salt/pki/minion/minion_master.pub
在该证书存在的情况下,更改master,也不会重新生成,进而导致证书不正确无法与master通信。
因此,在minion重启之前,需要先把/etc/salt/pki/minion/minion_master.pub删除掉。
好在我当时只有三十多台机器,我登上每一台机器上去执行:
“sudo rm -rf /etc/salt/pki/minion/minion_master.pub"
"sudo /etc/init.d/salt-minion restart"
其实也挺快的,我几分钟就刷完了。
最后给出正确的做法:
1、搭建好新的salt master的环境,并启动;
2、批量修改minion端的配置文件,将master指向新的master,在老的master上运行:
salt cmd.run ” sed -i ‘s/master: old_master/master: new_master/g’ /etc/salt/minion”
3、老的master上的相关文件拷过来;
4、删除minion上的认证证书:
salt cmd.run "sudo rm -rf /etc/salt/pki/minion/minion_master.pub"
5、批量重启minion:
salt cmd.run "sudo /etc/init.d/salt-minion restart"
6、把minion accept到新的master中:
salt-key -A
转载请注明出处:http://www.opscoder.info/move_salt_master.html
http://yoyolive.com/saltstack/2014/05/29/saltstack-base-service.html
对基础服务的管理包括配置管理系统、用户账号管理、yum配置管理、hosts文件管理、时间同步管理、DNS配置管理。
配置管理系统
配置管理系统使用模块化设计,每个服务一个模块,将多个模块组织到一起形成角色(/srv/salt/roles/)。所有模块放置到:/srv/salt下,入口配置文件为:/srv/salt/top.sls。模块使用的变量放置到:/srv/pillar,入口配置文件:/srv/pillar/top.sls。针对变量的作用域不同,将变量分为三级级,一级应用于模块(/srv/pillar/模块名),一级应用于角色(/srv/pillar/roles/),一级应用于主机节点(/srv/pillar/nodes)。具体配置在此不一一列出,具体参见salt配置文件。
入口配置/srv/salt/top.sls,直接引用各种角色:
base:
'*':
- roles.common
'admin.grid.mall.com':
- roles.admin
'ha.grid.mall.com':
- roles.ha
'web*.grid.mall.com':
- roles.web
'cache*.grid.mall.com':
- roles.cache
'mc*.grid.mall.com':
- roles.mc
'db*.grid.mall.com':
- roles.db
'search*.grid.mall.com':
- roles.search
'storage*'.grid.mall.com':
- roles.storage
变量入口配置文件/srv/pillar/top.sls:
base:
'*':
- roles.common
# 引用角色级变量
# 模块级变量在角色级变量中引用
'admin.grid.mall.com':
- roles.admin
'ha.grid.mall.com':
- roles.ha
'web*.grid.mall.com':
- roles.web
'cache*.grid.mall.com':
- roles.cache
'mc*.grid.mall.com':
- roles.mc
'db*.grid.mall.com':
- roles.db
'search*.grid.mall.com':
- roles.search
'storage*'.grid.mall.com':
- roles.storage
# 引用节点级变量
'ha1.grid.mall.com':
- nodes.ha1
'ha2.grid.mall.com':
- nodes.ha2
'mc1.grid.mall.com':
- nodes.mc1
'mc2.grid.mall.com':
- nodes.mc2
'db1.grid.mall.com':
- nodes.db1
'db2.grid.mall.com':
- nodes.db2
用户账号管理
用户管理模块:/srv/salt/users
此模块用到pillar,pillar和grains都可以用来获取变量,但是grains偏向于获取客户端相关信息,比如客户端硬件架构、cpu核数、操作系统版本等信息,相当于puppet的facter;pillar用于定义用户变量,通过pillar变量的传递,使salt state模块易于重用,相当于puppet的hiera。使用pillar变量之前需要执行salt '*' saltutil.refresh_pillar命令使变量生效。使用命令salt 'admin.grid.mall.com' pillar.item users获取users变量:
# salt 'admin.grid.mall.com' pillar.item users
admin.grid.mall.com:
----------
users:
----------
dongliang:
----------
fullname:
Shi Dongliang
gid:
1000
group:
dongliang
password:
$6$BZpX5dWZ$.......
shell:
/bin/bash
ssh_auth:
----------
comment:
dongliang@leju.com
key:
AAAAB3......==
sudo:
True
uid:
1000
获取admin.grid.mall.com上面定义的所有pillar变量:
# salt 'admin.grid.mall.com' pillar.items
添加用户:
/srv/salt/users/user.sls用于管理用户
sudo.sls为用户添加sudo权限:
sudoers:
file.managed:
- name: /etc/sudoers
/srv/salt/users/user.sls读取/srv/pillar/users/init.sls中的users变量。
users:
dongliang: # 定义用户名
group: dongliang # 用户所在组
uid: 1000 # 用户uid
gid: 1000 # 用户gid
fullname: Shi Dongliang
password: $6$BZpX5dWZ$...... # 密码,注意是hash后的密码
shell: /bin/bash # 用户shell
sudo: true # 是否给sudo权限
ssh_auth: # 无密码登录,可选项
key: AAAAB3......==
comment: dongliang@mall.com
在salt-master上执行下面命令使配置生效
# salt '' saltutil.refresh_pillar
# salt '' state.highstate
yum配置管理
yum配置管理:/srv/salt/base/repo.sls
配置文件:/srv/salt/base/files/mall.repo # 此配置文件可以通过salt协议下发到客户端
/srv/salt/base/repo.sls定义,管理mall.repo文件,当文件改变后执行yum clean all清理缓存,是配置生效。
/etc/yum.repos.d/mall.repo:
file.managed:
- source: salt://base/files/mall.repo
- user: root
- group: root
- mode: 644
- order: 1
cmd.wait:
- name: yum clean all
- watch:
- file: /etc/yum.repos.d/mall.repo
hosts文件管理
hosts文件管理:/srv/salt/base/hosts.sls
/srv/salt/base/hosts.sls 定义了每个主机名和IP的对应关系。如下:
admin.grid.mall.com:
host.present:
- ip: 172.16.100.81
- order: 1
- names:
- admin.grid.mall.com
时间同步管理
时间同步作为一个cron,定义文件为:/srv/salt/base/crons.sls
# 引用ntp模块
include:
- ntp
'/usr/sbin/ntpdate 1.cn.pool.ntp.org 1.asia.pool.ntp.org':
cron.present:
- user: root
- minute: 0
- hour: 2
ntp模块:ntp/init.sls
# 安装ntpdate软件包
ntpdate:
pkg.installed:
- name: ntpdate
DNS配置管理
配置DNS服务器定义在resolv.sls,控制/etc/resolv.conf配置文件:
/etc/resolv.conf:
file.managed:
- source: salt://base/files/resolv.conf
- user: root
- group: root
- mode: 644
- template: jinja
http://www.wudiweb.com/tech/topics/355131
目录树
引言:一个”非专职运维人员“的烦恼
这来自两种情况:
1. 自主开发的应用,需要持续的改进,不断的更新、发布、部署、调整配置,这不是运维部门喜欢的状态。
2. 软件商提供的“产品”无法满足运维部门的要求:无法通过简单的 Q&A 文档保证系统的正常运行,经常需要有一定技术能力的人员解决系统运行过程中各种稀奇古怪的问题。
这种情况下只能自己做一个“非专职运维人员”,需要频繁的登录各种服务器,执行一些命令来查看状态或者更改配置(包括配置文件的变更和软件包的安装部署)。很多操作都是不断的重复,日复一日,让人厌烦。
”重复的工作应该交给程序去做“,所以我自己写过一些脚本。为了避免将脚本上传到几十台服务器并且不时进行更改,我使用Fabric来进行服务器的批量操作。
尽管避免了”批量的人工操作“,但我还是在进行”人工的批量操作“。远远没有实现自动管理。将有限的生命解放出来,投入到更有意义的编码工作是一个奔四程序员应有的追求,所以我又睁大红肿的眼睛,迷茫的搜索这个世界。
我发现了Puppet,Chef和CFEngine,但是并不满意。直到我发现了Salt,我的眼前一亮:这正是我所需要的东西。
如果说Salt有什么独特之处打动了我,那就是:
简单:可能是源于python的简约精神,Salt的安装配置和使用简单到了令人发指的地步。任何稍有经验的linux使用者可以在10分钟之内搭建一个测试环境并跑通一个例子(相比之下,puppet可能需要30--60分钟)。
高性能:Salt使用大名鼎鼎的ZeroMQ作为通讯协议,性能极高。可以在数秒钟之内完成数据的传递
可伸缩:基于ZeroMQ通信,具备很强的扩展性;可以进行分级管理,能够管理分布在广域网的上万台服务器。
尽管twitter、豆瓣、oracle、等著名网站的运维团队都在使用puppet,但是我相信,他们切换到salt只是一个时间问题。毕竟不是所有的人都喜欢操纵傀儡(puppet),但是谁又能离开盐(salt)呢?
关于Salt和Puppet的对比,可以参考这里,或者看看中文版。
Salt快速入门
1. master: 老大,管理端
2. minion: 马仔,被管理端
3. syndic: 头目,对于老大来说是马仔,对于马仔来说是老大
在入门阶段,先不考虑syndic。
1. 安装配置
*NIX
Linux
Solaris
HP Unix
FreeBSD
OS X
windows
理论上来说,Salt可以安装在任何*NIX系统上,包括master和minion。除了源代码之外, 还可以通过Salt提供的安装脚本,或者PyPI进行安装。
对于Linux,尤其是企业环境中常用的RHEL,CentOS,Ubuntu,可以通过包管理器非常容易的安装master 和/或 minion。 比如: yum(需要先配置EPEL), apt(需要增加http://debian.madduck.net/repo/库),yaourt,ports。
Mac OS X 先使用HomeBrew解决依赖包:brew install swig zmq,然后用PyPI安装:pip install salt。
对于windows,只能安装minion(windows只适合做马仔)。从官方网站下载合适的安装包。安装过程中可以指定master地址和本机名称。 安装后需要自己启动Salt服务。配置文件在C:\salt\conf\minion。
具体的各操作系统下的安装可以参考官方文档。这里为了简单,只考虑常用的RHEL/CentOS 和 windows。 在下面的例子中,使用一台RHEL/CentOS作为master, 另外一台RHEL/CentOS和一台windows 2003 Server作为 minion。
2. 安装管理端(master)
- # 安装EPEL,注意选择合适的版本
- rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
- yum update
- # 安装master
- yum install salt-master
- # 修改配置
- vim /etc/salt/master
- # 最基本的设定服务端监听的IP(比如使用VIP做master的高可用时):
- # interface: 服务端监听IP
- # 其他配置参考[官方文档](http://docs.saltstack.com/ref/configuration/master.html)
- # 启动服务(以下命令等效)
- salt-master -d
- /etc/init.d/salt-master start
- service salt-master start
3. 安装被管理端(minion)
- # 安装EPEL,注意选择合适的版本
- rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
- yum update
- # 安装minion
- yum install salt-minion
- # 修改配置
- vim /etc/salt/minion
- # 最基本的设定是指定master地址,以及本机标识符:
- # master: master的主机名或IP地址
- # id: 本机标识符
- # 其他配置参考[官方文档](http://docs.saltstack.com/ref/configuration/minion.html)
- # 启动服务(以下命令等效)
- salt-minion -d
- /etc/init.d/salt-minion start
- service salt-minion start
4. 接受minion的托管请求
Salt底层使用公钥-私钥证书来保证通信信道的安全。具体的机制可以参考ZeroMQ的相关内容。Salt已经屏蔽了底层的细节,只需要使用封装好的命令:
- # 在master上运行
- # 查看所有minion
- salt-key -L
- Accepted Keys:
- windows
- bond_app_server_main
- mac_os_vm
- salt-master
- Unaccepted Keys:
- minion1
- minion2
- Rejected Keys:
- #其中Unaccepted Keys是未许可的minion。可以使用下面的命令通过认证:
- salt-key -a minion1
5. 测试
再举一些例子:
- # 查询主机运行了多长时间
- sudo salt '*' cmd.run "uptime"
- # 批量重启服务
- salt '*' cmd.run "service httpd restart"
- # 让多台机器一起,使用Apache Bench进行压力测试
- salt '*' cmd.run "ab -n 10 -c 2 http://www.google.com/"
1. 4505(publish_port): salt的消息发布系统
2. 4506(ret_port):salt客户端与服务端通信的端口
网络的设置需要保证这些端口可以访问。
Salt的强大功能
认真分析一下我的“非专职运维工作”的内容,发现可以分为以下三个方面:
1. 变更操作:根据需要对节点中某个资源的某种状态进行调整,并检验变更的结果
2. 配置管理:让上述行为变得“可管理”,支持“有关人士”对上述行为的标记、控制、识别、报告、跟踪和归档甚至审批和审计
3. 状态监控:随时掌握状态,发现异常。尽量在系统用户发现问题之前解决麻烦
Salt对上述三个方面提供了完美的支持,事实上,Salt提供的功能比我需要的还要多。下图是Salt的主要功能:
如果想对Salt的功能和使用有一个初步的了解,最好参考官方文档:Salt Stack Walkthrough。
1. 批量操作(targeting)
- # 测试连通性
- salt '*' test.ping
- # 查询主机运行了多长时间
- sudo salt '*' cmd.run "uptime"
- # 批量重启服务
- salt '*' cmd.run "service httpd restart"
- # 让多台机器一起,使用Apache Bench进行压力测试
- salt '*' cmd.run "ab -n 10 -c 2 http://www.google.com/"
默认:通配符(globbing))
* E:正则表达式(Regular Expression)
* L:列表
* N: 分组(group)
* C:复合匹配
先看一下通配符、正则表达式和列表的例子:
- # 通配符是最常用的匹配方式。Salt使用[linux风格的通配符](http://docs.python.org/2/library/fnmatch.html)
- salt '*' test.ping
- salt '*.example.net' test.ping
- salt '*.example.*' test.ping
- salt 'web?.example.net' test.ping
- salt 'web[1-5]' test.ping
- salt 'web-[x-z]' test.ping
- # 正则表达式可以适应更复杂的情况。使用[python的re模块](http://docs.python.org/2/library/re.html#module-re)进行匹配
- salt -E 'web1-(prod|devel)' test.ping
- # 最直接的方式是自己指定多个minion,即列表
- salt -L 'web1,web2,web3' test.ping
2. 节点分组(nodegroups)
group 的定义可以使用各种匹配规则,比如:
- group1: 'L@foo.domain.com, bar.domain.com,baz.domain.com or bl*.domain.com'
- group2: 'G@os:Debian and foo.domain.com'
3. 命令执行(execution)
Salt即可以批量执行命令,也可以单机执行。通常单机执行用于测试:
1. 单机(立即)执行。 使用salt-call命令单机执行操作
2. 批量(立即)执行。最常用的操作。使用salt命令,对匹配的minion节点执行操作
Salt可以执行的命令也可以分为两种:
1. 系统命令,使用cmd.run执行
2. Salt模块,将常用的命令/批处理封装到内置的Salt模块(module),使用模块名.功能名的方式执行。
比如:
- # 执行系统命令
- salt '*' cmd.run 'hostname'
- # 执行Salt模块
- salt '*' disk.usage
Salt已经内置了大量的模块,这些模块涵盖了日常管理任务的主要任务,包括:
1. 通用的管理任务,比如apt, at, cp, cron, disk, extfs, file, grains, hosts, iptables, mount, network, pam, parted, pkg, ps, selinux, shadow, ssh, test等
2. 针对特定软件的任务,比如apache, cassandra, djangomod, git, mongodb, mysql, nginx, nova, postgres, solr, sqlite3, 和tomcat
而且,自己开发Salt模块也非常简单,很容易将实际管理操作中的一些经验通过自定义的模块固化下来,并方便分享。
在开发和调试模块的时候,可以使用test=True参数进行模拟执行(Dry run)。比如:
- salt 'minion1.example.com' state.highstate -v test=True
4. 节点信息(grains)
grains的基本使用举例如下:
- # 查看grains分类
- salt '*' grains.ls
- # 查看grains所有信息
- salt '*' grains.items
- # 查看grains某个信息
- salt '*' grains.item osrelease
5. 配置管理(state)
Salt中可以定义节点的目标状态,称之为state。state对应配置管理中的配置,可以对其进行标识、变更控制、变更识别、状态报告、跟踪和归档以及审计等一些的管理行为。
状态描述
Salt使用SLS文件(SaLt State file)描述状态。SLS使用YAML格式进行数据序列化,因此简单明了,可读性也很高。
基本描述(yaml)
下边是一个简单的SLS文件例子:
- apache:
- pkg:
- - installed
- service:
- - running
- - require:
- - pkg: apache
该文件描述一个ID为apache的配置状态:
1. 软件包(pkg)已经安装
2. 服务应该处于运行中
3. 服务的运行依赖于apache软件包的安装
state文件中的所有YAML变量名来自Salt的state模块。
Salt内置了大量的state模块,比如cron, cmd, file, group, host, mount, pkg, service, ssh_auth,user等。 详细清单参考这里。
还可以开发自己的state模块。
扩展描述(jinja)
state可以使用jinja模板引擎进行扩展,其语法可以参考这里。
下面是一个更复杂的例子:
- vim:
- pkg:
- { % if grains['os_family'] == 'RedHat' % }
- - name: vim-enhanced
- { % elif grains['os'] == 'Debian' % }
- - name: vim-nox
- { % elif grains['os'] == 'Ubuntu' % }
- - name: vim-nox
- { % endif % }
- - installed
该state增加了判断逻辑:如果是redhard系列的就安装 vim-enhanced,如果系统是Debian或者Ubuntu就安装vim-nox。
逻辑关系
state之间可以有逻辑关系。常见的关系举例如下:
1. require:依赖某个state,在运行此state前,先运行依赖的state,依赖可以有多个
- httpd:
- pkg:
- - installed
- file.managed:
- - name: /etc/httpd/conf/httpd.conf
- - source: salt://httpd/httpd.conf
- - require:
- - pkg: httpd
watch:在某个state变化时运行此模块
- redis:
- pkg:
- - latest
- file.managed:
- - source: salt://redis/redis.conf
- - name: /etc/redis.conf
- - require:
- - pkg: redis
- service.running:
- - enable: True
- - watch:
- - file: /etc/redis.conf
- - pkg: redis
watch除具备require功能外,还增了关注状态的功能
3. order:优先级比require和watch低,有order指定的state比没有order指定的优先级高
- vim:
- pkg.installed:
- - order: 1
想让某个state最后一个运行,可以用last
保存状态
状态描述文件(SLS)要保存在master节点中,并通过指令分发到minion节点。
1. 路径设置
Salt master的配置文件(/etc/salt/master)中可以通过file_roots参数指定状态文件的保存路径。可以为不同的环境(如开发环境、UAT环境、生产环境、灾备环境等)分别指定路径,如下所示:
- file_roots:
- base:
- - /srv/salt/
- dev:
- - /srv/salt/dev/services
- - /srv/salt/dev/states
- prod:
- - /srv/salt/prod/services
- - /srv/salt/prod/states
其中,base环境是必须的。
2. 入口文件
file_roots中必须指定“base”环境的路径,因为该路径中存在Salt state的入口文件: top.sls。
Top文件建立配置环境、节点和状态配置之间的映射关系。比如一个简单的top.sls文件:
- base:
- '*':
- - servers
- dev:
- '*nodb*':
- - mongodb
该文件指定了: - 所有节点使用base环境的servers配置 - nodb节点使用dev环境的mongodb配置
结合第一部分的file_roots配置,该top配置意味存在以下的配置文件:
- /srv/salt/servers.sls
- /srv/salt/dev/mongodb.sls
注:这里也可以使用文件夹/srv/salt/servers/和/srv/salt/dev/mongodb/,在文件夹中放置一组状态文件和配置文件,便于建立复杂的状态配置。
top.sls中的可配置内容非常丰富,具体内容可以参考官方文档。
状态生效(State Enforcement)
master上对状态进行定义,最终这些状态要传递到minion节点上。在本节的例子中,如果定义好了状态文件/srv/salt/dev/mongodb.sls:
- mongodb:
- pkg:
- - installed
可以使用命令salt "minion1" state.highstate -v使得所有针对"minion1"的state生效;
在执行状态之前先进行测试是个好主意,需要指定参数test=True。比如,salt "minion1" state.highstate -v test=True。
关于state模块的更多用法,可以参考state模块说明,或官方文档。
更多
Salt的state模块的功能不仅如此,还可以使用模板和变量,以及定义状态的定时自动生效。
6. 小结
后续会介绍一些使用案例以及Salt的高级功能。
Salt state实例解析
1. 目录结构
- apache/init.sls
- apache/httpd.conf
- ssh/init.sls
- ssh/server.sls
- ssh/banner
- ssh/ssh_config
- ssh/sshd_config
- ssh/custom-server.sls
2. apache/init.sls
- apache:
- pkg:
- - installed
- service:
- - running
- - watch:
- - pkg: apache
- - file: /etc/httpd/conf/httpd.conf
- - user: apache
- user.present:
- - uid: 87
- - gid: 87
- - home: /var/www/html
- - shell: /bin/nologin
- - require:
- - group: apache
- group.present:
- - gid: 87
- - require:
- - pkg: apache
- /etc/httpd/conf/httpd.conf:
- file.managed:
- - source: salt://apache/httpd.conf
- - user: root
- - group: root
- - mode: 644
- - template: jinja
- - context:
- custom_var: "override"
- - defaults:
- custom_var: "default value"
- other_var: 123
1. sls文件使用YAML格式定义,最外面的层级定义配置项。
2. 一个sls文件中可以有多个配置项,配置项的ID可以起任意的名字。本例中包含ID为apache和/etc/httpd/conf/httpd.conf两个配置项。
3. 配置项内是一系列的状态声明。所有的状态项来自Salt状态模块。即可以使用Salt内置的状态模块,也可以编写自定义的状态模块
4. 状态声明内部指定状态函数的调用。状态函数是每个Salt状态模块中定义的函数。
5. apache配置项
1) pkg模块,使用操作系统的包管理器(如yum, apt-get)安装软件包
salt.states.pkg.installed函数, 验证软件包是否安装以及是否为指定的版本
2) service模块管理服务/守护进程(daemon)的启动或停止
salt.states.service.running函数检查服务是否已经启动
service模块定义了salt.states.service.mod_watch函数,可以使用watch要素监控其他的模块是否满足。这里监控以下情况:
apache软件包(pkg)是否已安装
/etc/httpd/conf/httpd.conf文件(file)是否存在
apache用户(user)是否存在
user.present是简写形式,直接调用user模块的present函数检查是否存在如下属性的apache用户:
uid=87
gid=87
home目录为/var/www/html
登录脚本为/bin/nologin
检查依赖项:apache用户组
group.present是简写形式,直接调用group模块的present函数检查是否存在如下属性的apache用户组:
gid=87
检查依赖项:apache软件包
6. /etc/httpd/conf/httpd.conf配置项
file.managed是简写形式,直接调用file模块的managed方法根据需要从master获取文件并可能会通过模板系统(templating system)进行渲染。文件要满足如下要求:
- 使用master上面的apache/httpd.conf文件
- user=root
- group=root
- mode=644
- 使用jinja模板渲染
- 上下文变量:
- custom_var="override"
- 默认值:
- custom_var="default value"
- other_var=123
3. ssh/init.sls
- openssh-client:
- pkg.installed
- /etc/ssh/ssh_config:
- file.managed:
- - user: root
- - group: root
- - mode: 644
- - source: salt://ssh/ssh_config
- - require:
- - pkg: openssh-client
4. ssh/server.sls
- include:
- - ssh
- openssh-server:
- pkg.installed
- sshd:
- service.running:
- - require:
- - pkg: openssh-client
- - pkg: openssh-server
- - file: /etc/ssh/banner
- - file: /etc/ssh/sshd_config
- /etc/ssh/sshd_config:
- file.managed:
- - user: root
- - group: root
- - mode: 644
- - source: salt://ssh/sshd_config
- - require:
- - pkg: openssh-server
- /etc/ssh/banner:
- file:
- - managed
- - user: root
- - group: root
- - mode: 644
- - source: salt://ssh/banner
- - require:
- - pkg: openssh-server
1. include语句将别的state添加到当前文件中,使得state可以跨文件引用。
使用include相当于把被引用的内容文件添加到自身,可以require、watch或extend被引用的SLS中定义的内容。
这里引用了sshstate。
2. openssh-server配置项
3. sshd
4. /etc/ssh/sshd_config配置项
5. /etc/ssh/banner配置项
5. ssh/custom-server.sls
- include:
- - ssh.server
- extend:
- /etc/ssh/banner:
- file:
- - source: salt://ssh/custom-banner
1. 引用sshstate的server配置项
2. extend可以复用已有的state,在原来的基础上进行扩展,增加新的配置或修改已有的配置。
将/etc/ssh/banner配置项的文件修改为salt://ssh/custom-banner
之前的几篇记录了salt的安装、配置、以及各个模块的使用,今天主要基于salt的grains和pillar自动化部署squid缓存服务。
动手之前先确定下当前需求:
- 我们有两个机房,两个机房的ip地址是不同的,一个是10.10.开头,另外一个是10.20.开头;
- 10.10.开头的机房主要用来缓存js、css等,另外一个机房的squid机器主要用来缓存图片,这两个的配置文件肯定是不同的
- 缓存图片服务的squid机器硬盘大小不同,也就是说要做的cache大小肯定也是不同的
- 机器的内存并不是统一大小
整理如下:
1.首先要通过salt自动安装squid服务
2.要自己编写grains模块收集机器的内存和硬盘大小
3.要使用pillar确认机器的ip地址是以什么开头的,以此来确认是用来缓存的具体对象
4.整理具体配置分发到不同服务的squid配置文件内
一、先整理squid的安装包
自己整理好的squid-2.7的rpm包,通过yum的方式来安装
编写state.sls文件
在根目录下/srv/salt下进行,vim squid.sls
squid:
pkg:
- name: ajk-squid #我自己打的rpm包
- installed
user.present: #检测用户,如果没有就创建 squid用户,设置为nologin状态
- home: { { pillar['squid_home_dir'] }}
- shell: /sbin/nologin
- require:
- group: squid
group.present: #用户组squid 和用户对应
- name: squid
- require:
- pkg: ajk-squid
service.running: #这里保持squid服务是正常运行的状态
- enable: True
- reload: True
- require:
- file: /etc/init.d/squid #squid的启动脚本,也是打包在安装包内的,检测下面的watch内的服务,有变化就执行
- watch:
- file: { { pillar['squid_conf_dir'] }}/squid.conf
{ { pillar['squid_conf_dir'] }}/squid.conf:
file.managed:
- source: salt://files/squid/squid.conf # 定义salt内的squid.conf配置文件
- user: root
- mode: 644
- template: jinja #使用jinja模板,这里是为了配置文件内使用pillar
- require:
- pkg: ajk-squid #依赖关系
{ { pillar[squid_home_dir] }} 这里在pillar内定义好的,我是为了美观方便;之前填写下面的目录也是可以的
squid_home_dir: /usr/local/squid-2.7
squid_conf_dir: /usr/local/squid-2.7/etc
目前,squid服务的state.sls模块就已经写好了
二、收集服务器端的硬件信息
还是要使用python脚本,在_grains下面编写脚本,编写脚本前确认下配置;我的需求是squid的内存设置为总内存的45%,我squid的硬盘会有三块,挂载为目录cache1、cache2、cache3 。每块盘取90%,如果90%之后大于65G,直接取值65,少于65的话,直接使用90%的值。
脚本如下:
vim squid.py
# -*- coding: utf-8 -*-
'''
Module for squid disk information by python2.7.3
'''
import commands
import os
def cache():
'''
Return the cache usage information for volumes mounted on this minion
'''
grains={}
m = commands.getoutput("free -g|awk '$0~/Mem/ {print$2+1}'")
grains['cache_mem_size']=int(int(m)*(0.45))
file = commands.getoutput("df -Th |awk '{print$7}'")
cache = 'cache'
if cache in file:
a = commands.getoutput("df -Th |grep cache |awk 'NR==1 {print$3}' |sed 's/G//g'")
b = int(int(a)*(0.9))
if b > = 65:
grains['cache_disk_size'] = 65*1024
else:
grains['cache_disk_size'] = int(b*1024)
else:
grains['cache_disk_size'] = 'The cache of partition does not exist'
return grains
我的squid机器在salt上面定义了一个组:
root@salt _grains # cat /etc/salt/master.d/nodegroups.conf
nodegroups:
squid_20: 'cdn20-*'
‘然后,加载编写的模块,命令如下 :
salt -N squid_20 saltutil.sync_all
查询编写的模块取值,根据disk信息取值:
root@salt _grains # salt -N 'squid_20' grains.item cache_disk_size
cdn20-005:
cache_disk_size: 43008
cdn20-001:
cache_disk_size: 66560
查询内存信息取值:
root@salt _grains # salt -N 'squid_20' grains.item cache_mem_size
cdn20-005:
cache_mem_size: 7
cdn20-001:
cache_mem_size: 14
三、编写squid.conf的配置文件
根据上文的目录定义,路径在/srv/salt/files/squid下
vim squid.conf
{ % if grains['ip_interfaces'].get('eth0')[0].startswith('10.20') %}
...........省略具体配置
## MEMORY CACHE OPTIONS
cache_mem { { grains['cache_mem_size'] }} GB #内存的大小
## DISK CACHE OPTIONS
cache_dir aufs /cache1 { { grains['cache_disk_size'] }} 16 256 #cache的大小
cache_dir aufs /cache2 { { grains['cache_disk_size'] }} 16 256
cache_dir aufs /cache3 { { grains['cache_disk_size'] }} 16 256
visible_hostname{ { grains['host'] }} #机器名
{ % else %} (#去掉)
缓存js等的配置文件,此处省略
{ % endif %}(#去掉)
这里只是说明下salt需要配置的东西,至于squid具体的配置文件,这里就不多说了
当然,上述的判断可以在pillar里面做完而不用在配置文件的时候做判断,只不过我感觉那样要多一层逻辑,就直接判断了 ··· 其实是我比较懒····
这样,一个squid的基本安装配置基本就成功了,可以找机器进行测试
后续,添加机器的话,可以进行直接部署了
http://www.tuicool.com/articles/m6NjeqR
今天在查找salt中pillar嵌套pillar的方法时,无意之间发现了pillar除了可以直接使用文件(sls)外,也同时支持多种后端的数据存储方式。例如:mysql, mongodb, ldap, json, cobbler甚至是puppet。这无疑为开发中的接口提供了极大的便利。
详细的支持列表可见:http://docs.saltstack.com/en/latest/ref/pillar/all/index.html#all-salt-pillars。
严格意义上来说,这篇博文并非完全原创,英文原文请参考:http://www.tmartin.io/articles/2014/salt-pillar-mongodb/。
下面就来说说详细的配置方式,假定你已经有了一个部署好的salt环境,并且正确配置了salt master和salt minion,并且完成认证,主机名为salt-master.salt.com,这里我们使用Ubuntu 12.04 64bit作为演示环境。
安装MongoDB和Python MongoDB
apt-get install mongodb python-pymongo python-pymongo-ext
确保你能连接到MongoDB
# mongo
MongoDB shell version: 2.2.3
connecting to: test
>
创建MongoDB数据库和存放Pillar的Collection
创建数据库pillar
use pillar
在数据库中插入pillar数据db.pillar.insert({
_id: 'salt-master.salt.com',
mongo_pillar: {
key1: "value1",
key2: "value2",
}})
注意:这里的_id必须要和你的minion节点的主机名一致,并且 无法使用通配符,也就是一个节点都有自己一套独立的pillar,这一点和文件中定义pillar有很大的不同 。mongo_pillar部分中是定义的是pillar中的内容,也就是我们可以直接引用的部分。配置Salt Master
下一步就是告诉Salt Master,我们在MongoDB中存放了pillar数据,需要劳您大驾,移步MongoDB读取数据。修改:
/etc/salt/master添加
mongo.db: "pillar"
mongo.host: "localhost"
ext_pillar:
- mongo: {}
注意:如果需要使用不同于标准安装接口,请使用mongo.port,如果需要配置用户名和密码,请使用mongo.user和mongo.password。其他参数定义,请详见:http://docs.saltstack.com/en/latest/ref/pillar/all/salt.pillar.mongo.html#module-documentation。测试
salt salt-master.salt.com pillar.item mongo_pillar返回
salt-master.salt.com:
----------
mongo_pillar:
----------
key1:
value1
key2:
value2
如果想在sls中直接使用{{ salt['pillar.get']('mongo_pillar:key1') }}
总结
pillar应该是salt中一个比较灵活的配置选项,个人理解pillar的作用就像puppet中init定义的初始化的参数的默认值,每次部署时,只需要更改pillar的文件就可以啦。但是随着代码的增长(主要用于部署OpenStack),发现pillar的管理越来越难,pillar本身对如何组织结构并没有严格的限制,而且嵌套(extend)功能暂时还不能很完美的支持(https://github.com/saltstack/salt/issues/3991),这也给pillar的管理提高了复杂度。
http://blog.opmacloud.com/2014/06/%E4%BD%BF%E7%94%A8saltstack%E7%AE%A1%E7%90%86%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E3%80%81%E9%83%A8%E7%BD%B2nginx%E3%80%81zabbix/
使用saltstack管理配置文件、部署nginx、zabbix
看下saltstack的目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
[root@manager srv]# pwd /srv [root@manager srv]# tree . ├── pillar │ ├── nginx │ │ └── vhost.sls │ └── top.sls └── salt ├── base │ ├── base.sls │ ├── hosts │ └── limits.conf ├── _grains ├── nginx │ ├── conf.sls │ ├── files │ │ ├── nginx │ │ ├── nginx_ajp_module-master.zip │ │ ├── nginx.conf │ │ ├── nginx_log_cut.sh │ │ ├── tengine-2.0.2.tar.gz │ │ └── vhost │ │ ├── lens.networkbench.com.conf │ │ └── newlens-api.networkbench.com.conf │ ├── install.sls │ └── vhost.sls ├── ssh │ ├── client.sls │ ├── server.sls │ ├── ssh_config │ └── sshd_config ├── top.sls └── zabbix ├── conf_d.sls ├── conf.sls ├── files │ ├── zabbix-2.2.1.tar.gz │ ├── zabbix_agentd │ ├── zabbix_agentd.conf │ └── zabbix_agentd.conf.d │ ├── io.conf │ └── iostat.conf └── install.sls 12 directories, 28 files |
从top文件逐个说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@manager salt]# cat top.sls base: '*': - base.base - ssh.client - ssh.server - zabbix.install - zabbix.conf - zabbix.conf_d 'lens1,lens2': - match: list - nginx.install - nginx.conf - nginx.vhost |
base.sls主要是一些基本软件包的安装和一些系统配置文件的集中管理,sshclient和sshserver是对openssh配置文件集中管理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[root@manager salt]# cat base/base.sls vim-enhanced: pkg: - name: vim-enhanced - installed unzip: pkg: - name: unzip - installed /etc/hosts: file.managed: - source: salt://base/hosts - user: root - group: root - mode: 644 - backup: minion /etc/security/limits.conf: file.managed: - source: salt://base/limits.conf - user: root - group: root - mode: 644 - backup: minion |
下面看下zabbix的安装,这里采用的是编译安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[root@manager salt]# cat zabbix/install.sls zabbix_source: file.managed: - name: /var/tmp/zabbix-2.2.1.tar.gz - unless: test -e /var/tmp/zabbix-2.2.1.tar.gz - source: salt://zabbix/files/zabbix-2.2.1.tar.gz extract_zabbix: cmd.run: - cwd: /var/tmp - names: - tar xvf zabbix-2.2.1.tar.gz - unless: test -d /var/tmp/zabbix-2.2.1 - require: - file: zabbix_source zabbix_user: user.present: - name: zabbix - uid: 1501 - createhome: False - gid_from_name: True - shell: /sbin/nologin zabbix_pkg: pkg.installed: - pkgs: - gcc zabbix_compile: cmd.run: - cwd: /var/tmp/zabbix-2.2.1 - names: - ./configure --prefix=/opt/zabbix --enable-agent; make -j4; make install - require: - cmd: extract_zabbix - pkg: zabbix_pkg - unless: test -d /opt/zabbix |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[root@manager salt]# cat zabbix/conf.sls zabbix_log_dir: cmd.run: - names: - mkdir /opt/zabbix/log - require: - cmd: zabbix_compile - unless: test -d /opt/zabbix/log zabbix_conf: file.managed: - name: /opt/zabbix/etc/zabbix_agentd.conf - source: salt://zabbix/files/zabbix_agentd.conf - template: jinja zabbix_log: file.managed: - name: /opt/zabbix/log/zabbix_agentd.log - user: zabbix - group: zabbix - mode: 644 zabbix_service: file.managed: - name: /etc/init.d/zabbix_agentd - user: root - mode: 755 - source: salt://zabbix/files/zabbix_agentd cmd.run: - names: - /sbin/chkconfig zabbix_agentd on - unless: /sbin/chkconfig --list zabbix_agentd service.running: - name: zabbix_agentd - enable: True - watch: - file: /opt/zabbix/etc/zabbix_agentd.conf - file: /opt/zabbix/etc/zabbix_agentd.conf.d/*.conf |
conf_d.sls存放的是zabbix_agentd.conf.d目录下的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[root@manager salt]# cat zabbix/conf_d.sls zabbix_agentd.conf.d_io: file.managed: - name: /opt/zabbix/etc/zabbix_agentd.conf.d/io.conf - source: salt://zabbix/files/zabbix_agentd.conf.d/io.conf - watch_in: service: zabbix zabbix_agentd.conf.d_iostat: file.managed: - name: /opt/zabbix/etc/zabbix_agentd.conf.d/iostat.conf - source: salt://zabbix/files/zabbix_agentd.conf.d/iostat.conf - watch_in: service: zabbix |
下面是nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
[root@manager salt]# cat nginx/install.sls nginx_source: file.managed: - name: /var/tmp/tengine-2.0.2.tar.gz - unless: test -e /var/tmp/tengine-2.0.2.tar.gz - source: salt://nginx/files/tengine-2.0.2.tar.gz ajp_source: file.managed: - name: /var/tmp/nginx_ajp_module-master.zip - unless: test -e /var/tmp/nginx_ajp_module-master.zip - source: salt://nginx/files/nginx_ajp_module-master.zip extract_nginx: cmd.run: - cwd: /var/tmp - names: - tar xvf tengine-2.0.2.tar.gz - unzip nginx_ajp_module-master.zip - unless: test -d /var/tmp/tengine-2.0.2 - unless: test -d /var/tmp/nginx_ajp_module-master - require: - file: nginx_source - file: ajp_source nginx_user: user.present: - name: nginx - uid: 1500 - createhome: False - gid_from_name: True - shell: /sbin/nologin nginx_pkg: pkg.installed: - pkgs: - gcc - openssl-devel - pcre-devel - zlib-devel - unzip nginx_compile: cmd.run: - cwd: /var/tmp/tengine-2.0.2 - names: - ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_upstream_check_module --add-module=/var/tmp/nginx_ajp_module-master/;make -j4;mak install - require: - cmd: extract_nginx - pkg: nginx_pkg - unless: test -d /opt/nginx |
nginx的配置文件和脚本管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
[root@manager salt]# cat nginx/conf.sls {% set nginx_user = 'nginx' %} nginx_conf: file.managed: - name: /opt/nginx/conf/nginx.conf - source: salt://nginx/files/nginx.conf - template: jinja - defaults: nginx_user: {{ nginx_user }} nginx_vhost_dir: cmd.run: - names: - mkdir /opt/nginx/conf/vhost - require: - cmd: nginx_compile - unless: test -d /opt/nginx/conf/vhost nginx_service: file.managed: - name: /etc/init.d/nginx - user: root - mode: 755 - source: salt://nginx/files/nginx cmd.run: - names: - /sbin/chkconfig nginx on - unless: /sbin/chkconfig --list nginx service.running: - name: nginx - enable: True - reload: True - watch: - file: /opt/nginx/conf/nginx.conf - file: /opt/nginx/conf/vhost/*.conf nginx_log_cut: file.managed: - name: /opt/nginx/sbin/nginx_log_cut.sh - user: root - mode: 755 - source: salt://nginx/files/nginx_log_cut.sh cron.present: - name: /opt/nginx/sbin/nginx_log_cut.sh - user: root - minite: 10 - hour: 0 - require: - file: nginx_log_cut |
nginx conf的模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
[root@manager salt]# cat nginx/files/nginx.conf user {{ nginx_user }}; worker_processes auto; worker_cpu_affinity auto; worker_rlimit_core 768m; worker_rlimit_nofile 65536; working_directory /opt/nginx/logs; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections 65535; use epoll; } http { include mime.types; default_type text/plain; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" $request_time ' '"$host" "$upstream_addr" "$upstream_status" "$upstream_response_time"'; log_format main1 '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" $request_time ' '"$host" "$upstream_addr" "$upstream_status" "$upstream_response_time" ' '$ssl_protocol $ssl_cipher'; access_log off; sendfile on; tcp_nopush on; client_max_body_size 20M; client_body_buffer_size 32k; client_header_timeout 25; max_ranges 10; send_timeout 15; keepalive_timeout 0; server_name_in_redirect off; server_tokens off; gzip on; gzip_buffers 32 4k; gzip_comp_level 9; gzip_disable "msie6"; gzip_http_version 1.0; gzip_min_length 800; gzip_proxied any; gzip_types text/css application/x-javascript text/plain application/json; gzip_vary on; proxy_buffers 64 4k; proxy_connect_timeout 3s; proxy_hide_header ETag; proxy_http_version 1.1; proxy_intercept_errors on; proxy_max_temp_file_size 0; proxy_next_upstream error timeout http_502 http_503 http_504 http_500; proxy_read_timeout 5s; proxy_send_timeout 8s; proxy_set_header Connection Keep-Alive; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; index index.html index.htm; include vhost/*.conf; } |
nginx vhost的管理
首先是pillar的配置
1 2 3 4 5 6 7 8 9 10 |
[root@manager srv]# cat pillar/nginx/vhost.sls vhost: {% if 'lens' in grains['id'] %} - name: newlens-api.networkbench.com.conf target: /opt/nginx/conf/vhost/newlens-api.networkbench.com.conf source: salt://nginx/files/vhost/newlens-api.networkbench.com.conf - name: lens target: /opt/nginx/conf/vhost/lens.networkbench.com.conf source: salt://nginx/files/vhost/lens.networkbench.com.conf {% endif %} |
然后是vhost.sls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@manager srv]# cat salt/nginx/vhost.sls include: - nginx.install {% for vhostname in pillar['vhost'] %} {{vhostname['name']}}: file.managed: - name: {{vhostname['target']}} - source: {{vhostname['source']}} - template: jinja - watch_in: service: nginx {% endfor %} |
本条目发布于2014年6月9日。属于saltstack分类,被贴了 saltstack 标签。
http://www.opstool.com/article/293
实时管理
cmd.run的方式
执行命令
sudo salt '*' cmd.run 'uptime'
系统模块
系统自建的模块 参考salt文档 http://docs.saltstack.com/en/latest/ref/modules/all/index.html
例如查看minion的磁盘使用率,使用disk模块的usage函数
sudo salt '*' disk.usage
使用sys.doc模块查询salt模块的相关使用方法。sys.doc 相当于系统的man,可以查询salt模块的在线doc
sudo salt '*' sys.doc disk
自定义模块
自定义模块的目录/srv/salt/_modules/
,自定义模块路径一般为/srv/salt/_modules/custom.py
。 示例:
$cat /srv/salt/_modules/custom.py
def test():
return 'i am test'
手动同步模块到minion
sudo salt '*' saltutil.sync_modules
执行模块
sudo salt '*' custom.test
Targetting
简单方式的匹配:Shell Style & Perl 正则匹配
模式 | 含义 |
* | 匹配所有minion |
web1 | 匹配web1 |
web* | 匹配web开头的minion |
web? | 匹配web开头4个字符ID的minion |
web[1-5] | 匹配web1到web5 |
web[1,3] | 匹配web1和web3 |
web1-(prod|devel) | 匹配web1-prod和web1-devel |
列表匹配
sudo salt -L 'web1,web2' test.ping
Grains匹配
sudo salt -G 'virtual:physical' test.ping #匹配所有物理机
sudo salt -G 'virtual:phy*' test.ping #grains匹配方式中同样可以使用 Shell Style & Perl正则方式
Pillar匹配
sudo salt -I 'master:ipv6:False' test.ping
SLS文件中的匹配方式
'virtual:physical':
- match: grain
States
states用于实现对minion进行状态管理,官方参考文档 http://docs.saltstack.com/ref/states/all/index.html
states 定义路径/src/salt
(在/etc/salt/master中的file_roots变量定义),states文件使用YAML格式定义
states文件的后缀是sls(Salt State),sls文件编写需要注意在:之后要保留一个空格,否则会导致解析错误
手动执行state的方式,以修改admin账号的bashrc为例
准备/src/salt/bashrc.sls
,内容如下
/home/admin/.bashrc:
file.managed:
- source: salt://files/bashrc
- user: admin
- group: admin
- mode: 644
准备好用于分发的bash文件,salt://files/bashrc
对应/srv/salt/files/bashrc
使bash.sls生效
sudo salt '*' state.sls 'bashrc'
Highstate的方式。其实是使用top.sls作为state的入口文件
/src/salt/top.sls文件如下,top.sls引用bashrc.sls
base:
'*':
- bashrc
手动执行highstate生效
sudo salt '*' state.highstate
使用schedule 让minion自动执行highstate
定义 /srv/pillar/top.sls
base:
'*':
- schedule
定义 /srv/pillar/schedule.sls
(30分钟为单位)
schedule:
highstate:
function: state.highstate
minutes: 30
Pillar
官方文档 http://docs.saltstack.com/topics/tutorials/pillar.html
pillar数据定义路径/srv/pillar
, 入口文件:/srv/pillar/top.sls
查看pillar信息
sudo salt '*' pillar.data
Grains
官方文档 http://docs.saltstack.com/topics/targeting/grains.html
查看grains分类
sudo salt '*' grains.ls
查看grains所有信息
sudo salt '*' grains.items
查看grains某个信息
sudo salt '*' grains.item osrelease
自定义grains
grains自定义目录/srv/salt/_grains/
,自定义路径/srv/salt/_grains/grans_test.py
,示例:
def grans_test():
grains = {}
grains['grans_test'] = 'this is a grans test!'
return grains
if __name__ == '__main__':
print grans_test()
同步grains
sudo salt '*' saltutil.sync_grains
查看机器grains信息
sudo salt '*' grains.item grans_test
Job管理
Salt实时管理的任务都是作为Job来执行
查看正在执行的Job
sudo salt-run jobs.active
查看Job列表(包括执行过的)
sudo salt-run jobs.list_jobs
查看指定Job的状态
sudo salt-run jobs.lookup_jid 20140408112045976162
Minion状态管理
查看minion的状态up or down
sudo salt-run manage.status #查看所有状态
sudo salt-run manage.up #只看up的
sudo salt-run manage.down #只看down的
查看minion的版本,该命令会提示哪些minion的版本需要升级
sudo salt-run manage.versions
参考文档
- http://blog.halfss.com/blog/2013/05/22/yun-wei-zi-dong-hua-zhi-saltxue-xi-bi-ji/
- http://www.saltstack.cn/projects/cssug-kb/wiki
- http://salt.readthedocs.org/en/latest/topics/index.html [很不错的英文salt资料]
- http://www.saltstack.cn/projects/cssug-kb/wiki/Using_pillar_data_in_saltstack [Salt中使用Pillar]
http://www.ttlsa.com/saltstack/saltstack-pillar-grains-action-shencan-06/
前面已经讲了5章关于saltstack 的一些基本应用与基本功能(基本而已 还有很多东西我也没弄) 但是目前就这些基本的功能就能满足我们线上的业务了 下面我整理了下关于我们全网统一squid配置文件的一个案例 我顺便记录下 以便下次接着扩展
先说下原始需求
1.我们全网的squid配置文件 配置比较乱 有视频 下载 web 3种业务的配置
2.我们全网的设备 磁盘大小 磁盘块数 也不同
3.我们某些节点还有特殊配置
目前就是针对这3个需求 统一一个squid主配置文件的模板 (jinja模板)
先讲下我的思路 (我的思路可能不是最好的 但是我能保证我的配置是能用的)
1.先收集全网所以squid 配置文件 对比 分析 挑选出 其中的共同之处 (squid 性能配置一般是一样的) 然后定义存储到pillar里面
2.然后对比 那些有区别的地方 (统计一下 有多少种配置) 然后 讲每种配置 都存储到pillar 里面
3.然后编写grains 去 采集设备自身的信息 (磁盘数 服务业务等等) 然后根据自身的grains 信息 自动调用上面定义的pillar 生成文件
OK 思路就是这样 不知道 你们看懂没 总结一句话吧 1. 把不变的东西 存到pillar 里面 2. 不确定的东西 用grains 去采集 3.根据采集的值 调用不同的pillar
现在我开始讲案例吧
先说下我们全网的squid配置文件的不同之处
1. 视频 下载 web 的核心配置不一样 (我们是通过api去确定这台设备改服务什么)这个是主导方向
2.有12*1T 12*2T 的设备 ( 直接定义2种pillar )
3.还有某些自定义的配置 (预留一个自定义的pillar)
下面贴下我编写的grains python脚本吧(自定义这个一起讲过 看前面的文章去)
cat _grains/fc8.py
脚本的意思 这里不用多讲了吧 还是那句话 python 牛掰了 想怎么弄 就怎么弄 按照官方源码的格式弄就行
这里说下这个脚本的用途吧 去采集3个值
1. 磁盘的块数
2.每块盘的大小
3.这台设备的应用(公司api已经有绑定)
同步下 这里不说了 saltutil.sync_grains 你懂的 验证这个也不多说了
自定义grains 就弄完了 因为我python 还没入门 说实话 刚才的脚本 我也是凑出来的 实在搞不定的就是直接用python 调用shell
然后去编写pillar值吧 这个是静态的 很简单 (例子 我前面的博客也有介绍)
我直接上配置吧
我的pillar结构就是这样的 下面我会每个挑个例子说下
cache.sls 这个里面定义 squid 的cache_dir配置 (跟盘大小 跟盘数量有关 你懂的)
sc.sls 这个里面定义所以squid配置文件里面共同的配置 你懂的
core.sls 这个里面定义 核心配置(跟 服务业务有关 视频 下载 web)
optimize.sls 这个是一些调优配置 (服务业务有关 视频 下载 web)
diy.sls 这个你懂的 留个一些 特殊配置用的
ok 下面 开始讲 没个sls的 定义吧 (前面也讲过 我这里指截图一部分 )
cache.sls 的部分配置
截图为 web 业务的2种配置 下载跟视频的 也一样 挨着定义就行 这里不截图
看看优化配置吧 (也是根据 web 视频 下载 3大业务来分的) 下面的截图是web的
其他的 也都差不多 记住我的方向是 根据业务来分的 就行 其他的配置 格式 也都一样 只是 东西不同(squid配置文件的一些东西)
OK pillar 也差不多讲完了 现在去弄弄 jinjia模板吧
我直接贴我的目标吧
这个就不讲了
核心在下面
判断很简单 你懂的 记住调用pillar值格式就行 我介绍一个吧
{{ pillar[‘CPISWEB’][’12_1T’] }} 就这个吧
学过python的 这个应该能看懂吧 CPISWEB 是cache.sls 里面定义的一个 针对web的 12_1T 是web的cache_dir配置 简单吧
OK 先写到这里 抽烟去了。。。。。。。
转自:http://www.shencan.net/index.php/2013/07/10/saltstack%E5%85%AD-pillar-grains-%E5%AE%9E%E9%99%85%E6%BC%94%E7%BB%83/
http://blog.sina.com.cn/s/blog_c509f4d90102v53t.html
虚拟模块
模块名 |
描述 |
管理aliases file信息 |
|
salt.modules.alternatives |
|
管理apace模块 |
|
APT(Advanced Packaging Tool)支持 |
|
压缩(archive)支持 |
|
at支持 |
|
通过augeas管理配置文件 |
|
管理Bluetooth(使用Bluez) |
|
Mac OS X的Homebrew支持 |
|
指定butter云组件路由 |
|
Cassandra NoSQL数据库模块 |
|
A module for shelling out |
|
返回配置信息 |
|
minion端salt-cp支持 |
|
cron支持 |
|
daemontools服务模块 |
|
管理minion本地持久化的数据结构 |
|
Debconf支持 |
|
Debian系列系统服务支持 |
|
管理磁盘信息 |
|
管理django站点 |
|
管理dnqmasq模块 |
|
dns通用管理工具 |
|
用于支持DEB 分发版本的包管理 |
|
另外一个包管理 |
|
eix 支持 |
|
Fire events on the minion, events can be fired up to the master |
|
管理ex2/3/4文件系统]] |
|
管理minion的文件信息,设置或读取文件属组、权限等 |
|
管理FreeBSD jail环境 |
|
管理FreeBSD 内核 |
|
FreeBSD package管理支持 |
|
管理FreeBSD服务 |
|
FreeBSD sysctl管理支持 |
|
管理ruby gem |
|
Gentoolkit支持 |
|
管理gentoo服务 |
|
git SCM支持 |
|
Module for handling openstack glance calls. |
|
grains数据控制 |
|
管理Linux和OpenBSD组 |
|
GRUB Legacy支持 |
|
通过libguestfs管理虚拟机镜像 |
|
Mercurial SCM支持 |
|
管理hosts文件 |
|
虚拟机镜像管理 |
|
iptables支持 |
|
posix-like系统键盘管理模块 |
|
minion key信息支持 |
|
openstack keystone调用管理 |
|
Linux内核管理模块 |
|
Provide the hyper module for kvm hypervisors |
|
Mac OSX launchd/launchctl管理支持 |
|
Layman支持 |
|
ldap管理支持 |
|
Linux文件访问控制支持 |
|
Linux LVM2支持 |
|
Linux sysctl管理支持 |
|
posix-like系统locale支持 |
|
locate工具管理 |
|
logrotate管理支持 |
|
Support for modifying make.conf under Gentoo |
|
使用mdadm工具管理RAID arrary |
|
mongodb管理支持 |
|
monit模块 |
|
moosefs管理支持 |
|
管理UNIX mount及fstab文件 |
|
Run munin plugins/checks from salt and format the output as data |
|
mysql管理支持 |
|
收集和管理网络信息 |
|
NFS3管理模块 |
|
nginx管理 |
|
openstack nova调用管理 |
|
Manage and query NPM packages |
|
nzbget支持 |
|
OpenBSD包管理 |
|
OpenBSD服务管理 |
|
Mac OS X implementations of various commands in the "desktop" interface |
|
Arch pacman管理 |
|
pam管理 |
|
posix-like系统分区管理parted支持 |
|
PHP pecl扩展支持 |
|
minion pillar数据管理 |
|
系统python或virtualenv pip管理 |
|
pkgng支持 |
|
Resources needed by pkg providers |
|
Solaris Pkgutil支持 |
|
Postgres数据库管理支持 |
|
poudriere支持 |
|
A salt interface to psutil, a system and process library |
|
Publish a command from a minion to a target |
|
puppet管理支持 |
|
FreeBSD组管理 |
|
FreeBSD用户管理 |
|
qemu镜像命令管理 |
|
qemu命令管理 |
|
quotaposix-like系统quota管理 |
|
rabbitmq管理 |
|
Windows注册表管理 |
|
Module to integrate with the returner system and retrieve data sent to a salt |
|
RHEL/Fedora网络管理 |
|
类RHEL服务管理 |
|
rpm支持 |
|
Manage ruby installations and gemsets with RVM, the Ruby Version Manager |
|
Amazon S3支持 |
|
The Saltutil module is used to manage the state of the salt minion itself |
|
selinux调用管理 |
|
服务管理 |
|
管理shadow文件 |
|
Solaris 10和11服务管理模块 |
|
Solaris组管理 |
|
Solaris包管理 |
|
Solaris shadow文件管理 |
|
Solaris用户管理 |
|
solr模块支持 |
|
SQLite3支持 |
|
管理ssh客户端 |
|
管理minion state |
|
返回minion各种状态 |
|
Provide the service module for supervisord |
|
Subversion SCM |
|
sysbench支持 |
|
he sys module provides information about the available functions on the minion |
|
systemd服务管理 |
|
支持关机、重启等 |
|
Module for running arbitrary tests |
|
posix-like系统timezone管理 |
|
SSL/TLS模块 |
|
tomcat支持 |
|
Module for the management of upstart systems |
|
libvirt管理支持 |
|
创建python virtualenv环境 |
|
收集Windows磁盘信息 |
|
管理Windows minion文件信息 |
|
管理Windows组 |
|
管理Windows网络信息 |
|
Windows包管理 |
|
Windows服务管理 |
|
Windows shadow管理 |
|
返回Windows minion各种信息 |
|
Windows用户管理 |
|
YUM支持 |
|
YUM支持 |
|
ZFS支持 |
|
OpenSUSE zypper包管理支持 |
http://my.oschina.net/u/877567/blog/186288
编写模块
简述
以ubuntu为例 salt 全部模块文件置于如下目录中:
/usr/share/pyshared/salt/
编写一个自定义的模块
在已定义的 file_roots 中,创建一个 _modules/ 目录,我们要扩展的外部模块就编写在这个目录下,(具体位置参见配置文件: /etc/salt/master)
描述一下这个模块的功能:检查 /etc/hostname /etc/resolv.conf 这两个文件的 attr 属性
/srv/salt/_modules/getattr.py
import os import popen2 def run(): cmd = "lsattr /etc/hostname /etc/resolv.conf" child=os.popen(cmd) data = child.read() return data
将模块分发到目标机器
salt '*' saltutil.sync_modules
命令执行完毕后,可以看到getattr.py被分发到minions主机的如下位置
/var/cache/salt/master/roots/hash/base/_modules/getattr.py.hash.md5 /var/cache/salt/minion/files/base/_modules/getattr.py /var/cache/salt/minion/extmods/modules/getattr.py
执行自己编写的模块
salt '*' getattr.run
命令执行成功后返回信息如下:
salt-master: -------------e- /etc/hostname -------------e- /etc/resolv.conf
参考
A guide on how to write Salt modules
http://arlen.blog.51cto.com/7175583/1424216
SaltStack 通过模块来实现管理,具备丰富的模块功能,命令形式也比较自由,这里通过罗列几个有用的命令来作为入门的学习实验。
sys.doc : 类似linux的man命令,可以显示minion支持的模块的详细操作说明
1
2
3
4
5
6
7
8
9
10
|
# 这里查询 status.all_status 模块函数的使用方法 [root@yw_home monitor] # salt 192.168.0.100 sys.doc status.all_status status.all_status: Return a composite of all status data and info for this minion. Warning: There is a LOT here! CLI Example: salt '*' status.all_status |
status 模块是系统状态的常用信息模块,可以利用这个模块查看系统的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# 负载信息 [root@yw_home salt] # salt '192.168.0.100' status.loadavg 192.168.0.100: ---------- 1-min: 0.0 15-min: 0.0 5-min: 0.0 # cpu信息 [root@yw_home salt] # salt '192.168.0.100' status.cpuinfo # 磁盘信息 [root@yw_home salt] # salt '192.168.0.100' status.diskstats # 内存信息 [root@yw_home salt] # salt '192.168.0.100' status.meminfo # 类似w命令的返回信息 [root@yw_home salt] # salt '192.168.0.100' status.w 192.168.0.100: ---------- - idle: 10:02 - jcpu: 0.00s - login: 183.63.100.85 - pcpu: 0.62s - tty : pts /0 - user: root - what: 0.44s /usr/bin/python |
test 模块
1
2
3
|
[root@yw_home salt] #salt '192.168.0.100' test.ping 192.168.0.100: True |
备注: 想更多的了解test模块,可以查看 salt 192.168.0.100 sys.doc test
cmd 模块是常用的执行远程命令模块,具有强大的功能
1
2
3
4
5
6
|
# cmd.run 执行一个远程shell命令 [root@yw_home salt] #salt '192.168.0.100' cmd.run 'ls -l' # cmd.script 在远程minion执行一个master上的脚本,命令会从master下载脚本到minion上并执行 # 路径为file_root参数指定的路径为 salt:// 路径 [root@yw_home salt] #salt '192.168.0.100' cmd.script salt://scripts/runme.sh |
备注: 想更多的了解cmd模块,可以查看 salt 192.168.0.100 sys.doc cmd
state 模块是salt state的管理模块,可以通过state模块简单的对minion操作sls状态
1
2
3
4
5
6
7
8
|
# 更新指定minons的所有sls状态 [root@yw_home salt] #salt '192.168.0.100' state.highstate # 查看当前运行的sls状态 [root@yw_home salt] #salt '192.168.0.100' state.running # 动态指定一个sls状态 [root@yw_home salt] #salt '192.168.0.100' state.single pkg.installed name=vim |
备注: 想更多的了解cmd模块,可以查看 salt 192.168.0.100 sys.doc state
saltutil 模块 saltstack的一些辅助操作命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
saltutil.is_running: 判断一个函数是否正在使用。 例如: salt '*' saltutil.is_running state.highstate saltutil.kill_job: 强制关闭一个job进程 例如: salt '*' saltutil.kill_job <job id > |
备注: 想更多的了解saltUtil模块,可以查看 salt 192.168.0.100 sys.doc saltutil
上面列出的仅是saltstack的一小部分模块,saltstack有超多模块来辅助进行服务器的管理,更多信息可以参考官网下载的doc文件的最后不少章节,都是讲关于模块函数的。
本文出自 “纳米龙” 博客,请务必保留此出处http://arlen.blog.51cto.com/7175583/1424216
http://runforever.github.io/blog/2014-07-11-saltstack%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9D%97.html
SaltStack自定义模块
来由
公司项目以前使用的是fabric将代码部署到云平台,现在迁移到本地的服务器,
再使用fabric显然有点不合适,然而使用SaltStack的state来描述发版本的过
程又略显不灵活,所以决定自己编写一个SaltStack的模块来实现版本发布的需求,
下面给出编写自定义模块的方法。
版本发布流程
- 使用git pull最新的master代码。
- 使用脚本替换一些变量。
- 一些其他的操作
- 重启supervisor开启的uwsgi服务。
如何编写SaltStack自定义模块
编写SaltStack自定义模块超级简单,前提是需要你会一些Python编程,具体如下:
步骤
- 首先需要在master机器的file_roots 下建一个_modules文件夹,里面放.py 文件,也就是自定义模块。
- file_roots 在/etc/salt/master 里可以设置,默认是/srv/salt/,即你需要在这个目录下新建文件夹_modules
- 在_modules里新建自定义模块,然后编写相应的代码。
- 比如模块名是foo,在里面定义了方法bar。
- 写完代码后,使用命令 salt ‘*’ saltutil.sync_all 将自定义模块同步到各个minion上。
- 也可以使用 salt ‘*’ saltutil.sync_modules 将自定义模块同步到minion上
- 运行自定也模块,使用命令 salt ‘*’ foo.bar
实例
目录结构:
srv \-- salt \-- _modules \-- foo.py \-- prod ...
自定义模块代码:
# coding: utf-8 def bar(): CMD_RUN = __salt__['cmd.run'] cmd = "ls /etc/init" return CMD_RUN(cmd) # 解释 # 自定义模块会加载__salt__变量,这个dict变量里包含所有的salt function # 上面的cmd.run就是salt的命令运行函数 # __salt__变量必须在自定义的模块里使用,也就是必须在自定一的方法中使用, # 如上面的bar方法,不能将__salt__变量放到全局变量中使用,否则会报__salt__变量为定义
注意事项
- 如果要使用__salt__变量,必须要在自定义的方法中使用,不能在全局变量中使用。
- 如果运行命令报错了,如报 foo.bar is not avaliable,请到minion机器上去查看具体的日志。
- 报上述错误并不是模块没有同步到minion上,而是你编写的模块运行有问题。
- minion的日志记录在/var/log/salt/minion中,可以去这里查看具体错误。
最后的思考
- 编写SaltStack自定义模块很简单、方便。
- 实现自定义模块的过程中,可以发扬NIH(Not invent here)的思想。
- 可以充分利用__salt__变量里的salt自带函数来实现你想要的功能。
http://lixcto.blog.51cto.com/4834175/1429759
模块是个啥呢?其实就是个文件。
salt模块其实分为两类,一类模块,叫execution modules,这一类模块是在命令行上面执行的
来个内置执行模块的链接地址:
http://docs.saltstack.cn/ref/modules/all/index.html#all-salt-modules
还有一类模块,叫state modules,这一类模块是在state里面使用的
也来个内置state模块的链接:
http://docs.saltstack.cn/ref/states/all/index.html
先说执行模块是怎么写的吧。
执行模块,默认的路径在/srv/salt/_modules下
__salt__是个字典,是个啥字典呢,这个玩意,是属于salt全局的一个字典,只要我们定义的模块被minion加载后,就可以用__salt__了。
注意:这个__salt__字典,不是在我们模块里面自己定义的,而是salt全局的,我们写模块的时候直接拿来用就OK了
OK,知道__salt__是个啥之后,那个这东西里面都装了些什么玩意呢?
其实,__salt__这个字典里面装的minion上面所有的modules。__salt__的key是一个个的模块名称,value则是模块里面的一个个函数。
好,下面咱们看个例子,看看内建模块是怎么调用的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
这个foo.py是楼主自定义的一个模块,很简单,传一个参数进去,然后返回一段话 root@salt-master:~# cat /srv/salt/_modules/foo.py def foo(name): return "I am %s" % name 这个cheng.py也是楼主定义的一个模块,目的是通过__salt__调用我们上面定义的那个foo模块中的 foo函数 root@salt-master:~# cat /srv/salt/_modules/cheng.py def cheng(name): return __salt__[ 'foo.foo' ](name) OK,咱们同步一下模块 root@salt-master:~# salt '*' saltutil.sync_modules salt-minion: - modules.cheng - modules.foo 好,看一下结果! root@salt-master:~# salt '*' cheng.cheng lisisi salt-minion: I am lisisi root@salt-master:~# |
通过这个例子,大家差不多该知道怎么调用__salt__里面的模块函数了吧。
好,咱们总结一下
使用格式:__salt__['模块.函数']('函数参数')
OK,下一个话题,来看看自定义的模块,怎样使用grains,pillar,以及编写文档,还有自定义输出格式。
看这个例子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
root@salt-master:~# cat -n /srv/salt/_modules/lisisi.py 1 '' ' 2 :maintainer: LiXiangcheng <626659817@qq.com> 3 :maturity: new 4 :depends: 5 :platform: all 6 '' ' 7 __outputter__ = { 8 'lisisi' : 'json' 9 } 10 def lisisi(args): 11 '' ' 12 A function just one example 13 CLI Example: 14 salt '*' lisisi.lisisi args 15 16 '' ' 17 grain = __grains__[ 'chengge' ] 18 pillar = __pillar__[ 'group' ] 19 result = __salt__[ 'cmd.run' ](args) 20 result = "%s,%s,%s" % (grain,pillar,result) 21 return result root@salt-master:~# |
下面解释一下,1到6行都看得明白,是一些基本信息。
7到9行,是指定输出格式,__outputter__这个东西也是个字典,这个字典会绑定salt中的一个方法,当你以 函数名:输出格式 这种形式加入__outputter__这个字典后,salt就会帮你把你指定的函数,按照指定的格式打印返回值。
好了,那输出格式有哪些个呢?看下面
'grains','yaml','json','pprint','raw','highstate','quiet','key','txt','no_return','nested','virt_query'
看到了没,这么多。一般咱们用默认的就OK了,大多数的输出格式都不好看其实。楼主这里用json输出格式测试一下。
再看一下11~16行,这个东西是干啥的呢?这个东西,是把你这个函数的用法加到sys.doc里面的。
再看一下17行。这个用到grains,咋用的呢,也是通过salt默认的一个字典__grains__,你想去哪个grain的时候,这么用就ok了,__grains__['Id']
18行,这个用到了pillar,咋用的呢?和grains一个样,__pillar__['Id']
下面的几行就不说了。
OK,来看一下结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
好同步一下模块 root@salt-master:~# salt '*' saltutil.sync_modules salt-minion: - modules.lisisi 看一下doc,看看这个函数是咋用的? root@salt-master:~# salt '*' -d lisisi.lisisi lisisi.lisisi: A function just one example CLI Example: salt '*' lisisi.lisisi args OK,可以执行了,传个命令进行 root@salt-master:~# salt '*' lisisi.lisisi "ls /tmp" { "salt-minion" : "1002,lixc,lixc1" } root@salt-master:~# |
OK,关于执行模块,楼主看了官方文档,还有这么个功能,__virtual__, 这东西叫虚拟模块
这功能楼主一看,尼玛,这东西好像和C++里面的多态虚函数,差不多。
这东西咋用的呢?官网上的例子是pkg这个模块,安装软件,有很多平台啊,有debian用的apt-get,centos用的是yum,用这个函数就可以来自动的判断。。。
楼主举个小例子吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
先看一下,楼主的这个模块是咋定义的? root@salt-master:~# cat /srv/salt/_modules/foo.py __virtualname__ = 'sisi' def __virtual__(): if __grains__[ 'chengge' ] == 1002: return True return __virtualname__ def foo(name): return "I am %s" % name 再看一下,chengge这个grains的value是啥,和楼主那个模块里都是1002,说明__virtual__这个函数会 返回True root@salt-master:~# salt '*' grains.item chengge salt-minion: chengge: 1002 同步一下模块 root@salt-master:~# salt '*' saltutil.sync_modules salt-minion: - modules.foo 好,执行这个模块,正常打印了吧。 root@salt-master:~# salt '*' foo.foo lisisi salt-minion: I am lisisi 接着,咱们把1002随便改为1003吧,这时候1003这个值和chengge这个grain的value是不一致的,这时候 __virtual__这个函数返回__virtualname__,也就是 'sisi' root@salt-master:~# sed -i 's#1002#1003#g' /srv/salt/_modules/foo.py 查看一下,修改成功了没 root@salt-master:~# grep 1003 /srv/salt/_modules/foo.py if __grains__[ 'chengge' ] == 1003: OK,修改之后,再同步一下模块 root@salt-master:~# salt '*' saltutil.sync_modules salt-minion: - modules.foo 再执行一下模块,看到了没,模块不可用了。 root@salt-master:~# salt '*' foo.foo lisisi salt-minion: 'foo.foo' is not available. 再这么访问一下,看到了神奇的地方了没 root@salt-master:/srv/salt/_modules# salt '*' sisi.foo lixc salt-minion: I am lixc |
哈哈,大伙应该知道这东西大概怎么用了吧。其实__virtual__这东西,返回一个string的时候,模块就可用,当它返回False的时候。模块就不可用了。。。
如果__virtual__这个函数,返会__virtualname__,那么我们的模块的名字就会被改名,修改的名字就是__vitualname__对于的值。
我们可以根据__virtual__这个函数,来控制,自定义模块的使用场景。。。
哈哈,还有一个东西忘记提了,怎么同步模块呢,上面已经写了一种方法,楼主总结下吧。以下三种方法都可以同步模块
salt '*' state.highstate
salt '*' saltutil.sync_all
salt '*' saltutil.sync_modules
exection modules官方上还介绍了一个装饰器的功能。。楼主还没看懂。自定义state modules,楼主也没有看到呢,楼主先研究研究再写吧。
本文出自 “小城运维” 博客,请务必保留此出处http://lixcto.blog.51cto.com/4834175/1429759
http://www.fireinfo.cn/content-11-134-1.html
参考:http://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.cp.html#module-salt.modules.cp
cp.cache_[file,files] 将salt://中文件复制到minions/var/cache/salt/files中
cp.cache_dir 将salt://中文件夹复制到minions/var/cache/salt/files中
cp.get_file 将salt://中文件复制到minions指定文件夹中
cp.get_dir 将salt://中文件夹复制到minions指定文件夹中
salt '*' cp.get_file salt://files/b /tmp/b
salt '*' cp.get_url salt://path/to/template /minion/dest 从网址中下载文件
salt '*' cp.get_template salt://path/to/template /minion/dest配置文件的下发,和cp.get_file类似(个人感觉)
salt '*' cp.hash_file salt://files/a 返回文件a的hash值
salt '*' cp.is_cached salt://files/a 判断a文件是否在minion的cache中
salt '*' cp.list_master 列出salt://files/目录下的所有文件
salt '*' cp.list_master_dirs 列出salt://下的所有文件夹
salt '*' cp.push /etc/fstab 从minion中下载文件
salt ‘*’cp.push_dir 从minion中下载文件夹
http://blog.liuts.com/post/240/
Saltstack是一个具备puppet与func功能为一身的集中化管理平台,saltstack基于python实现,功能十分强大,各模块融合度及复用性极高,官方极力推荐作为云计算平台的基础架构。轻松维护成千上万台服务器不是问题,现分享作者基于saltstack实现一个集中化的配置管理平台,以Nginx配置例子展开,涉及salt的grains、grains_module、pillar、States、jinja(template)等,本文适合有salt基础的同学阅读。
一、设备环境说明
有两组web业务服务器,组名分别为web1group与web2group,设备硬件配置、web根目录存在异常,见下图:
二、master配置说明
1、关键配置定义:
- nodegroups:
- web1group: 'L@SN2012-07-010,SN2012-07-011,SN2012-07-012'
- web2group: 'L@SN2013-08-021,SN2013-08-022'
- file_roots:
- base:
- - /srv/salt
- pillar_roots:
- base:
- - /srv/pillar
2、定义的文件树结构(具体文件后续说明)
三、自定义grains_module
1)#vi /srv/salt/_grains/nginx_config.py
- import os,sys,commands
- def NginxGrains():
- '''
- return Nginx config grains value
- '''
- grains = {}
- max_open_file=65536
- #Worker_info={'cpus2':'01 10','cpus4':'1000 0100 0010 0001','cpus8':'10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001'}
- try:
- getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')
- except Exception,e:
- pass
- if getulimit[0]==0:
- max_open_file=int(getulimit[1])
- grains['max_open_file'] = max_open_file
- return grains
2)同步grains模块
salt '*' saltutil.sync_all
3)刷新模块(让minion编译模块)
salt '*' sys.reload_modules
4)验证max_open_file key的value
[root@SN2013-08-020 _grains]# salt '*' grains.item max_open_file
SN2013-08-022:
max_open_file: 1024
SN2013-08-021:
max_open_file: 1024
SN2012-07-011:
max_open_file: 1024
SN2012-07-012:
max_open_file: 1024
SN2012-07-010:
max_open_file: 1024
四、配置pillar
本例使用分组规则定义pillar,即不同分组引用各自的sls属性
1)定义入口top.sls
#vi /srv/pillar/top.sls
- base:
- web1group:
- - match: nodegroup
- - web1server
- web2group:
- - match: nodegroup
- - web2server
2)定义私有配置,本例只配置web_root的数据,当然可以根据不同需求进行定制,格式为python的字典形式,即"key:value"。
#vi /srv/pillar/web1server.sls
- nginx:
- root: /www
#vi /srv/pillar/web2server.sls
- nginx:
- root: /data
3)验证配置结果:
#salt 'SN2013-08-021' pillar.data nginx
SN2013-08-021:
----------
root:
/data
#salt 'SN2012-07-010' pillar.data nginx
SN2012-07-010:
----------
root:
/www
五、配置States
1)定义入口top.sls
#vi /srv/salt/top.sls
- base:
- '*':
- - nginx
2)定义nginx配置及重启服务SLS,其中salt://nginx/nginx.conf为配置模板文件位置。
#vi /srv/salt/nginx.sls
- nginx:
- pkg:
- - installed
- file.managed:
- - source: salt://nginx/nginx.conf
- - name: /etc/nginx/nginx.conf
- - user: root
- - group: root
- - mode: 644
- - template: jinja
- service.running:
- - enable: True
- - reload: True
- - watch:
- - file: /etc/nginx/nginx.conf
- - pkg: nginx
3)Nginx配置文件(引用jinja模板)
功能点:
1、worker_processes参数采用grains['num_cpus'] 上报值(与设备CPU核数一致);
2、worker_cpu_affinity分配多核CPU根据当前设备核数进行匹配,分别为2\4\8\其它核;
3、worker_rlimit_nofile参数与grains['max_open_file'] 获取的系统ulimit -n一致;
4、worker_connections 参数理论上为grains['max_open_file'];
5、 root参数为定制的pillar['nginx']['root']值。
#vi /srv/salt/nginx/nginx.conf
- # For more information on configuration, see:
- user nginx;
- worker_processes {{ grains['num_cpus'] }};
- {% if grains['num_cpus'] == 2 %}
- worker_cpu_affinity 01 10;
- {% elif grains['num_cpus'] == 4 %}
- worker_cpu_affinity 1000 0100 0010 0001;
- {% elif grains['num_cpus'] >= 8 %}
- worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
- {% else %}
- worker_cpu_affinity 1000 0100 0010 0001;
- {% endif %}
- worker_rlimit_nofile {{ grains['max_open_file'] }};
- error_log /var/log/nginx/error.log;
- #error_log /var/log/nginx/error.log notice;
- #error_log /var/log/nginx/error.log info;
- pid /var/run/nginx.pid;
- events {
- worker_connections {{ grains['max_open_file'] }};
- }
- http {
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
- log_format main '$remote_addr - $remote_user [$time_local] "$request" '
- '$status $body_bytes_sent "$http_referer" '
- '"$http_user_agent" "$http_x_forwarded_for"';
- access_log /var/log/nginx/access.log main;
- sendfile on;
- #tcp_nopush on;
- #keepalive_timeout 0;
- keepalive_timeout 65;
- #gzip on;
- # Load config files from the /etc/nginx/conf.d directory
- # The default server is in conf.d/default.conf
- #include /etc/nginx/conf.d/*.conf;
- server {
- listen 80 default_server;
- server_name _;
- #charset koi8-r;
- #access_log logs/host.access.log main;
- location / {
- root {{ pillar['nginx']['root'] }};
- index index.html index.htm;
- }
- error_page 404 /404.html;
- location = /404.html {
- root /usr/share/nginx/html;
- }
- # redirect server error pages to the static page /50x.html
- #
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root /usr/share/nginx/html;
- }
- }
- }
4)同步配置
#salt '*' state.highstate
(由于非第一次运行,看不到配置文件比对的信息)
5)验证结果:
1、登录root@SN2013-08-021
#vi /etc/nginx/nginx.conf
2、登录root@SN2012-07-010
#vi /etc/nginx/nginx.conf
http://www.xiyang-liu.com/2014/12/saltstack-file-server-module/
原文链接:http://www.ituring.com.cn/article/41632
Salt States
参考链接: 原文Salt File Server, 官网文档cp模块
在配置管理系统中,从中心服务器想客户端推送文件是很基本的需求。SaltStack使用内建的ZeroMQ服务器做为文件服务器。 文件服务器主要用来在state系统中推送文件到客户端,也可以用于其他文件的传输。
cp模块
客户端对文件服务器的操作都在cp模块中。Salt State系统,Salt-cp都用到了cp模块。
环境
因为文件服务器是为Salt state系统服务,所以也支持环境的概念。master的配置文件中定义各环境的路径,文件的路径基于指定环境的根目录(参见下面的例子)。
常见用法
get_file
cp.get_file用来从master下载文件到客户端,语法如下:
# salt '*' cp.get_file salt://vimrc /etc/vimrc
其中vimrc在master上的实际路径要看环境中定义的根目录,假设在master中有如下定义:
file_roots:
base:
- /srv/salt/
那么vimrc的实际路径就是/srv/salt/vimrc,这样做的好处是,可以满足state系统中环境的概念。
源路径和目标路径中都可以使用模板,如下:
# salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja
这个例子中,将下载与客户端操作系统名字相同的目录下的文件。
对于大文件,cp.get_file支持gzip压缩,在参数中指定gzip的压缩级别,如下:
# salt '*' cp.get_file salt://vimrc /etc/vimrc gzip=5
其中,1代表作小压缩,9代表最大压缩。
cp.get_file默认不在客户端上建立目录,如果客户端上没有这个目录了,文件拷贝将失败,可以指定makedirs=True来创建目录:
# salt '*' cp.get_file salt://vimrc /etc/vim/vimrc makedirs=True
在这个例子中,如果“/etc/vim不存在,将会建立此目录。
get_dir
cp.get_dir可以从master下载整个目录,语法如下:
# salt '*' cp.get_dir salt://etc/apache2 /etc
cp.get_dir也支持模板和压缩:
# salt '*' cp.get_dir salt://etc/{{pillar.webserver}} /etc gzip=5 template=jinja
get_url
cp.get_url可以从一个URL地址下载文件,URL可以是msater上的路径(salt://),也可以是http网址。
salt '*' cp.get_url salt://my/file /tmp/mine
salt '*' cp.get_url http://www.slashdot.org /tmp/index.html
get_template
cp.get_template可以在文件下载之前用模板引擎处理。
salt '*' cp.get_template salt://path/to/template /minion/dest
push
cp.push可以从客户端传文件到master上,处于很明显的安全考虑,默认没有启用此功能,如果你需要的话可以参考文档,很方便的开启。
http://linux48.com/archives/307
在server端编写模块
salt默认的根目录在/srv/salt中,没有这个目录需要建立一个
mkdir -p /srv/salt/
编写安装nginx模块
“最高同步”需要执行的top规则
#cat /srv/salt/top.sls
base:
'*': #通过正则去匹配所有minion
- nginx #这里都是我自己写的state.sls模块名 这里可以无视 后面会提到
my_app: #通过分组名去进行匹配 必须要定义match:nodegroup
- match: nodegroup
- nginx
'os:Redhat': #通过grains模块去匹配,必须要定义match:grain
- match: grain
- nginx
nginx安装规则
#cat /srv/salt/nginx.sls
nginx:
pkg: #定义使用(pkg state module)
- installed #安装nginx(yum安装)
service.running: #保持服务是启动状态
- enable: True
- reload: True
- require:
- file: /etc/init.d/nginx
- watch: #检测下面两个配置文件,有变动,立马执行上述/etc/init.d/nginx 命令reload操作
- file: /etc/nginx/nginx.conf
- file: /etc/nginx/fastcgi.conf
- pkg: nginx
/etc/nginx/nginx.conf: #绝对路径
file.managed:
- source: salt://files/nginx/nginx.conf #nginx.conf配置文件在salt上面的位置
- user: root
- mode: 644
- template: jinja #salt使用jinja模块
- require:
- pkg: nginx
/etc/nginx/fastcgi.conf:
file.managed:
- source: salt://files/nginx/fastcgi.conf
- user: root
- mode: 644
- require:
- pkg: nginx
/etc/init.d/nginx:
file.managed:
- source: salt://files/nginx/nginx
- user: root
- mode: 777
- require:
- pkg: nginx
在当前目录下面(salt的主目录)创建files/nginx/nginx.conf、files/nginx/fastcgi.conf文件
mkdir -p /srv/salt/files/nginx/
fastcgi.conf 配置文件
cat fastcgi.conf
#test1111111111111111111
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
nginx.conf配置文件
cat nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
# test111111111111111111111
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
}
nginx启动脚本
cat nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
sysconfig="/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/nginx"
pidfile="/var/run/${prog}.pid"
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f $sysconfig ] && . $sysconfig
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest_q || return 6
stop
start
}
reload() {
configtest_q || return 6
echo -n $"Reloading $prog: "
killproc -p $pidfile $prog -HUP
echo
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
configtest_q() {
$nginx -t -q -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status