salt-minion,salt-master,multi master

http://www.cnblogs.com/taosim/articles/3371839.html

http://www.cnblogs.com/taosim/articles/3760812.html

=======================================

http://blog.coocla.org/114.html

 

 

入门虾扯淡,利用salt批量修改salt-minion的配置文件,前提条件客户端已经安装好salt-minion,并且已经和salt-master认证上

在salt里面大致可以分为这样几个部件:state、grains、pillar、modules、returners、schedule

state:

salt基于minon的状态管理,state系统的核心文件是sls文件,他们代表的是系统当前应该所处的某个状态,这些状态信息按照一个简单的格式来定义,在对客户端进行state状态管理时,salt-minon会按照这些sls文件中定义的状态对当前系统进行一致性的设置

grains:

这个单词我是真的不知道怎么读,它就好比是salt的一个接口,里面封装了获取系统相关硬软件的配置信息属性,而你也可以通过这个grains自定义赋予一些其他的属性,这些信息都是在salt-minion启动的时候被赋予的,除非你去手动的刷新重新获取,所以说grains是保留一些静态的属性信息,没有刷新或者重新启动是不会被改变的;举个例子来理解:就好比你入职一个公司,你的公司名是:A,你的职位名是:B,你的职责是:C,你的工资是:D  ;这些信息在你入职之后是被赋予的,假如你职位变动了或者你跳槽了,以上的一些信息就会发生一次改变,而这个职位变动或者跳槽就可以理解为“手动刷新或者重新启动”

pillar:

这个单词读起来同样拗口,这个东东呢也是saltstack部署中的重要组件之一,它是对特定的minion生成特定数据的接口,这些数据包含:敏感信息的数据、salt-minion的配置信息、通过模板文件定义或者其他sls文件定义的变量的引用、其他自定义的任意数据信息。而这些信息都是被匹配到的节点才能拥有或者使用

乱扯了一大堆,贴贴代码:

1、安装master,minion

Master:

# rpm -ivh http://mirrors.sohu.com/fedora-epel/5/x86_64/epel-release-5-4.noarch.rpm

# yum install salt-master -y

Minion:

# rpm -ivh http://mirrors.sohu.com/fedora-epel/5/x86_64/epel-release-5-4.noarch.rpm

# yum install salt-minion -y

2、修改minion配置文件,指定master

# vim /etc/salt/minion

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

3、配置master,自动接受认证

# vim /etc/salt/master

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

/etc/init.d/salt-master start

/etc/init.d/salt-minion start

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

4、当在管理上百台机器的时候,假如需要修改minon的某个参数时,可以使用如下方法(只是举例)

修改minion配置文件中的id的参数,每台机器我用IP作为minion的id的值。

编写一个入口文件top.sls:

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

第一行: 固定写法,必须的
第二行:   匹配minion
第三行: 匹配到的minion,将会按照这个状态管理文件salt-agent.sls中定义的内容去进行状态管理

编写状态管理文件salt-agent.sls (这个名字根据入口文件中自行DIY):

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

第一行:你懂得,自己DIY,标示而已
第二行:salt自带的文件管理
第三行:文件管理的模板文件,这个路径指的是Master上的:/srv/salt/salt-agent/minion  salt://等价于/srv/salt
第四行:要管理的目标文件
第五行:指明这个source是个jinja类型的模板
第六行:salt自带的等待执行的命令
第七行:要执行的命令
第八行:salt里面的监视器
第九行:监视的目标

这个文件处理的流程:1.用salt://salt-agent/minion去修改/etc/salt/minion中的内容  —> 2.监视/etc/salt/minion文件,如果这个文件发生变化  —> 3.执行service salt-minion restart命令

我操,啰嗦的太多了

来看看salt://salt-agent/minion这个模板文件,其实我只是修改了默认配置文件中的这一行内容,当然matser那项的配置要和上面修改的保持一致,不然待会就认证不上了:

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

这个id的值来自于当前minion的grains中的tag这个属性的值。tag这个属性的值默认是没有的,这里可以自定义对其进行赋予,看代码

_grains/minion-conf.py    目录必须这名字“_grains”,python脚本名字还是你懂得DIY吧

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

一切准备妥当,如果你的/srv/结构类似于下面的样子,就可以开始同步grains信息,执行以下命令

SaltStack学习笔记(一)利用salt修改salt-minion配置文件 SaltStack学习笔记(一)利用salt修改salt-minion配置文件

执行命令,查看minion所具有的属性:salt ‘games’ grains.items

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

OK,现在万事具备,只需要对改minion进行状态管理了,走起

SaltStack学习笔记(一)利用salt修改salt-minion配置文件

在执行了 salt ‘games’ state.highstate 对games进行了状态管理,由于minion被重启,而且id被修改,所以此时被当做另外一台机器认证到了master上,所以没有任何返回,在下面进行了 salt ‘games’ test.ping 也验证了这点,此时games节点的id被修改为图中 202-73的那台机器,所以名为games的key就可以删除了。

啰啰嗦嗦一大堆,笨嘴笨嘴啊

 

==============

 

如何使用salt states快速的配置一个系统。

本文将指导完成使用salt来配置一个minion运行apache http服务器并且使这个服务正确的运行。

在往下面进行之前,请确保你的salt已经安装并且已经工作。

Setting up the salt sate tree
states以文本文件的形式存储在master上,并且按照需求通过master的文件服务器传输给minions。state文件的集合构成了state tree

在使用salt时必须为其至少设置一个所谓的中央系统也就是state tree的第一个顶级点。编辑master的配置文件将以下行取消注释:

Note:如果你在部署FreeBSD的操作系统,这个 file_roots参数默认值为:/usr/local/etc/salt/states

重启salt master使这个配置改变生效:

Preparing the top file
在master上,上一步中的目录并没有被创建,(默认/srv/salt),创建一个名为top.sls文件,并添加一下内容:

这个top.sls文件是用来分隔环境的。默认环境是base,在base的环境集合定义了对minions的匹配,可以使用简单的*来指定所有的主机。

目标minions
salt可以通过glob、pcre正则表达式,或者通过grains来进行匹配任何的目标机器,例如:

Create an sls module
在top.sls相同的目录下,创建一个名为webserver.sls的空文件,内容如下:

第一行,是对全局ID的声明,可以是任意的标识符,在这种情况下,使用需要被安装的软件包的包名来定义。

Note:对于apache httpd web服务器的包名取决于操作系统的发行版,例如,在Fedora是httpd,但在Debian/Ubuntu是apache2

第二行,是对state的声明,定义了我们所要十一on个的salt states,在这个例子中,我们使用pkg state以确保一个给定的包被正确安装。
第三行,称为函数的声明,这个函数被定义在pkg state这个模块中。

Renderers渲染器
states的sls文件可以写成很多格式,salt只依赖于很简单的数据结构,并且不关心这些数据结构的建立,模版语言和DSLs到处都有,每个人都喜欢。
建立数据结构可以很简单的编写预期的任务,在本文中我们在jinja2的模版中使用YAML,这也是默认的格式。可以在master配置文件中修改默认渲染器

Install the package
接下来运行我们创建的state,在master上打开一个终端并且运行一下命令:

master将会指导所有的目标minions运行 state.highstate。当minion执行highstate,它将会下载top文件中匹配的内容,minion将表达式中匹配的内容下载、编译、执行。
一旦完成,minion将返回所有的动作执行结果和所有更改

 

Troubleshooting Salt
如果输出的内容不是你所预期的,以下的建议可以帮助你缩小问题。

启用日志记录
当你启用日志的debug模式,salt输出的信息将会很全

 

前台运行minion
不使用daemon模式(-d)启动minion,可以从输出看到其工作的任何细节

增加salt运行的默认超时时间,例如,修改默认超时时间为60s:

 

为了更好的达到这三个效果:

 

 
 
参考文档:http://docs.saltstack.com/topics/tutorials/states_pt1.html

 

===============

 

如何使用salt state快速进行系统配置(一)

Call multiple states
你可以在一个声明的ID下面定义多个state语句,例如,我们可以快速的修改webserver.sls,并且如果apache没有运行将其启动。

 

在运行state.highstate之前,尝试停止apache,并且再次观察其输出内容。

Expand the sls module
正如你所见,sls模块以.sls附加为文件扩展名并且从state的根下开始引用,同一个sls模块可以同时定义在一个目录。现在通过创建一个名为webserver的目录,并且将webserver.sls移动并且重命名到webserver/init.sls,你的state目录结构应该像下面这样:

 

组织sls模块
你可以将其他的.sls文件放置到state文件目录。这样的组织使你的state树在文件系统上显的更加简洁,例如:如果我们创建了一个webserver/django.sls文件,那么我们可以这样来引用它 webserver.django
此外,state提供了强大的扩展功能,详情请阅读:

如何使用salt states快速进行系统配置(三)

Require other states
现在我们已经安装了apache,并且处于工作状态,让我们添加一个HTML文件来定制我们的网站。但是如果没有webserver,它将不是一个有用的网站,所以除非apache已经安装并且运行否则我们不希望salt来安装这些HTML文件。像下面内容一样,将其包含在你的webserver/init.sls:

 

第九行声明一个新的ID,在这个例子中它是我们自定义的HTML文件要安装的位置(Note:在不同的操作系统或发行版上apache服务的默认位置可能不同,/srv/www也可能是个好位置。)
第十行声明使用的state。
第十一行声明使用第十行中的state的函数名。这个managed函数将从master上下载文件,并且按照指定的位置进行安装。
第十二行是函数的参数,在本例中利用managed函数中的source参数,指定需要从master上下载的文件的路径和名称
第十三行是require的声明
第十四行是require所要引用的state 和 ID,在这个例子它值的例子开头处的那个ID,这个声明告诉salt在不安装apache之前不要安装HTML文件

接下来,创建index.html文件,并且保存在webserver目录下:

 

最后,在调用一次state.highstate,minion将获取和执行highstate以及从master的文件服务器上获取我们的HTML文件

 

现在验证apache中你自定义的HTML吧!

require VS watch
现在有两个依赖的声明,“require和watch”,不是所有的state都支持”watch”。service state不支持”watch”并且不支持通过观察一个条件进行重新启动一个服务

例如,如果你使用salt配置安装apache的虚拟主机,当配置文件发送改变时要重启apache,你可以修改之前的例子:

如果在不同的操作系统或者发行版上pkg和service的名称不通,你可以单独声明一个名字,详细配置请阅读:
 
 
参考:http://docs.saltstack.com/topics/tutorials/states_pt2.html

 

===============================

 

 

Templating sls modules
sls模块内联执行可能依赖于你的编程逻辑。默认的模板使用jinja2模板系统作为渲染器,可以通过修改主配置文件master来改变渲染器的配置

所有的state都通过一个模板系统完成最初的读取,使用模板系统,只需要添加一个模板标记,一个使用模板标记的sls例子:

这个使用了模板的sls文件生成后结果如下:

 

下面这个是一个更复杂的例子:

 

Using grains in sls modules
通常情况下state在不同的系统有不同的表现。grains的信息也可以在sls模板文件中使用,例如,可以这样用:

 

 

Calling salt modules from templates
所有的state都是在minion上加载模板系统,这允许数据可以被实时的收集到目标系统上,它还允许在sls模块中允许shell命令。

模板内容也可以有效的使用salt函数:

注意,上面这个例子要正常工作,请确保some_group_that_exists存在
下面的例子,使用network.hw_addr函数来检索eth的mac地址:

 

Advanced sls module syntax
最后,我们将讨论在一些更负载的state树中的一些令人难以置信的技巧

 

Include语句
前面的例子展示了如何通过多个文件进行扩展。同样,require可以使用include语句进行多个文件中的state之间的依赖,例如:

 

Extend语句
你可以使用extend语句修改之前的例子,例如当apache的vhosts文件发生了改变也重启apache

 

 

extend它只是起追加作用,而不是取代任何必要的组件

 

Name语句
你可以使用name语句的值来覆盖ID的值,例如,这个例子更加有利于维护重写

Names语句
更强大的是使用names语句一次性的声明多个states来覆盖ID语句。这经常可以在模板中利用循环来实现,例如第一个例子中的循环可以写成下面这样的形式:

 

 
 
参考:http://docs.saltstack.com/topics/tutorials/states_pt3.html

 

==============================

本文将讲述salt如何通过建立一个file_roots来建立起工作的根,对于不同的”推广”"开发”"测试”"生产”等场景。

Salt fileserver path inheritance
salt允许在同一个环境下设置多个根目录,比如下面的例子,它使用本地的目录以及一个通过NFS共享的目录
# In the master config file (/etc/salt/master)

在同一个环境下salt的fileserver可以包含多个根的列表。如果相同的文件在多个根下出现,那么最顶端的根将会生效,例如,如果/srv/salt/foo.txt 和 /mnt/salt-nfs/base/foo.txt都存在,那么使用salt://foo.txt时,这个foo.txt取的是 /srv/salt/foo.txt

Environment configuration
配置多个环境如下:

从上可以看出/srv/salt/prod继承了所有的环境,所以这个路径可以用在任何的环境下。/srv/salt/qa可以用于两个环境下,/srv/salt/dev则只能用再一个环境下。

基于顺序的定义,新的state文件可以放置到/srv/salt/dev下,并且推送到dev主机上进行测试。

这些state文件也可以被移动到/srv/salt/qa下,那么现在他们就可以用再开发和测试环境中,并且允许他们被推送到测试主机上进行测试。

如果这些文件移动到/srv/salt/prod下,那么这些文件将可以用在现在这三个所有的环境下

Practical example
一个简单的网站,被安装到/var/www/foobarcom。下面是一个部署的top.sls:

 

使用pillar,按照角色分配给主机:

 

 

 

最后,编写部署网站的sls模块:

 

 

根据上面的这个sls模块所定义,那么网站的源代码就应该放置在下面这个位置:
/srv/salt/dev/webserver/src/foobarcom.

首先,让我们先部署到dev的环境下,使用state.highstate

然而,如果并不想通过top.sls文件将所有的states配置部署到minions(假如当前我们已经当以很多的了state),使用state.sls仅仅不是foobarcom这个state

 

一旦网站需要部署到dev和qa,那么只需要把文件从/srv/salt/dev/webserver/src/foobarcom移动到/srv/salt/qa/webserver/src/foobarcom,并且执行以下命令:

 

最后网站被qa测试通过,就可以将文件从/srv/salt/qa/webserver/src/foobarcom 移动到/srv/salt/prod/webserver/src/foobarcom,执行以下命令:

 

由于salt的fileserver的继承,即使从/srv/salt/prod移走,你仍然可以通过相同的url(salt://)同时从qa和dev环境下访问

 

参考:http://docs.saltstack.com/topics/tutorials/states_pt4.html

 

 http://netkiller-github-com.iteye.com/blog/1927482

第 126 章 SaltStack

http://saltstack.com/

126.1. 安装 Salt Stack

126.1.1. 服务端安装

yum install salt-master
			

 

chkconfig salt-master on
service salt-master start
			

126.1.2. 客户端安装

yum install salt-minion
chkconfig salt-minion on

配置 master

			
cp /etc/salt/minion{,.original}
sed -i '12,12imaster: salt.example.org' /etc/salt/minion
cat >> /etc/hosts <<'EOF'

192.168.2.1	salt.example.org
EOF
			
service salt-minion start

126.1.3. 防火墙配置

-A INPUT -p tcp -m multiport --dports 4505,4506 -m state --state NEW -j ACCEPT
			

126.1.4. key 管理

登陆master服务器,输入 salt-key 查看接入的 minion 客户端。

# salt-key
Accepted Keys:
Unaccepted Keys:
haproxy
Rejected Keys:
			

接受客户端 key

# salt-key -a haproxy
The following keys are going to be accepted:
Unaccepted Keys:
haproxy
Proceed? [n/Y] y
Key for minion haproxy accepted.
			

至此,master 与 minion 已经建立了信任关系

126.1.5. 测试

你可以运行下面命令测试你的 minion

salt '*' test.arg 1 "two" 3.1 txt="hello" wow='{a: 1, b: "hello"}'
salt '*' test.arg_repr 1 "two" 3.1 txt="hello" wow='{a: 1, b: "hello"}'
salt '*' test.collatz 3
salt '*' test.conf_test
salt '*' test.cross_test file.gid_to_group 0
salt '*' test.echo 'foo bar baz quo qux'
salt '*' test.fib 3
salt '*' test.get_opts
salt '*' test.kwarg num=1 txt="two" env='{a: 1, b: "hello"}'
salt '*' test.not_loaded
salt '*' test.outputter foobar
salt '*' test.ping
salt '*' test.provider service
salt '*' test.providers
salt '*' test.rand_sleep 60
salt '*' test.retcode 42
salt '*' test.sleep 20
salt '*' test.tty tty0 'This is a test'
salt '*' test.tty pts3 'This is a test'
salt '*' test.version
salt '*' test.versions_information
salt '*' test.versions_report
			

我通常只作ping测试

# salt '*' test.ping
haproxy:
    True

# salt '*' test.versions_information
haproxy:
    ----------
    Jinja2:
        unknown
    M2Crypto:
        0.20.2
    PyYAML:
        3.09
    PyZMQ:
        2.2.0.1
    Python:
        2.6.6 (r266:84292, Feb 22 2013, 00:00:18)
    Salt:
        0.16.0
    ZMQ:
        3.2.3
    msgpack-pure:
        None
    msgpack-python:
        0.1.13
    pycrypto:
        2.0.1

# salt '*' test.versions_report
haproxy:
               Salt: 0.16.0
             Python: 2.6.6 (r266:84292, Feb 22 2013, 00:00:18)
             Jinja2: unknown
           M2Crypto: 0.20.2
     msgpack-python: 0.1.13
       msgpack-pure: Not Installed
           pycrypto: 2.0.1
             PyYAML: 3.09
              PyZMQ: 2.2.0.1
                ZMQ: 3.2.3

 

126.2. salt 命令

		
# salt '*' sys.doc | grep "salt '*'"

salt '*' acl.delfacl user myuser /tmp/house/kitchen
salt '*' acl.delfacl default:group mygroup /tmp/house/kitchen
salt '*' acl.delfacl d:u myuser /tmp/house/kitchen
salt '*' acl.delfacl g myuser /tmp/house/kitchen /tmp/house/livingroom
salt '*' acl.getfacl /tmp/house/kitchen
salt '*' acl.getfacl /tmp/house/kitchen /tmp/house/livingroom
salt '*' acl.addfacl user myuser rwx /tmp/house/kitchen
salt '*' acl.addfacl default:group mygroup rx /tmp/house/kitchen
salt '*' acl.addfacl d:u myuser 7 /tmp/house/kitchen
salt '*' acl.addfacl g mygroup 0 /tmp/house/kitchen /tmp/house/livingroom
salt '*' acl.version
salt '*' acl.wipefacls /tmp/house/kitchen
salt '*' acl.wipefacls /tmp/house/kitchen /tmp/house/livingroom
salt '*' aliases.get_target <alias>
salt '*' aliases.has_target <alias> <target>
salt '*' aliases.list_aliases
salt '*' aliases.rm_alias <alias>
salt '*' aliases.set_target <alias> <target>
salt '*' alternatives.check_installed name path
salt '*' alternatives.display <command name>
salt '*' alternatives.install name link path priority
salt '*' alternatives.remove name path
salt '*' alternatives.show_current emacs
salt '*' archive.gunzip /tmp/sourcefile.txt.gz
salt '*' archive.gunzip template=jinja /tmp/{{grains.id}}.txt.gz
salt '*' archive.gzip /tmp/sourcefile.txt
salt '*' archive.gzip template=jinja /tmp/{{grains.id}}.txt
salt '*' archive.rar /tmp/rarfile.rar /tmp/sourcefile1 /tmp/sourcefile2
salt '*' archive.rar template=jinja /tmp/rarfile.rar /tmp/sourcefile1 /tmp/{{grains.id}}.txt
salt '*' archive.tar cjvf /tmp/tarfile.tar.bz2 /tmp/file_1 /tmp/file_2
salt '*' archive.tar template=jinja cjvf /tmp/salt.tar.bz2 {{grains.saltpath}}
salt '*' archive.unrar /tmp/rarfile.rar /home/strongbad/ file_1 file_2
salt '*' archive.unrar template=jinja /tmp/rarfile.rar /tmp/{{grains.id}}/ file_1 file_2
salt '*' archive.unzip /tmp/zipfile.zip /home/strongbad/ file_1 file_2
salt '*' archive.unzip template=jinja /tmp/zipfile.zip /tmp/{{grains.id}}/ file_1 file_2
salt '*' archive.zip /tmp/zipfile.zip /tmp/sourcefile1 /tmp/sourcefile2
salt '*' archive.zip template=jinja /tmp/zipfile.zip /tmp/sourcefile1 /tmp/{{grains.id}}.txt
salt '*' cmd.exec_code ruby 'puts "cheese"'
salt '*' cmd.has_exec cat
salt '*' cmd.retcode "file /bin/bash"
salt '*' cmd.retcode template=jinja "file {{grains.pythonpath[0]}}/python"
salt '*' cmd.retcode "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.run "ls -l | awk '/foo/{print \$2}'"
salt '*' cmd.run template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \$2}'"
salt '*' cmd.run "Get-ChildItem C:\ " shell='powershell'
salt '*' cmd.run "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.run_all "ls -l | awk '/foo/{print \$2}'"
salt '*' cmd.run_all template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \$2}'"
salt '*' cmd.run_all "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.run_stderr "ls -l | awk '/foo/{print \$2}'"
salt '*' cmd.run_stderr template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \$2}'"
salt '*' cmd.run_stderr "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.run_stdout "ls -l | awk '/foo/{print \$2}'"
salt '*' cmd.run_stdout template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \$2}'"
salt '*' cmd.run_stdout "grep f" stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.script salt://scripts/runme.sh
salt '*' cmd.script salt://scripts/runme.sh 'arg1 arg2 "arg 3"'
salt '*' cmd.script salt://scripts/windows_task.ps1 args=' -Input c:\tmp\infile.txt' shell='powershell'
salt '*' cmd.script salt://scripts/runme.sh stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.script_retcode salt://scripts/runme.sh
salt '*' cmd.script_retcode salt://scripts/runme.sh stdin='one\ntwo\nthree\nfour\nfive\n'
salt '*' cmd.which cat
salt '*' cmd.which_bin '[pip2, pip, pip-python]'
salt '*' config.backup_mode
salt '*' config.dot_vals host
salt '*' qemu.gather_bootstrap_script True
salt '*' config.get pkg:apache
salt '*' config.manage_mode
salt '*' config.option redis.host
salt '*' config.valid_fileproto salt://path/to/file
salt '*' cp.cache_dir salt://path/to/dir
salt '*' cp.cache_file salt://path/to/file
salt '*' cp.cache_files salt://pathto/file1,salt://pathto/file1
salt '*' cp.cache_local_file /etc/hosts
salt '*' cp.cache_master
salt '*' cp.get_dir salt://path/to/dir/ /minion/dest
salt '*' cp.get_file salt://path/to/file /minion/dest
salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja
salt '*' cp.get_file_str salt://my/file
salt '*' cp.get_template salt://path/to/template /minion/dest
salt '*' cp.get_url salt://my/file /tmp/mine
salt '*' cp.get_url http://www.slashdot.org /tmp/index.html
salt '*' cp.hash_file salt://path/to/file
salt '*' cp.is_cached salt://path/to/file
salt '*' cp.list_master
salt '*' cp.list_master_dirs
salt '*' cp.list_minion
salt '*' cp.list_states
salt '*' cp.push /etc/fstab
salt '*' cron.list_tab root
salt '*' cron.list_tab root
salt '*' cron.raw_cron root
salt '*' cron.rm_job root /usr/local/weekly
salt '*' cron.rm_job root /usr/bin/foo dayweek=1
salt '*' cron.rm_env root MAILTO
salt '*' cron.rm_job root /usr/local/weekly
salt '*' cron.rm_job root /usr/bin/foo dayweek=1
salt '*' cron.set_env root MAILTO user@example.com
salt '*' cron.set_job root '*' '*' '*' '*' 1 /usr/local/weekly
salt '*' cron.set_special @hourly 'echo foobar'
salt '*' cron.write_cron_file root /tmp/new_cron
salt '*' cron.write_cron_file_verbose root /tmp/new_cron
salt '*' daemontools.full_restart <service name>
salt '*' daemontools.get_all
salt '*' daemontools.reload <service name>
salt '*' daemontools.restart <service name>
salt '*' daemontools.start <service name>
salt '*' daemontools.status <service name>
salt '*' daemontools.stop <service name>
salt '*' daemontools.term <service name>
salt '*' data.cas <key> <value> <old_value>
salt '*' data.clear
salt '*' data.dump '{'eggs': 'spam'}'
salt '*' data.getval <key>
salt '*' data.getvals <key> [<key> ...]
salt '*' data.load
salt '*' data.update <key> <value>
salt '*' disk.inodeusage
salt '*' disk.usage
salt '*' django.collectstatic <settings_module>
salt '*' django.command <settings_module> <command>
salt '*' django.createsuperuser <settings_module> user user@example.com
salt '*' django.loaddata <settings_module> <comma delimited list of fixtures>
salt '*' django.syncdb <settings_module>
salt '*' dnsmasq.version
salt '*' dnsmasq.get_config
salt '*' dnsmasq.get_config file=/etc/dnsmasq.conf
salt '*' dnsmasq.set_config domain=mydomain.com
salt '*' dnsmasq.set_config follow=False domain=mydomain.com
salt '*' dnsmasq.set_config file=/etc/dnsmasq.conf domain=mydomain.com
salt '*' dnsmasq.version
salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 ad1.yuk.co,ad2.yuk.co
salt '*' dnsutil.hosts_delete /etc/hosts ad1.yuk.co
salt '*' dnsutil.hosts_delete /etc/hosts ad2.yuk.co,ad1.yuk.co
salt '*' dnsutil.parse_hosts
salt '*' event.fire 'stuff to be in the event' 'tag'
salt '*' event.fire_master 'stuff to be in the event' 'tag'
salt '*' extfs.attributes /dev/sda1
salt '*' extfs.blocks /dev/sda1
salt '*' extfs.dump /dev/sda1
salt '*' extfs.mkfs /dev/sda1 fs_type=ext4 opts='acl,noexec'
salt '*' extfs.tune /dev/sda1 force=True label=wildstallyns opts='acl,noexec'
salt '*' file.append /etc/motd \
salt '*' file.check_file_meta /etc/httpd/conf.d/httpd.conf salt://http/httpd.conf '{hash_type: 'md5', 'hsum': <md5sum>}' root, root, '755' base
salt '*' file.check_hash /etc/fstab md5=<md5sum>
salt '*' file.check_managed /etc/httpd/conf.d/httpd.conf salt://http/httpd.conf '{hash_type: 'md5', 'hsum': <md5sum>}' root, root, '755' jinja True None None base
salt '*' file.check_perms /etc/sudoers '{}' root root 400
salt '*' file.chgrp /etc/passwd root
salt '*' file.chown /etc/passwd root root
salt '*' file.comment /etc/modules pcspkr
salt '*' file.contains /etc/crontab 'mymaintenance.sh'
salt '*' file.contains_glob /etc/foobar '*cheese*'
salt '*' file.contains_regex /etc/crontab
salt '*' file.contains_regex_multiline /etc/crontab '^maint'
salt '*' file.directory_exists /etc
salt '*' file.file_exists /etc/passwd
salt '*' file.find / type=f name=\*.bak size=+10m
salt '*' file.find /var mtime=+30d size=+10m print=path,size,mtime
salt '*' file.find /var/log name=\*.[0-9] mtime=+30d size=+10m delete
salt '*' file.get_diff /home/fred/.vimrc salt://users/fred/.vimrc
salt '*' file.get_gid /etc/passwd
salt '*' file.get_group /etc/passwd
salt '*' file.get_hash /etc/shadow
salt '*' file.get_managed /etc/httpd/conf.d/httpd.conf jinja salt://http/httpd.conf '{hash_type: 'md5', 'hsum': <md5sum>}' root root '755' base None None
salt '*' file.get_mode /etc/passwd
salt '*' file.get_selinux_context /etc/hosts
salt '*' file.get_sum /etc/passwd sha512
salt '*' file.get_uid /etc/passwd
salt '*' file.get_user /etc/passwd
salt '*' file.gid_to_group 0
salt '*' file.group_to_gid root
salt '*' file.makedirs /opt/code
salt '*' file.makedirs_perms /opt/code
salt '*' file.manage_file /etc/httpd/conf.d/httpd.conf '{}' salt://http/httpd.conf '{hash_type: 'md5', 'hsum': <md5sum>}' root root '755' base ''
salt '*' file.mkdir /opt/jetty/context
salt '*' file.patch /opt/file.txt /tmp/file.txt.patch
salt '*' file.sed /etc/httpd/httpd.conf 'LogLevel warn' 'LogLevel info'
salt '*' file.remove /tmp/foo
salt '*' file.rename /path/to/src /path/to/dst
salt '*' file.restorecon /home/user/.ssh/authorized_keys
salt '*' file.sed /etc/httpd/httpd.conf 'LogLevel warn' 'LogLevel info'
salt '*' file.contains /etc/crontab 'mymaintenance.sh'
salt '*' file.set_mode /etc/passwd 0644
salt '*' file.set_selinux_context path <role> <type> <range>
salt '*' file.source_list salt://http/httpd.conf '{hash_type: 'md5', 'hsum': <md5sum>}' base
salt '*' file.stats /etc/passwd
salt '*' file.symlink /path/to/file /path/to/link
salt '*' file.touch /var/log/emptyfile
salt '*' file.uid_to_user 0
salt '*' file.uncomment /etc/hosts.deny 'ALL: PARANOID'
salt '*' file.user_to_uid root
salt '*' gem.install vagrant
salt '*' gem.sources_add http://rubygems.org/
salt '*' gem.sources_list
salt '*' gem.sources_remove http://rubygems.org/
salt '*' gem.uninstall vagrant
salt '*' gem.update vagrant
salt '*' gem.update_system
salt '*' git.add /path/to/git/repo /path/to/file
salt '*' git.archive /path/to/repo /path/to/archive.tar.gz
salt '*' git.checkout /path/to/repo somebranch user=jeff
salt '*' git.checkout /path/to/repo opts='testbranch -- conf/file1 file2'
salt '*' git.checkout /path/to/repo rev=origin/mybranch opts=--track
salt '*' git.clone /path/to/repo git://github.com/saltstack/salt.git
salt '*' git.clone /path/to/repo.git\
salt '*' git.commit /path/to/git/repo 'The commit message'
salt '*' git.config_get /path/to/repo user.email
salt '*' git.config_set /path/to/repo user.email me@example.com
salt '*' git.describe /path/to/repo
salt '*' git.describe /path/to/repo develop
salt '*' git.fetch /path/to/repo '--all'
salt '*' git.fetch cwd=/path/to/repo opts='--all' user=johnny
salt '*' git.init /path/to/repo.git opts='--bare'
salt '*' git.fetch /path/to/repo
salt '*' git.merge /path/to/repo @{upstream}
salt '*' git.pull /path/to/repo opts='--rebase origin master'
salt '*' git.push /path/to/git/repo remote-name
salt '*' git.rebase /path/to/repo master
salt '*' git.rebase /path/to/repo 'origin master'
salt '*' git.remote_get /path/to/repo
salt '*' git.remote_get /path/to/repo upstream
salt '*' git.remote_set /path/to/repo remote_url=git@github.com:saltstack/salt.git
salt '*' git.remote_set /path/to/repo origin git@github.com:saltstack/salt.git
salt '*' git.remotes /path/to/repo
salt '*' git.reset /path/to/repo master
salt '*' git.revision /path/to/repo mybranch
salt '*' git.rm /path/to/git/repo /path/to/file
salt '*' git.stash /path/to/repo master
salt '*' git.status /path/to/git/repo
salt '*' git.submodule /path/to/repo.git/sub/repo
salt '*' grains.get pkg:apache
salt '*' grains.item os
salt '*' grains.item os osrelease oscodename
salt '*' grains.item host sanitize=True
salt '*' grains.items
salt '*' grains.items sanitize=True
salt '*' grains.ls
salt '*' grains.setval key val
salt '*' group.add foo 3456
salt '*' group.chgid foo 4376
salt '*' group.delete foo
salt '*' group.getent
salt '*' group.info foo
salt '*' grub.conf
salt '*' grub.version
salt '*' hg.archive /path/to/repo output=/tmp/archive.tgz fmt=tgz
salt '*' hg.clone /path/to/repo https://bitbucket.org/birkenfeld/sphinx
salt '*' hg.describe /path/to/repo
salt '*' hg.pull /path/to/repo '-u'
salt '*' hg.revision /path/to/repo mybranch
salt '*' hosts.add_host <ip> <alias>
salt '*' hosts.get_alias <ip addr>
salt '*' hosts.get_ip <hostname>
salt '*' hosts.has_pair <ip> <alias>
salt '*' hosts.list_hosts
salt '*' hosts.rm_host <ip> <alias>
salt '*' hosts.set_host <ip> <alias>
salt '*' qemu_nbd.bootstrap /srv/salt-images/host.qcow 4096 qcow2
salt '*' img.mount_image /tmp/foo
salt '*' img.seed /tmp/image.qcow2
salt '*' img.umount_image /mnt/foo
salt '*' ip.apply_network_settings
salt '*' ip.build_bond bond0 mode=balance-alb
salt '*' ip.build_interface eth0 eth <settings>
salt '*' ip.build_network_settings <settings>
salt '*' ip.build_routes eth0 <settings>
salt '*' ip.down eth0
salt '*' ip.get_bond bond0
salt '*' ip.get_interface eth0
salt '*' ip.get_network_settings
salt '*' ip.get_routes eth0
salt '*' ip.up eth0
salt '*' iptables.append filter INPUT rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
salt '*' iptables.delete filter INPUT position=3
salt '*' iptables.delete filter INPUT rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
salt '*' iptables.flush filter
salt '*' iptables.get_policy filter INPUT
salt '*' iptables.get_rules
salt '*' iptables.get_saved_policy filter INPUT
salt '*' iptables.get_saved_policy filter INPUT conf_file=/etc/iptables.saved
salt '*' iptables.get_saved_rules
salt '*' iptables.insert filter INPUT position=3 rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
salt '*' iptables.save /etc/sysconfig/iptables
salt '*' iptables.set_policy filter INPUT ACCEPT
salt '*' iptables.version
salt '*' key.finger
salt '*' keyboard.get_sys
salt '*' keyboard.get_x
salt '*' keyboard.set_sys dvorak
salt '*' keyboard.set_x dvorak
salt '*' kmod.available
salt '*' kmod.check_available kvm
salt '*' kmod.is_loaded kvm
salt '*' kmod.load kvm
salt '*' kmod.lsmod
salt '*' kmod.mod_list
salt '*' kmod.remove kvm
salt '*' locale.get_locale
salt '*' locale.list_avail
salt '*' locale.set_locale 'en_US.UTF-8'
salt '*' locate.locate
salt '*' locate.stats
salt '*' locate.updatedb
salt '*' locate.version
salt '*' logrotate.set rotate 2
salt '*' logrotate.set /var/log/wtmp rotate 2
salt '*' logrotate.show_conf
salt '*' lowpkg.file_list httpd
salt '*' lowpkg.file_list httpd postfix
salt '*' lowpkg.file_list
salt '*' lowpkg.file_list httpd
salt '*' lowpkg.file_list httpd postfix
salt '*' lowpkg.file_list
salt '*' lowpkg.list_pkgs
salt '*' lowpkg.verify
salt '*' match.compound 'L@cheese,foo and *'
salt '*' match.data 'spam:eggs'
salt '*' match.glob '*'
salt '*' match.grain 'os:Ubuntu'
salt '*' match.grain_pcre 'os:Fedo.*'
salt '*' match.ipcidr '192.168.44.0/24'
salt '*' match.list 'server1,server2'
salt '*' match.pcre '.*'
salt '*' match.pillar 'cheese:foo'
salt '*' mine.get '*' network.interfaces
salt '*' mine.get 'os:Fedora' network.interfaces grain
salt '*' mine.send network.interfaces eth0
salt '*' mine.update
salt '*' monit.monitor <service name>
salt '*' monit.restart <service name>
salt '*' monit.start <service name>
salt '*' monit.stop <service name>
salt '*' monit.summary
salt '*' monit.summary <service name>
salt '*' monit.unmonitor <service name>
salt '*' mount.active
salt '*' mount.fstab
salt '*' mount.is_fuse_exec sshfs
salt '*' mount.mount /mnt/foo /dev/sdz1 True
salt '*' mount.remount /mnt/foo /dev/sdz1 True
salt '*' mount.rm_fstab /mnt/foo
salt '*' mount.set_fstab /mnt/foo /dev/sdz1 ext4
salt '*' mount.swapoff /root/swapfile
salt '*' mount.swapon /root/swapfile
salt '*' mount.swaps
salt '*' mount.umount /mnt/foo
salt '*' '*' network.arp
salt '*' network.dig archlinux.org
salt '*' network.hwaddr eth0
salt '*' network.in_subnet 10.0.0.0/16
salt '*' network.interfaces
salt '*' network.ip_addrs
salt '*' network.ip_addrs6
salt '*' network.netstat
salt '*' network.ping archlinux.org
salt '*' network.subnets
salt '*' network.traceroute archlinux.org
salt '*' nginx.configtest
salt '*' nginx.signal reload
salt '*' nginx.version
salt '*' partition.align_check /dev/sda minimal 1
salt '*' partition.check 1
salt '*' partition.cp /dev/sda 2 3
salt '*' partition.get_id /dev/sda 1
salt '*' partition.mkfs /dev/sda2 fat32
salt '*' partition.mklabel /dev/sda msdos
salt '*' partition.mkpart /dev/sda primary fat32 0 639
salt '*' partition.mkpartfs /dev/sda logical ext2 440 670
salt '*' partition.name /dev/sda 1 'My Documents'
salt '*' partition.part_list /dev/sda
salt '*' partition.part_list /dev/sda unit=s
salt '*' partition.part_list /dev/sda unit=kB
salt '*' partition.probe
salt '*' partition.probe /dev/sda
salt '*' partition.rescue /dev/sda 0 8056
salt '*' partition.resize /dev/sda 3 200 850
salt '*' partition.rm /dev/sda 5
salt '*' partition.set /dev/sda 1 boot on
salt '*' partition.set_id /dev/sda 1 83
salt '*' partition.name /dev/sda 1 boot
salt '*' pecl.install fuse
salt '*' pecl.list
salt '*' pecl.uninstall fuse
salt '*' pecl.update fuse
salt '*' pillar.data
salt '*' pillar.data key='roles'
salt '*' pillar.ext 'libvirt: _'
salt '*' pillar.get pkg:apache
salt '*' pillar.data
salt '*' pillar.data key='roles'
salt '*' pillar.raw
salt '*' pillar.raw key='roles'
salt '*' pip.freeze /home/code/path/to/virtualenv/
salt '*' pip.install <package name>,<package2 name>
salt '*' pip.install requirements=/path/to/requirements.txt
salt '*' pip.install <package name> bin_env=/path/to/virtualenv
salt '*' pip.install <package name> bin_env=/path/to/pip_bin
salt '*' pip.install markdown,django editable=git+https://github.com/worldcompany/djangoembed.git#egg=djangoembed upgrade=True no_deps=True
salt '*' pip.list salt
salt '*' pip.uninstall <package name>,<package2 name>
salt '*' pip.uninstall requirements=/path/to/requirements.txt
salt '*' pip.uninstall <package name> bin_env=/path/to/virtualenv
salt '*' pip.uninstall <package name> bin_env=/path/to/pip_bin
salt '*' pkg.latest_version <package name>
salt '*' pkg.latest_version <package name> fromrepo=epel-testing
salt '*' pkg.latest_version <package1> <package2> <package3> ...
salt '*' pkg.clean_metadata
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
salt '*' pkg.del_repo myrepo
salt '*' pkg.del_repo myrepo basedir=/path/to/dir
salt '*' pkg.file_list httpd
salt '*' pkg.file_list httpd postfix
salt '*' pkg.file_list
salt '*' pkg.file_list httpd
salt '*' pkg.file_list httpd postfix
salt '*' pkg.file_list
salt '*' pkg.get_repo myrepo
salt '*' pkg.get_repo myrepo basedir=/path/to/dir
salt '*' pkg.group_diff 'Perl Support'
salt '*' pkg.group_info 'Perl Support'
salt '*' pkg.group_install groups='["Group 1", "Group 2"]'
salt '*' pkg.group_install 'My Group' skip='["foo", "bar"]'
salt '*' pkg.group_install 'My Group' include='["foo", "bar"]'
salt '*' pkg.group_list
salt '*' pkg.install <package name>
salt '*' pkg.install pkgs='["foo", "bar"]'
salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3-4.el6"}]'
salt '*' pkg.install sources='[{"foo": "salt://foo.rpm"}, {"bar": "salt://bar.rpm"}]'
salt '*' pkg.latest_version <package name>
salt '*' pkg.latest_version <package name> fromrepo=epel-testing
salt '*' pkg.latest_version <package1> <package2> <package3> ...
salt '*' pkg.list_pkgs
salt '*' pkg.list_repos
salt '*' pkg.list_upgrades
salt '*' pkg.mod_repo reponame enabled=1 gpgcheck=1
salt '*' pkg.mod_repo reponame basedir=/path/to/dir enabled=1
salt '*' pkg.mod_repo reponame baseurl= mirrorlist=http://host.com/
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
salt '*' pkg.purge <package name>
salt '*' pkg.purge <package1>,<package2>,<package3>
salt '*' pkg.purge pkgs='["foo", "bar"]'
salt '*' pkg.refresh_db
salt '*' pkg.remove <package name>
salt '*' pkg.remove <package1>,<package2>,<package3>
salt '*' pkg.remove pkgs='["foo", "bar"]'
salt '*' pkg.upgrade
salt '*' pkg.upgrade_available <package name>
salt '*' pkg.verify
salt '*' pkg.version <package name>
salt '*' pkg.version <package1> <package2> <package3> ...
salt '*' pkg_resource.add_pkg '{}' bind 9
salt '*' pkg_resource.check_desired
salt '*' pkg_resource.compare
salt '*' pkg_resource.find_changes
salt '*' pkg_resource.pack_pkgs '["foo", {"bar": 1.2}, "baz"]'
salt '*' pkg_resource.pack_sources '[{"foo": "salt://foo.rpm"}, {"bar": "salt://bar.rpm"}]'
salt '*' pkg_resource.parse_targets
salt '*' pkg_resource.perform_cmp
salt '*' pkg_resource.sort_pkglist '["3.45", "2.13"]'
salt '*' pkg_resource.stringify 'vim: 7.127'
salt '*' pkg_resource.version vim
salt '*' pkg_resource.version foo bar baz
salt '*' pkg_resource.version 'python*'
salt '*' puppet.fact kernel
salt '*' puppet.facts
salt '*' puppet.noop
salt '*' puppet.noop tags=basefiles::edit,apache::server
salt '*' puppet.noop debug
salt '*' puppet.noop apply /a/b/manifest.pp modulepath=/a/b/modules tags=basefiles::edit,apache::server
salt '*' puppet.run
salt '*' puppet.run tags=basefiles::edit,apache::server
salt '*' puppet.run debug
salt '*' puppet.run apply /a/b/manifest.pp modulepath=/a/b/modules tags=basefiles::edit,apache::server
salt '*' quota.get_mode
salt '*' quota.off
salt '*' quota.on
salt '*' quota.report /media/data
salt '*' quota.set /media/data user=larry block-soft-limit=1048576
salt '*' quota.set /media/data group=painters file-hard-limit=1000
salt '*' quota.stats
salt '*' quota.warn
salt '*' rbenv.default
salt '*' rbenv.default 2.0.0-p0
salt '*' rbenv.install
salt '*' rbenv.install_ruby 2.0.0-p0
salt '*' rbenv.is_installed
salt '*' rbenv.list
salt '*' rbenv.uninstall_ruby 2.0.0-p0
salt '*' rbenv.update
salt '*' rbenv.versions
salt '*' ret.get_fun mysql network.interfaces
salt '*' ret.get_jid redis 20421104181954700505
salt '*' ret.get_jids mysql
salt '*' ret.get_minions mysql
salt '*' rvm.do 2.0.0 <command>
salt '*' rvm.gemset_copy foobar bazquo
salt '*' rvm.gemset_create 2.0.0 foobar
salt '*' rvm.gemset_delete 2.0.0 foobar
salt '*' rvm.gemset_empty 2.0.0 foobar
salt '*' rvm.gemset_list
salt '*' rvm.gemset_list_all
salt '*' rvm.get
salt '*' rvm.install
salt '*' rvm.install_ruby 1.9.3-p385
salt '*' rvm.is_installed
salt '*' rvm.list
salt '*' rvm.reinstall_ruby 1.9.3-p385
salt '*' rvm.rubygems 2.0.0 1.8.24
salt '*' rvm.set_default 2.0.0
salt '*' rvm.wrapper <ruby_string> <wrapper_prefix>
salt '*' saltutil.find_job <job id>
salt '*' saltutil.is_running state.highstate
salt '*' saltutil.kill_job <job id>
salt '*' saltutil.refresh_modules
salt '*' saltutil.refresh_pillar
salt '*' saltutil.regen_keys
salt '*' saltutil.revoke_key
salt '*' saltutil.running
salt '*' saltutil.signal_job <job id> 15
salt '*' saltutil.sync_all
salt '*' saltutil.sync_grains
salt '*' saltutil.sync_modules
salt '*' saltutil.sync_outputters
salt '*' saltutil.sync_renderers
salt '*' saltutil.sync_returners
salt '*' saltutil.sync_states
salt '*' saltutil.term_job <job id>
salt '*' saltutil.update 0.10.3
salt '*' service.disable <service name>
salt '*' service.disabled <service name>
salt '*' service.enable <service name>
salt '*' service.enabled <service name>
salt '*' service.get_all
salt '*' service.get_all limit=upstart
salt '*' service.get_all limit=sysvinit
salt '*' service.get_disabled
salt '*' service.get_disabled limit=upstart
salt '*' service.get_disabled limit=sysvinit
salt '*' service.get_enabled
salt '*' service.get_enabled limit=upstart
salt '*' service.get_enabled limit=sysvinit
salt '*' service.reload <service name>
salt '*' service.restart <service name>
salt '*' service.start <service name>
salt '*' service.status <service name>
salt '*' service.stop <service name>
salt '*' shadow.info root
salt '*' shadow.set_date username 0
salt '*' shadow.set_inactdays username 7
salt '*' shadow.set_maxdays username 90
salt '*' shadow.set_mindays username 7
salt '*' shadow.set_password root '$1$UYCIxa628.9qXjpQCjM4a..'
salt '*' shadow.set_warndays username 7
salt '*' sqlite3.fetch /root/test.db 'SELECT * FROM test;'
salt '*' sqlite3.indexes /root/test.db
salt '*' sqlite3.indices /root/test.db
salt '*' sqlite3.modify /root/test.db 'CREATE TABLE test(id INT, testdata TEXT);'
salt '*' sqlite3.sqlite_version
salt '*' sqlite3.tables /root/test.db
salt '*' sqlite3.version
salt '*' ssh.auth_keys root
salt '*' ssh.check_key <user> <key> <enc> <comment> <options>
salt '*' root salt://ssh/keyfile
salt '*' ssh.check_known_host <user> <hostname> key='AAAA...FAaQ=='
salt '*' ssh.get_known_host <user> <hostname>
salt '*' ssh.host_keys
salt '*' ssh.recv_known_host <hostname> enc=<enc> port=<port>
salt '*' ssh.rm_auth_key <user> <key>
salt '*' ssh.rm_known_host <user> <hostname>
salt '*' ssh.set_auth_key <user> '<key>' enc='dsa'
salt '*' ssh.set_auth_key_from_file <user>                salt://ssh_keys/<user>.id_rsa.pub
salt '*' ssh.set_known_host <user> fingerprint='xx:xx:..:xx'                  enc='ssh-rsa' config='.ssh/known_hosts'
salt '*' state.clear_cache
salt '*' state.high '{"vim": {"pkg": ["installed"]}}'
salt '*' state.highstate
salt '*' state.low '{"state": "pkg", "fun": "installed", "name": "vi"}'
salt '*' state.running
salt '*' state.show_highstate
salt '*' state.show_lowstate
salt '*' state.show_sls core,edit.vim dev
salt '*' state.show_top
salt '*' state.single pkg.installed name=vim
salt '*' state.sls core,edit.vim dev
salt '*' state.template '<Path to template on the minion>'
salt '*' state.template_str '<Template String>'
salt '*' state.top reverse_top.sls
salt '*' status.all_status
salt '*' status.cpuinfo
salt '*' status.cpustats
salt '*' status.custom
salt '*' status.diskstats
salt '*' status.diskusage [paths and/or filesystem types]
salt '*' status.diskusage         # usage for all filesystems
salt '*' status.diskusage / /tmp  # usage for / and /tmp
salt '*' status.diskusage ext?    # usage for ext[234] filesystems
salt '*' status.diskusage / ext?  # usage for / and all ext filesystems
salt '*' status.loadavg
salt '*' status.meminfo
salt '*' status.netdev
salt '*' status.netstats
salt '*' status.pid <sig>
salt '*' status.procs
salt '*' status.uptime
salt '*' status.vmstats
salt '*' status.w
salt '*' supervisord.add <name>
salt '*' supervisord.custom "mstop '*gunicorn*'"
salt '*' supervisord.remove <name>
salt '*' supervisord.reread
salt '*' supervisord.restart <service>
salt '*' supervisord.start <service>
salt '*' supervisord.status
salt '*' supervisord.status_raw
salt '*' supervisord.stop <service>
salt '*' supervisord.update
salt '*' sys.argspec pkg.install
salt '*' sys.argspec sys
salt '*' sys.argspec
salt '*' sys.doc
salt '*' sys.doc sys
salt '*' sys.doc sys.doc
salt '*' sys.doc network.traceroute user.info
salt '*' sys.list_functions
salt '*' sys.list_functions sys
salt '*' sys.list_functions sys user
salt '*' sys.list_modules
salt '*' sys.reload_modules
salt '*' sysctl.assign net.ipv4.ip_forward 1
salt '*' sysctl.get net.ipv4.ip_forward
salt '*' sysctl.persist net.ipv4.ip_forward 1
salt '*' sysctl.show
salt '*' system.halt
salt '*' system.init 3
salt '*' system.poweroff
salt '*' system.reboot
salt '*' system.shutdown
salt '*' test.arg 1 "two" 3.1 txt="hello" wow='{a: 1, b: "hello"}'
salt '*' test.arg_repr 1 "two" 3.1 txt="hello" wow='{a: 1, b: "hello"}'
salt '*' test.collatz 3
salt '*' test.conf_test
salt '*' test.cross_test file.gid_to_group 0
salt '*' test.echo 'foo bar baz quo qux'
salt '*' test.fib 3
salt '*' test.get_opts
salt '*' test.kwarg num=1 txt="two" env='{a: 1, b: "hello"}'
salt '*' test.not_loaded
salt '*' test.outputter foobar
salt '*' test.ping
salt '*' test.provider service
salt '*' test.providers
salt '*' test.rand_sleep 60
salt '*' test.retcode 42
salt '*' test.sleep 20
salt '*' test.tty tty0 'This is a test'
salt '*' test.tty pts3 'This is a test'
salt '*' test.version
salt '*' test.versions_information
salt '*' test.versions_report
salt '*' timezone.get_hwclock
salt '*' timezone.get_offset
salt '*' timezone.get_zone
salt '*' timezone.get_zonecode
salt '*' timezone.set_hwclock UTC
salt '*' timezone.set_zone 'America/Denver'
salt '*' timezone.zone_compare 'America/Denver'
salt '*' user.add name <uid> <gid> <groups> <home> <shell>
salt '*' user.chfullname foo "Foo Bar"
salt '*' user.chgid foo 4376
salt '*' user.chgroups foo wheel,root True
salt '*' user.chhome foo /home/users/foo True
salt '*' user.chhomephone foo "7735551234"
salt '*' user.chroomnumber foo 123
salt '*' user.chshell foo /bin/zsh
salt '*' user.chuid foo 4376
salt '*' user.chworkphone foo "7735550123"
salt '*' user.delete name remove=True force=True
salt '*' user.getent
salt '*' user.info root
salt '*' user.list_groups foo
salt '*' user.list_users
salt '*' virtualenv.create /path/to/new/virtualenv

 

文章出处:http://netkiller.github.io/linux/management/saltstack.html

 

 http://arlen.blog.51cto.com/7175583/1424684

在进行salt操作时候,salt ,跟salt-key是两个经常用到的命令,这里对这两个命令的用法进行说明,也对两个命令的参数进行说明,外文水平有限,就当做是参考参考。

 

Salt 命令

  • salt命令的帮助信息翻译:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
###
[root@localhost salt]# salt --help
Usage: salt [options] '<target>' <function> [arguments]
 
Options:
  --version             版本号
  --versions-report     依赖包版本号
  -h, --help            显示帮助信息
  -c CONFIG_DIR, --config-dir=CONFIG_DIR
                        指定配置文件目录.
                        默认: /etc/salt
  -t TIMEOUT, --timeout=TIMEOUT
                        指定命令超时时间
                        建议默认:5秒
  -s, --static          等到所有minions都执行完了再一起显示数据
                         
  --async               运行所有的salt命令不等待返回结果
  --state-output=STATE_OUTPUT, --state_output=STATE_OUTPUT
                        覆盖掉配置文件中对minion输出内容所定义的 state_output 值
            默认: full
  --subset=SUBSET       对目标minions的随机子集执行程序. 
            minions在执行前会先验证是否存在该命名的函数,再去执行
  -v, --verbose         可以查看详细的命令执行情况
  --show-timeout        显示命令执行超时的 minions
  -b BATCH, --batch=BATCH, --batch-size=BATCH
                        开启salt命令批量执行模式, 既可以指定一批minions,
            也可以用指定百分比的方式确定多少minions批量执行
  -a EAUTH, --auth=EAUTH, --eauth=EAUTH, --extended-auth=EAUTH
                        指定一个扩展的认证系统.
  -T, --make-token      创建并保存一个认证token用于重用.
                        生成的token确保Salt Master在指定的周期内有效.
  --return=RETURNER     设置一个其它的返回方法. 
            默认情况下,salt查询后结果会返回给master, 
            指定return后,数据可以重定向其它的任意数量的系统,数据库或应用.
  -d, --doc, --documentation
            返回指定模块的文档说明,不指定特定的模块则返回全部                    
  --args-separator=ARGS_SEPARATOR
                        指定发送命令跟命令参数的分隔符. 
            当用户想把一个命令当作参数发送给另一个命令执行时,
            是个很好用的选项.
 
  Logging Options:
    指定下面的配置选项会覆盖掉配置文件中对应的配置信息.
 
    -l LOG_LEVEL, --log-level=LOG_LEVEL
                        日志等级. 
            其中一个: 'all''garbage''trace'
            'debug''info''warning''error''quiet'.
                        默认: 'warning'.
    --log-file=LOG_FILE
                        日志文件路径. 默认: /var/log/salt/master.
    --log-file-level=LOG_LEVEL_LOGFILE
                        日志文件记录等级. 其中一个 'all''garbage',
                        'trace''debug''info''warning''error''quiet'.
                        默认: 'warning'.
 
  Target Options:
    Target Selection Options
 
    -E, --pcre          使用pcre(perl)的正则表达式规则匹配目标
    -L, --list          列出一组用逗号或空格隔开的minions id作为执行目标.
    -G, --grain         使用grain信息中指定的机器作为目标
                        例如: "os:Arch*"   'os:CentOS'
    --grain-pcre        使用基于pcre正则式规则的grain匹配目录
                        例如: "os:Arch.*"
    -N, --nodegroup     使用预先定义的节点组作为匹配目标.
    -R, --range         使用一个范围表达式去查找目标.
            例如: %cluster
    -C, --compound      多条件指定目标,根据多个条件筛选匹配目标
                        类似: salt 'G@os:RedHat and webser* or E@database.*'
    -X, --exsel         Instead of using shell globs use the return code of a
                        function.
    -I, --pillar        使用一个pillar 的值来筛选目标, 
                        例如: "role:production*"
    -S, --ipcidr        基于子网络匹配 (CIDR notation) or IPv4 address.
 
  Output Options:
    配置你的完美输出格式
 
    --out=OUTPUT, --output=OUTPUT
                        指定输出的格式,开发一般用json,默认是yaml
            可选如下: 'no_return',
                        'grains''yaml''overstatestage''json''pprint',
                        'nested''raw''highstate''quiet''key''txt',
                        'virt_query'.
    --out-indent=OUTPUT_INDENT, --output-indent=OUTPUT_INDENT
                        指定行缩进的空格数.
            负数为取消行缩进. 
            只有在输出格式适合行缩进,该参数才有效.
    --out-file=OUTPUT_FILE, --output-file=OUTPUT_FILE
                        内容输出到指定的文件
    --no-color, --no-colour
                        关闭颜色显示
    --force-color, --force-colour
                        强制颜色显示
  •  salt 使用实例:

测试所有的minion,并显示超时的对象

1
2
3
#
salt '*' test.ping --show-timeout
# 加入 --show-timeout 选项,可以在测试结果中显示连接失败的minion,如果不加该参数,对于测试失败的minion,返回结果不会显示出来

 

使用json输出方便进行二次开发,调用信息

1
2
3
#
salt '*' status.meminfo --out=json
## 指定json格式的输出,方便作为数据给web进行显示,或是python进行解析

 

复杂的minion匹配方式

1
2
#
salt 'G@os:RedHat and webser* or E@database.*' status.meminfo

 

salt-key 命令

sat-key的帮助文件中文信息:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
[root@localhost ~]# salt-key --help
Usage: salt-key [options]
 
Salt key 用于管理认证key
 
Options:
  --version            显示版本号后退出
  --versions-report    显示程序的所有依赖包版本号,并退出
  -h, --help           帮助信息
  -c CONFIG_DIR, --config-dir=CONFIG_DIR
                       指定配置目录,默认 :/etc/salt/
                          
  -q, --quiet          安静模式,不输出信息到控制台
  -y, --yes            对所有询问是否继续,回答yes,默认:false
 
  Logging Options:
                   设置loggin选项会覆盖掉配置文件中对日志的配置.
 
    --log-file=LOG_FILE                
                        指定日志文件路径,默认: /var/log/salt/key.
    --log-file-level=LOG_LEVEL_LOGFILE
                        日志文件等级,可设置下面中的一个值 'all''garbage',
                        'trace''debug''info''warning''error''quiet'.
                        默认: 'warning'.
    --key-logfile=KEY_LOGFILE
                        将所有的输出发送到指定的文件,默认: '/var/log/salt/key'
                        
 
  Output Options:
    配置输出格式
 
    --out=OUTPUT, --output=OUTPUT
                        把salt-key命令的输出信息发送给指定的outputer. 
                可设置为下面参数值 'no_return''virt_query'.
                        'grains''yaml''overstatestage''json''pprint',
                        'nested''raw''highstate''quiet''key''txt',
                        
    --out-indent=OUTPUT_INDENT, --output-indent=OUTPUT_INDENT
                        设置输出行缩进的空格数. 
                        负数取消输出缩进编排.仅对使用的outputer有效.
    --out-file=OUTPUT_FILE, --output-file=OUTPUT_FILE
                        把显示输出到指定的文件
    --no-color, --no-colour
                        关闭字体颜色
    --force-color, --force-colour
                        强制开启输出颜色渲染
 
  Actions:
    -l ARG, --list=ARG 
                      打印公钥key. 可设置下面三个值
                "pre""un", and "unaccepted" 会显示 不许可/未签名 keys. 
                "acc" or "accepted"会显示 许可/已签名 keys. 
                "rej" or "rejected"会显示拒绝的 keys.  
                "all" 会显示所有 keys.
    -L, --list-all      会显示所有公钥,相当月: "--list all"
    -a ACCEPT, --accept=ACCEPT
                        许可指定的公钥(使用--include-all选项
                        可以指定除了挂起的key外的所有reject状态的公钥)
 
    -A, --accept-all    许可所有pending的公钥
    -r REJECT, --reject=REJECT
                        拒绝指定的公钥 (使用--include-all选项
                        可以指定除了挂起的key外的所有accept状态的公钥)
 
    -R, --reject-all    拒接所有pending的公钥
 
    --include-all         配合 accepting/rejecting 选项使用,指定所有非pending状态的公钥
 
    -p PRINT, --print=PRINT
                        打印指定的公钥
    -P, --print-all     Print all public keys
    -d DELETE, --delete=DELETE
                        根据公钥的名称删除公钥
    -D, --delete-all    删除所有 keys
    -f FINGER, --finger=FINGER
                        打印指定key的指纹信息
    -F, --finger-all    打印所有key的指纹信息
 
  Key 常用选项:
    --gen-keys=GEN_KEYS
                        对生成的key配置设置一个salt使用的名称。
    --gen-keys-dir=GEN_KEYS_DIR
                        设置生成key对的放置目录,默认当前目录。default=.
 
--keysize=KEYSIZE                   
                为生成key设置位数, 仅跟--gen-keys选项配合时有效,
                数值大小必须大于2048,否则会被提升至2048位,默认2048
                        default=2048

 

salt-key的使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
# 显示所有minion的认证信息
salt-key -L
 
# 接受192.168.0.100的认证信息
salt-key -a 192.168.0.100
 
# 接受192.168.0.100的认证信息,不需要手动验证
salt-key -a 192.168.0.100 -y
 
# 接受192.168.0.100的认证信息,即使该minion是Rejected Keys状态
salt-key -a 192.168.0.100 --include-all
 
# 接受所有 Unaccepted Keys 状态的minion的认证信息
salt-key -A
 
# 拒绝认证192.168.0.100
salt-key -d 192.168.0.100
 
# 拒绝所有 Unaccepted Keys 状态的minion
salt-key -D

 

本文出自 “纳米龙” 博客,请务必保留此出处http://arlen.blog.51cto.com/7175583/1424684

http://lansgg.blog.51cto.com/5675165/1543351

本文系统:centos6.5

1
2
3
4
[root@master salt]# rpm -qa |grep salt
salt-minion-2014.1.7-3.el6.noarch
salt-master-2014.1.7-3.el6.noarch
salt-2014.1.7-3.el6.noarch

salt-minion位置:

1
/etc/salt/minion

##### Primary configuration settings #####

#default_include: minion.d/*.conf      #默认值 :minion.d/*.conf  ; minion 可以从其他文件读取配置,默认情况下minion将自动的将minion.d/*.conf中的配置读取出来并应用,其中minion.d目录是相对存在于主配置文件所在的目录

1
default_include: minion.d/*.conf

#master: salt   #默认值 : salt  ; master服务器的ID

1
master: 192.168.28.141

# retry_dns: 30    # 默认值 : 30 ;minion在解析master的ip失败后的重试等待时间,设置为0,则关闭重试

1
retry_dns: 30

#master_port: 4506  #默认值 :4506  ;  设置主回复和认证服务器使用的端口

1
master_port: 4506

#user: root   #默认值 :root ; minion的运行用户,关系到minion执行命令的权限 

1
user: root

#pidfile: /var/run/salt-minion.pid  # 默认值 : pidfile: /var/run/salt-minion.pid  ; minion的pid文件位置

1
pidfile: /var/run/salt-minion.pid

#root_dir: /    #默认值 : /  ;指定该目录为salt运行的根目录,改变它可以使salt从另外一个目录开始运行,好比chroot 

1
root_dir: /

#pki_dir: /etc/salt/pki/minion     # 默认值 : /etc/salt/pki/minion   ; 存储PIK信息的目录

1
pki_dir: /etc/salt/pki/minion

#id:      # 默认值 : null   ;    指定给ID,作为minion与master交互的身份标识,不指定的话,salt通过socket.getfqdn()来获取主机的名称来作为标识

1
id: _host_serv_1.lansgg.com

#append_domain:   # 默认值 : null   ;指定一个主机名称或是一个域名,当socket.getfqdn()获取主机标识失败时候,可以用来作为替补ID

1
append_domain:  error_192_168_28_140

#grains:        #默认值 :         ;使用sls文件给minion自定义静态的grain信息。grains相当于对minion特别信息的匹配对象组,例如例子里面的匹配粒子信息中roles值为webserber,memcache的minion

1
2
3
4
5
6
7
8
grains:
  roles:
    - webserver
    - memcache
  deployment: datacenter4
  cabinet: 13
  cab_u: 14-15
#cachedir: /var/cache/salt/minion   # 默认值 : /var/cache/salt/minion  ; 存放缓存信息,salt工作执行的命令信息
1
cachedir: /var/cache/salt/minion

#verify_env: True       # 默认值 : True    ; 启动时候对配置目录进行验证并设置权限

1
verify_env: True

#cache_jobs: False     # 默认值 :False  ; minion会在本地缓存salt执行过的命令返回数据。可以减少命令执行时间,减低IO,但结果可能不会实时

1
cache_jobs: False

#sock_dir: /var/run/salt/minion  # 默认值 : /var/run/salt/minion  ; minion socket保存目录

1
sock_dir: /var/run/salt/minion

#output: nested    # 默认值 : nested   ; 设置salt-call的默认输出方式,nested是使用默认设置的来输出 

1
output: nested

#color: True      # 默认值 :True      ; 是否对输出结果进行颜色渲染  

1
color: True

# /etc/ssh/sshd_config:
#   file.managed:
#     - source: salt://ssh/sshd_config
#     - backup: minion
#  默认值 : 本功能关闭      ;备份文件,管理文件,递归在“cachedir”/ file_backups相对于原始位置和附加时间戳;唯一有效的设置是“minion”  默认情况下禁用。另外这个状态可以为每个文件指定文件

#backup_mode: minion       # 默认值 : minion  ; 当进行文件更新,修改操作时,备份文件的方式,minion是本地进行备份   

1
2
3
4
5
6
7
/etc/ssh/sshd_config:
 
     file.managed:
 
      source: salt://ssh/sshd_config
 
      - backup: minion

#acceptance_wait_time: 10   # 默认值 : 10   ; 等待master接受minion的认证时间

1
acceptance_wait_time: 10

#acceptance_wait_time_max: 0  # 默认值 : 0  ; 断线重试次数,如果设置为0,无限次重试,如果大于0,则连接重试到该设置值

1
acceptance_wait_time_max: 0

#rejected_retry: False     # 默认值 : False   ; 向master申请key的时候,被拒绝,是否重试

1
ejected_retry: False

#random_reauth_delay: 60   # 默认值 : 60      ;随机重认证间隔(秒),例如当master修改key时,所有的minion需要重新认证,这个时候容易产生syn风暴,设置该随机值,可以使  minion分不同时间进行重新认证,避免该问题

1
random_reauth_delay: 60

auth_timeout: 3      # 默认值   : 3     ;认证超时时间(s)

1
auth_timeout: 5

#loop_interval: 60     # 默认值 : 60    ;minion定时任务执行时间间隔  s

1
loop_interval: 300

#grains_refresh_every = 1    # 默认值  1       ;   对grains定时检测,(min),0为不检测

1
#grains_refresh_every = 1

# grains_cache: False   # 默认值 : False       ;对grains进行缓存

1
grains_cache: False

#dns_check: True     # 默认值  : True  ; 检测dns解析是否正常的

1
dns_check: True

#ipc_mode: ipc     # 默认值 : ipc  ; windows缺少IPC协议支持,而是使用更慢的TCP来作为内部进程交流的协议,在windows上需要设置为tcp

1
ipc_mode: ipc

#tcp_pub_port: 4510
#tcp_pull_port: 4511                ;上面 当设置为tcp模式时候,该参数覆盖掉原先minon指定的tcp端口

1
2
tcp_pub_port: 4510
tcp_pull_port: 4511

# include: /etc/salt/extra_config      # 默认值 : /etc/salt/extra_config      ;可以包含其他文件中的配置,要启用此功能,通过此参数定义路径或文件,此路径可以是相对的也可以是绝对的,相对的,会被看作相对于主配置文件所在的目录, 路径中还可以使用类似于shell风格的通配符,如果没有文件匹配的路径传递给此选项,那么master将会在日志中记录一条警告的消息 

1
2
3
#include:
  /etc/salt/extra_config
  /etc/roles/webserver

#####   Minion module management     #####

#disable_modules: [cmd,test]    #         ;  限制允许执行的模块,对特别的权限可以进行设置,防止服务器重启等

1
disable_modules: [cmd,test]

#module_dirs: []
#returner_dirs: []
#states_dirs: []
#render_dirs: []

########模块可以通过指定任意目录进行加载;指定一系列的外部目录用于搜索minion的模块以及returners。指定的路径必须给minion完全的操作权限

1
2
3
4
module_dirs: []
returner_dirs: []
states_dirs: []
render_dirs: []

#providers:        #           ;    minion的模块provider可以通过参数providers来进行特别指定

1
2
providers:
  pkg: yumpkg5

#####    State Management Settings    #####

#renderer: yaml_jinja     # 默认值   : yaml_jinja       ;state配置文件支持下面的配置语法,通过执行该参数,告诉saltstatck解析state模板的语言方法# yaml_jinja

# yaml_mako    # yaml_wempy    # json_jinja        # json_mako      # json_wempy

1
renderer: yaml_jinja

#failhard: False      # 默认值 : False     ;   设置一个全局的failhard表示,当单个的状态执行失败后,将会通知所有的状态停止运行状态

1
failhard: False

#autoload_dynamic_modules: True    # 默认值  : True  ;自动发现并加载master上的模块

1
autoload_dynamic_modules: True

#clean_dynamic_modules: True     # 默认值     : True     ;如果发现master上的模块已经清除,则自动清楚对应的模块

1
clean_dynamic_modules: True

#environment: None         # 默认值  : None   ;master在运行states的时候,通常不会把minion分割出来给任意一个单独的环境,但在minion端,可以自行进行独立的环境设置

1
environment: None

#state_top: top.sls      # 默认值   : top.sls  ; 指定top.sls文件的位置  

1
state_top: top.sls

#startup_states: ''          # 默认值: ‘‘   ;在minion daemon开始时执行states.       # 'highstate' -- 执行 state.highstate       # 'sls' -- 读取 sls_list 参数配置的路径下的sls文件列表并执行          # 'top' -- 读取top_file参数设置的文件并执行master上面设置的sls配置

1
startup_states: ''

#sls_list:      # 默认值  :   ;  当startup_states配置为sls,该参数列出minion要运行的states文件

1
2
3
sls_list:
  - edit.vim
  - hyper

#top_file: ''    # 默认值  :’’  ;    当startup_states是top时,指定要执行的top文件    

1
top_file: ''

#####     File Directory Settings    #####

#file_client: remote      # 默认值  : remote   ; 设置minion的文件客户端,reomote,默认选项,minon会到master去查找文件;设置为local,则minion会在本地查找配置文件

1
file_client: remote

#file_roots:
#  base:
#    - /srv/salt      # 默认值 :      ;  设置文件客户端路径

1
2
3
4
5
6
7
8
9
 file_roots:
   base:
     /srv/salt/
   dev:
     /srv/salt/dev/services
     /srv/salt/dev/states
   prod:
     /srv/salt/prod/services
     /srv/salt/prod/states

# fileserver_limit_traversal: False   # 默认值 : False   ;设置saltstack查找state文件时候,仅遍历查找带sls后缀的文件或是带_modules后缀的目录

1
fileserver_limit_traversal: False

#pillar_roots:      # 默认值    :         ; 当file_client设置为local时候,该参数制定pillar的搜索路径

1
2
3
pillar_roots:
  base:
    /srv/pillar

######        Security settings       #####

#open_mode: False   # 默认值  : False   ;  open_mode是一个危险的安全特性,当master遇到pki认证系统,秘钥混淆和身份验证失效时,打开open_mode,master将会接受 所有的身份验证。这将会清理掉pki秘钥接受的minions。通常情况下open_mode不应该被打开,它只适用于短时间内清理pki keys,若要打开它,可将值调整为True

1
open_mode: False

#permissive_pki_access: False   # 默认值  : False   ;pki keys的查看权限

1
permissive_pki_access:False

#state_verbose: True      # 默认值 :True   ;state_verbose允许从minions返回更多详细的信息,通常清空下只返回失败或者已经更改,但是将state_verbose设置为True,将会返回所有的状态检查

1
state_verbose: True

#state_output: full   # 默认值 : full  ;state_output的设置将会改变信息输出的格式,当被设置为”full”时,将全部的输出一行一行的显示输出;当被设置为”terse“时,将会 被缩短为一行进行输出;当被设置为”mixed”时,输出样式将会是简洁的,除非状态失败,这种情况下将会全部输出;当被设置为”change”时,输出 将会完全输出除非状态没有改变

1
state_output: full

#master_finger: ''   # 默认值 : ' ' ;

1
master_finger: ''

######         Thread settings        #####


#log_file: /var/log/salt/minion   # 默认值 : /var/log/salt/minion  ; log输出路径设置  ;并且可以输送到远端

1
2
3
#log_file: /var/log/salt/minion
#log_file: file:///dev/log
log_file: udp://loghost:10514

#key_logfile: /var/log/salt/key  # 默认值 : /var/log/salt/key  ; key log输出路径

1
key_logfile: /var/log/salt/key

#log_level: warning  # 默认值 : warning  ;控制台(console)日志默认输出等级: 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'

1
log_level: warning

#log_level_logfile:  # 默认值 : warning  ;日志文件输出等级:'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.

1
log_level_logfile:warning

#log_datefmt: '%H:%M:%S'   # 默认值 : '%H:%M:%S'  ; 控制台日志日期格式 

1
log_datefmt: '%H:%M:%S'

#log_datefmt_logfile: '%Y-%m-%d %H:%M:%S'   # 默认值 :'%Y-%m-%d %H:%M:%S'  ;  日志文件日期格式

1
log_datefmt_logfile: '%Y-%m-%d %H:%M:%S'

#log_fmt_console: '[%(levelname)-8s] %(message)s'  # 默认值 : '[%(levelname)-8s] %(message)s'  ; 控制台日志格式

1
log_fmt_console: '[%(levelname)-8s] %(message)s'

#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'  # 默认值 :  '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'      ;  日志文件信息格式

1
log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'

#log_granular_levels: {}   # 默认值 : {}  ;  更加高级的指定日志输出

1
2
3
   log_granular_levels:
     'salt''warning',
     'salt.modules''debug'

######      Module configuration      #####

#test: True          # 默认值 : True     ; 指定允许所有的模块运行测试模式

1
test: True

#test.foo: foo     # 默认值  : foo   ; 给测试模块test.foo指定一个简单的值

1
test.foo: foo

#test.bar: [baz,quo]   # 默认值 : [baz,quo]  ;  列表的测试模块值

1
test.bar: [baz,quo]

#test.baz: {spam: sausage, cheese: bread}  # 默认值 : {spam: sausage, cheese: bread}  ; 测试模块指定字典格式的值

1
test.baz: {spam: sausage, cheese: bread}

 

本文出自 “大風” 博客,请务必保留此出处http://lansgg.blog.51cto.com/5675165/1543351

 

http://www.fanli7.net/a/bianchengyuyan/Python/20140212/426935.html

salt 认证过程

当初始化安装 minion 启动服务启动后

  1. minion端生成一个秘钥对,并产生一个ID值,minion服务会安装ID值命名的公钥发送给 master ,直到接受为止;
  2. master认证完毕后,会将minion 端发送来的,以ID值命名的公钥存放在 /etc/salt/pki/master/minions 目录中(无扩展名);
  3. master认证完毕后,会将自身的公钥发送给 minion,并存储为 /etc/salt/pki/minion/minion_master.pub.

minion_id 值的生成过程

minion 默认按照如下顺序,试图在找到一个不是localhost的值作为ID:

  1. Python函数socket.getfqdn() 获取的值;
  2. /etc/hostname 定义的值(仅限于非Windows系统);
  3. /etc/hosts (%WINDIR%\system32\drivers\etc\hosts on Windows hosts) 中定义的任何映射 127.0.0.0/8 的主机名做ID值

如果以上都能够产生一个ID, 并且不是localhost,then a sorted list of IP addresses on the minion (excluding any within 127.0.0.0/8) is inspected. The first publicly-routable IP address is used, if there is one.Otherwise, the first privately-routable IP address is used.如果一切都失败了,那么则使用localhost作为备用,最终获取的ID将记录在/etc/salt/minion_id文件中,该文件可以手动更改,重启服务后不会被重新覆盖。

注意:如果minion端主配置文件 /etc/salt/minion 中启用了 id: xxxx , 那么这个ID值将覆盖 /etc/salt/minion_id 中记录的ID数值.

参考

  • master 秘钥对默认存储在

    /etc/salt/pki/master/master.pub 
    /etc/salt/pki/master/master.pem
  • master 端认证的公钥存储在:

    /etc/salt/pki/master/minions/
  • minion 秘钥对默认存储在

    /etc/salt/pki/minion/minion.pub 
    /etc/salt/pki/minion/minion.pem
  • minion 存放的master公钥

    /etc/salt/pki/minion/minion_master.pub
  • minion_id 默认存储在

    /etc/salt/minion_id

http://www.oschina.net/translate/getting-started-salt-stack-other-configuration-management-system-built-python

不久前的一天,当我自豪穿着Salt Stack 文化衫的时候,我的女儿看到后就当面问我,“Salt Stack 是什么呀?” 于是,我开始了作出了如下的解释,假如你有很多台服务器而且想要操作这些服务器,你也许需要一台一台的登录这些服务器,每次作出一次操作变更。这些操作可能是相当简单的,比如重启他们或者检查他们已经运行了多久,更或者,你想要做些更复杂的事情,比如安装软件和按照你的特殊需求来配置他们,也许你只是想要增加用户并且配置他们的权限。

假如你有百十来台服务器,你应该怎么做?想象一下你每次一台一台的登陆这些服务器,执行同样的命令在这些100台的服务器中并且编辑同一个配置文件,你可以想象吗?这是多么的苦逼!仅仅更新一下用户的密码策划就要用掉数天的时间,并且你可能出现错误的操作,怎么样通过一个命令一次完成所有服务器的操作?怎么解决?答案就是,Salt Stack!

 

葱油拌面
葱油拌面
翻译于 2年前

2人顶

 

 翻译的不错哦!

和我女儿一样,你也许还没有听说过Salt Stack(http://saltstack.org),但是你可能比较熟悉Puppet((http://puppetlabs.com))和Chef(http://opscode.com).Salt 跟他们差不多,但是Salt 是用Python写的,且对于设备的要求是相当轻量级的,使用起来相当容易(在我看来),Salt 通讯层使用0MQ(http://www.zeromq.org),这是使得它很快速。并且它是完全开源的,遵守Apche2 (http://www.apache.org/licenses/LICENSE-2.0)开源协议.拥有一个活跃和高效的开源社区。

目前,他们没有任何计划来发布一个残缺的社区版本或一个功能丰富的商业版本,对于Salt,你当前获得的这个版本是任何人都可以获得的,不论你是否付过钱。当然他们有发行商业版本的计划,不过它将是紧密的社区版本,且通过更多的测试和质量保证,以及相关的培训。

Salt和Puppet Chef 一样可以让你同时在多台服务器上执行命令也包括安装和配置软件。Salt 有两个主要的功能:配置管理和远程执行。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

Salt Stack 是一个命令行工具,这里没有任何地方需要你点击你的鼠标,执行的结果也会像字符界面一样反馈到你的屏幕上。这很好吧,它使得事情变得简单,并且很多服务器不需要一个图形界面。(注解:我使用Salt 条款在本文中,他们指的是同一个东西在上下文中)

在本文,Salt 包含两个工具,第一个是远程执行,虽然没有一个清晰的描述,但是假如你想要一个配置管理和远程执行的工具,在Salt中你可以找到很多方法。这可以让你登陆一台主服务器然后同时执行命令在一台或者多台服务器上。使用Salt,你仅仅需要在主服务器上输入命令,它会在每台机器上甚至一个服务器群组执行。

第二,Salt 能够存储配置指令,然后引导其他机器按照这些指令作出动作,如,安装软件,更改软件的配置,反馈这个任务成功执行与否。

接下来,我来演示使用Salt 安装一个额外的包,并且仅仅通过一个命令配置这个包。

 

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

安装 Salt

Salt 是不断变更的,也许当你读到本文时,有些事情已经改变,你可以在这里找到最新的文档:

http://docs.saltstack.org/en/latest/index.html

在安装Salt之前,你需要一些简单的准备工作:

1,一台Linux 服务器

2,sudo 或者root密码

3,这台服务器能够连接因特网

4,知道你的服务器的IP地址(可以是公网或私网IP)。

虽然Salt被设计为能够连接多台服务器,但在本文中,你可以在一台服务器上完成这些操作。

使用你的包管理器来安装Salt,你可以根据你系统版本分支找到相关的安装手册(http://docs.saltstack.org/en/latest/topics/installation/index.html),你也需要sudo或者root权限,来安装和使用salt

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

使用包管理的好处或者从在线的源代码安装是一个无法结束的争论,根据你的系统版本分支,选择更好的安装方法。

假如你倾向于使用源代码来安装,你可以在Salt 项目Github版本库里找到最新的Salt源码文件(https://github.com/saltstack/salt).

安装完成Salt-master和salt-minion后,希望一切运行正常且你没有收到错误信息。假如Salt并没有正常运行,你可以在到Salt Stack的邮件列表(http://saltstack.org/learn/#tab-mailinglist)和Salt IRC频道寻求帮助。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

配置主服务器和从服务器

主服务器和从服务器指的是控制器和被控制的服务器,这个主服务器本质上是中央协调中心对所有的从服务器,从服务器类似client/server配置,这里的主服务器是server,从服务器是client.

从服务器配置

在本文中,我配置salt-master和salt-minion 命令在同一台机器上,假如你在配置多台服务器,挑选其中一个为master,剩下的成为minions.根据你的需要来配置master和minion,接下来的我会解释如何配置一台服务器为master和另外的机器为minions.

Salt的配置文件在/etc/salt目录下,默认,这些文件被命名为minion和master,假如你在同一台机器安装了salt-master和salt-minion,你会看到不同的两个文件,master和minion

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

首先,你需要告诉你的minion怎样找到并连接你的Master服务器。即使你运行minion和Master在同一台服务器上,你仍然要告诉minion你的master在哪儿。

1,使用你最喜欢的文本编辑器,打开minion配置文件

2,取消注释行#master,移除# 替换为你的Master服务器的IP地址,应该是这样:master:你的master IP地址。(假如以上操作,在同一台服务器,此时增加 127.0.0.1)

3,命名一个昵称给你的服务器,查找到#id行,再一次移除#号,增加一个nameid:1st-salt-minion,(这个名字可以是任何字符串的)

4,为了重新加载新的配置,你需要使用sudo 重启你的salt-minion进程,-d 选项,启动salt-minion为一个后台进程,这样子的话,你可以访问您的命令行发布更多的命令。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

认证 Minion Keys

现在你的minion 已经知道到master在哪里,接下来让他们进行彼此验证,Salt使用公共密钥加密来确保master和minions的安全通信。你需要通过在master端验证minion的证书来明确master和minion之间的是授信的。

认证minion的证书使用salt-key命令,Salt自动生成这些证书,你需要做的仅仅是认证你需要的证书。

1,输入salt-key -L 列出所以没有认证,认证过,拒绝认证的证书

2,你应该可以看到一个没有认证的证书1st-Salt-Minion(或者你自己选择的minion)

3,认证这个证书使用 sudo salt-key -a 1st-salt-minion

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

通信测试

现在你已经有了一台 salt-master和一台salt-minion,并且master和minion已经相互信任,你可以从master 使用一个test ping的命令来测试他们之间的连接。假如你的master能够连接到minion,将会返回一个"return".输入 salt '*' test.ping,它应该有如下输出:

>{1st-Salt-Minion: True}
注意,通配符 *代表所有minion,因为这里你只有一台服务器,算是一个简单的模拟测试(要比salt '1st-salt-Minion' test ping 快多了)

假如你收到“True”,证明你已经成功安装和配置完成salt stack。

如果没有的话,你也许需要重启你的master和minion 不带-d参数,这样子的话,你能够获取到更多输出信息,更多的参考资料,请查看Salt 官方文档http://docs.saltstack.org/en/latest/topics/configuration.html

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

Salt的语法结构,包括命令,目标和动作,举个例子,* 指任何主机(* 是一个通配符),test.ping 是动作。

你可以在已经链接和信任的主机上执行任何可用的命令,关键提示:这些需要执行的命令在目标主机上必须可用,例如,如下命令:

sudo salt '*' cmd.run "service apache2 restart"
这个命令只会在已经安装了apach2e web服务器的主机上执行,另外,你也可以使用这样的命令:
sudo salt '*' cmd.run "service httpd restart"
另外一个例子,也许你想要查询你的主机已经运行了多长时间,你可以这样子做:
sudo salt '*' cmd.run "uptime"
在举另外一个例子,假如你的Apache Bench(译者注:一个apche 开源压力测试工具)安装在master上而没有安装在minion上,下面的命令:
sudo salt '*' cmd.run "ab -n 10 -c 2 http://www.google.com:80/index.html"
如果你尝试在minion上执行,你将会失败,因为Apache Bench 没有安装在minion上。
葱油拌面
葱油拌面
翻译于 2年前

1人顶

 

 翻译的不错哦!

在这里一切皆有可能,你可以在一个终端中一次重启你所有的机器,升级系统软件或者是检查你的机器状态,而不是像以前一样登陆这些机器一遍一遍的执行这些命令。

你也可以根据你自己的需求,执行一些命令在特定的目标群组上。参考-G 参数,从官网文档中获取更多细节http://saltstack.org

从此以后你不需要再登陆minion,所有的配置和执行能够快速高效的远程执行。

既然你已经安装了Salt并且能够执行一些远程的命令,为什么停步于此那?第二部分,Salt的强大源自于配置管理工具。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

配置管理

假如你之前没有使用过其他的配置管理系统,下面是一个简单的例子,比如说你有一组配置和相关的包,需要安装在每个WEB服务器上。你保留这些配置指令在一个文本文件中,然后引导你的服务器以你需要的方式安装和配置他们,每次你创建一个新的服务器。你也可以使用配置管理来保持你所有的服务器更新,一旦他们被创造和变化的反馈到新的包装或配置

安装了lib pam-crack 包,你可以有添加额外的要求用户密码。之所以选择这个包,是因为它对所有连接到因特网的服务器是有用的。它允许你设置一个额外长度的密码,并且会要求你密码中包含特殊字符或者数字,你也可以比较容易的选择特殊的包。但是这些包和例子必须在你的系统中可用。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

配置指令的存储

一般来讲,Salt的配置管理指令和文件保存在/srv/salt目录下,这里存放着所有的配置文件,和一些你想要拷贝到从服务器的文件。Salt的特点之一是包含一个文件服务器。虽然Salt不会在你的主服务器创建系统文件,但是所有的配置管理发生在/srv/salt目录中。

默认,Salt使用PyAMl语法(http://pyyaml.org) 作为它的模板文件的格式,但是其他很多模板语言在Salt中是可以使用的。一定要按照正确的格式书写YAML,比如它使用到两个空格代替tab。如果YAML文件出现不可预知的错误,你可以使用一个在线的debug工具(http://yaml-online-parser.appspot.com)。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

其它翻译版本(1)

启动配置管理

在启动配置管理功能之前,你需要再一次编辑你的master配置文件,在/etc/salt下。打开master配置文件,找到file_roots行,缺省配置文件中,这一行在第156行。现在,取消注释即删除#号,配置如下:

file_roots:
  base:
    - /srv/salt
这样子就可以告诉Salt你的配置管理文件在哪里。根据你是如何安装Salt,有时你需要自己创建/srv/salt目录
葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

其它翻译版本(1)

创建一个Top文件/Roadmap

基础配置文件也叫做Top文件,在/srv/salt目录下。我们来创建这个文件。这个文件提供了其它文件的映射。可以用于作为其它服务器的基础配置文件。再次使用你最喜欢的编辑器,在/srv/salt目录创建一个top.sls文件。你可以把它作为指向不同目录的路线图。在top.sls中加入一下行:

base:
  '*'
    - servers

base语法告诉Salt这是基础配置文件,可以应用在所有机器上。通配符'*'的目标是所有机器。'- servers'指令可以是任意值,运行你识别哪些质量可以使用。再选择一些其它有用的配置。这个条目还指向一个特别的配置,用于安装libpam-cracklib。

Lax
Lax
翻译于 2年前

0人顶

 

 翻译的不错哦!

其它翻译版本(1)

创建一个特定服务器的配置文件

保存top.sls后,在/srv/salt目录下创建servers.sls文件。这个文件包含特定的配置,包括安装包的名称,也可指向另外的配置文件。在servers.sls中,加入如下行:

libpam-cracklib:
  pkg:
    - installed

第一行是包管理工具可识别的软件包名称。以Apache HTTP server为例,在基于apatitude的包管理中叫做apache2,而在基于yum的包管理中叫做httpd。确保针对包管理工具使用正确的名字。也可以使用Salt的grains进行包管理。查看参考文档以获得更多信息,以及在SLS文件使用grains的例子(http://salt.readthedocs.org/en/latest/topics/tutorials/states_pt3.html#using-grains-in-sls-modules).

第2和第3行告诉Salt如何处理这个包——本例是安装这个包。要删除一个包,你只需要修改'- installed'为'- removed'即可。记住,空格很重要!第二行'pkg:'前有两个空格,第三行'- installed'前有四个空格。如果遇到任何错误,请通过在线YAML解析器检查语法。

 

Lax
Lax
翻译于 2年前

0人顶

 

 翻译的不错哦!

特定包的配置文件

安装libpam-cracklib包,你仅仅需要写三行配置即可。到此时的话,默认包管理器会安装libpam-cracklib包。然后您将需要登录到计算机上安装和配置它为您的特定需求。即使安装失败,Salt也会提供一个好的方案来解决。

Salt作为一个安全文件服务器,并把文件拷贝到远程的从服务器上。在servers.sls增加如下行:

/etc/pam.d/common-password:
  file:
    - managed
    - source: salt://servers/common-password
    - require:
      - pkg: libpam-cracklib
注意第四行,它告诉Salt你的特殊文件的位置,这一行后面的行,即第5行,告诉Salt这个包的依赖包。

这行salt://映射到你的主服务器/srv/salt目录。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

保存了server.sls文件后,在/srv/salt 目录下创建servers目录。这里用来存储libpam-cracklib包的配置文件。

当你在安装软件和配置文件的时,有时候你想要在测试服务器上先行安装,然后以你的需要配置。你可以拷贝配置文件到/srv/salt目录,这样子,你可以在部署到生成环境之前测试他们。

现在你的配置测试通过,现在你可以把配置文件随着安装libpam-cracklib 分发到每天从机器上了。/srv/salt 目录应该如下:

/srv/salt
            top.sls
            servers.sls
          /servers
                  common-password
葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

这里我把libpam-cracklib的配置作为一个例子,所有的其他软件配置都和这样差不多。例如,你可以比较容易的通过修改httpd.conf 来实现虚拟主机和主机头的配置。

所有的sls文件准备好以后,最后一步是告诉Salt配置远程机器。state.highstate 是触发这些同步的命令。使用先前的语法格式,目标位所有机器,键入以下格式的命令:

sudo salt '*' state.highstate
片刻后,从服务会反馈像如下成功的信息:
>>
  State: - pkg
  Name:      libpam-cracklib
  Function:  installed
      Result:    True
      Comment:   Package libpam-cracklib installed
      Changes:   wamerican: {'new': '7.1-1', 'old': ''}
                 cracklib-runtime: {'new': '2.8.18-3build1', 'old': ''}
                 libcrack2: {'new': '2.8.18-3build1', 'old': ''}
                 libpam-cracklib: {'new': '1.1.3-7ubuntu2', 'old': ''}
                   
----------
  State: - file
  Name:      /etc/pam.d/common-password
  Function:  managed
      Result:    True
      Comment:   File /etc/pam.d/common-password updated
      Changes:   diff: --- 
+++ 
@@ -22,7 +22,7 @@
 # pam-auth-update(8) for details.
 
 # here are the per-package modules (the "Primary" block)
-password   requisite   pam_cracklib.so retry=3 minlen=8 difok=3
+password   requisite   pam_cracklib.so retry=3 minlen=14 difok=3 dcredit=1 ucredit=1 lcredit=1 ocredit=1
 password   [success=1 default=ignore]   pam_unix.so obscure use_authtok try_first_pass sha512
 # here's the fallback if no module succeeds
 password   requisite   pam_deny.so

如你所见,Salt成功安装了libpam-cracklib并且从主服务器下载了一个common-password到从服务器的/etc/libpam-cracklib 目录。

本例中只有一台从服务器,相对来说是一个简单的例子,但是想象一下,假如你使用Salt配置管理安装了LAMP web服务器,你省了多长时间呀。把这些配置放在文本文件中,使得你快速高效的创建同样的服务器。

葱油拌面
葱油拌面
翻译于 2年前

0人顶

 

 翻译的不错哦!

总结

现在你有能力一次在很多台机器上执行远程命令并且能够把配置文件存储在易维护的文本中。也可以安装特殊的软件包。

刚开始的时候,多花点心思。您可以根据自己的特定配置创建一个或多个服务器,并且下载不同的包到每台机器上。Salt 也可以不按顺序执行,有些命令会同时执行,假如其中一台执行失败,其他依然不受影响继续执行。

虽然在安装Salt比较费时,但是你以后会得到极大的好处,特别是可以让你创建特定的服务器和可重复使用的配置。

访问Salt项目得到更多的细节,多关注邮件列表和用户文档以及一些例子。你会发现社区会非常热心的帮助你处理问题。

葱油拌面
葱油拌面
翻译于 2年前

1人顶

 

 翻译的不错哦!

 

 

 ===============================

http://docs.saltstack.com/en/latest/topics/tutorials/multimaster.html

3.4.4. Multi Master Tutorial

As of Salt 0.16.0, the ability to connect minions to multiple masters has been made available. The multi-master system allows for redundancy of Salt masters and facilitates multiple points of communication out to minions. When using a multi-master setup, all masters are running hot, and any active master can be used to send commands out to the minions.

Note

If you need failover capabilities with multiple masters, there is also a MultiMaster-PKI setup available, that uses a different topology MultiMaster-PKI with Failover Tutorial

In 0.16.0, the masters do not share any information, keys need to be accepted on both masters, and shared files need to be shared manually or use tools like the git fileserver backend to ensure that the file_roots are kept consistent.

3.4.4.1. SUMMARY OF STEPS

  1. Create a redundant master server
  2. Copy primary master key to redundant master
  3. Start redundant master
  4. Configure minions to connect to redundant master
  5. Restart minions
  6. Accept keys on redundant master

3.4.4.2. PREPPING A REDUNDANT MASTER

The first task is to prepare the redundant master. If the redundant master is already running, stop it. There is only one requirement when preparing a redundant master, which is that masters share the same private key. When the first master was created, the master's identifying key pair was generated and placed in the master's pki_dir. The default location of the master's key pair is/etc/salt/pki/master/. Take the private key, master.pem and copy it to the same location on the redundant master. Do the same for the master's public key, master.pub. Assuming that no minions have yet been connected to the new redundant master, it is safe to delete any existing key in this location and replace it.

Note

There is no logical limit to the number of redundant masters that can be used.

Once the new key is in place, the redundant master can be safely started.

3.4.4.3. CONFIGURE MINIONS

Since minions need to be master-aware, the new master needs to be added to the minion configurations. Simply update the minion configurations to list all connected masters:

master:
  - saltmaster1.example.com
  - saltmaster2.example.com

Now the minion can be safely restarted.

Now the minions will check into the original master and also check into the new redundant master. Both masters are first-class and have rights to the minions.

Note

Minions can automatically detect failed masters and attempt to reconnect to reconnect to them quickly. To enable this functionality, set master_alive_interval in the minion config and specify a number of seconds to poll the masters for connection status.

If this option is not set, minions will still reconnect to failed masters but the first command sent after a master comes back up may be lost while the minion authenticates.

3.4.4.4. SHARING FILES BETWEEN MASTERS

Salt does not automatically share files between multiple masters. A number of files should be shared or sharing of these files should be strongly considered.

3.4.4.4.1. Minion Keys

Minion keys can be accepted the normal way using salt-key on both masters. Keys accepted, deleted, or rejected on one master will NOT be automatically managed on redundant masters; this needs to be taken care of by running salt-key on both masters or sharing the/etc/salt/pki/master/{minions,minions_pre,minions_rejected} directories between masters.

Note

While sharing the /etc/salt/pki/master directory will work, it is strongly discouraged, since allowing access to the master.pem key outside of Salt creates a SERIOUS security risk.

3.4.4.4.2. File_Roots

The file_roots contents should be kept consistent between masters. Otherwise state runs will not always be consistent on minions since instructions managed by one master will not agree with other masters.

The recommended way to sync these is to use a fileserver backend like gitfs or to keep these files on shared storage.

3.4.4.4.3. Pillar_Roots

Pillar roots should be given the same considerations as file_roots.

3.4.4.4.4. Master Configurations

While reasons may exist to maintain separate master configurations, it is wise to remember that each master maintains independent control over minions. Therefore, access controls should be in sync between masters unless a valid reason otherwise exists to keep them inconsistent.

These access control options include but are not limited to:

  • external_auth
  • client_acl
  • peer
  • peer_run

http://docs.saltstack.com/en/latest/topics/tutorials/multimaster_pki.html

3.4.5. Multi-Master-PKI Tutorial With Failover

This tutorial will explain, how to run a salt-environment where a single minion can have multiple masters and fail-over between them if its current master fails.

The individual steps are

  • setup the master(s) to sign its auth-replies

  • setup minion(s) to verify master-public-keys

  • enable multiple masters on minion(s)

  • enable master-check on minion(s)

    Please note, that it is advised to have good knowledge of the salt- authentication and communication-process to understand this tutorial. All of the settings described here, go on top of the default authentication/communication process.

3.4.5.1. MOTIVATION

The default behaviour of a salt-minion is to connect to a master and accept the masters public key. With each publication, the master sends his public-key for the minion to check and if this public-key ever changes, the minion complains and exits. Practically this means, that there can only be a single master at any given time.

Would it not be much nicer, if the minion could have any number of masters (1:n) and jump to the next master if its current master died because of a network or hardware failure?

Note

There is also a MultiMaster-Tutorial with a different approach and topology than this one, that might also suite your needs or might even be better suited Multi-Master Tutorial

It is also desirable, to add some sort of authenticity-check to the very first public key a minion receives from a master. Currently a minions takes the first masters public key for granted.

3.4.5.2. THE GOAL

Setup the master to sign the public key it sends to the minions and enable the minions to verify this signature for authenticity.

3.4.5.3. PREPPING THE MASTER TO SIGN ITS PUBLIC KEY

For signing to work, both master and minion must have the signing and/or verification settings enabled. If the master signs the public key but the minion does not verify it, the minion will complain and exit. The same happens, when the master does not sign but the minion tries to verify.

The easiest way to have the master sign its public key is to set

master_sign_pubkey: True

After restarting the salt-master service, the master will automatically generate a new key-pair

master_sign.pem
master_sign.pub

A custom name can be set for the signing key-pair by setting

master_key_sign_name: <name_without_suffix>

The master will then generate that key-pair upon restart and use it for creating the public keys signature attached to the auth-reply.

The computation is done for every auth-request of a minion. If many minions auth very often, it is advised to use conf_master:master_pubkey_signature and conf_master:master_use_pubkey_signaturesettings described below.

If multiple masters are in use and should sign their auth-replies, the signing key-pair master_sign.* has to be copied to each master. Otherwise a minion will fail to verify the masters public when connecting to a different master than it did initially. That is because the public keys signature was created with a different signing key-pair.

3.4.5.4. PREPPING THE MINION TO VERIFY RECEIVED PUBLIC KEYS

The minion must have the public key (and only that one!) available to be able to verify a signature it receives. That public key (defaults to master_sign.pub) must be copied from the master to the minions pki-directory.

/etc/salt/pki/minion/master_sign.pub

DO NOT COPY THE master_sign.pem FILE. IT MUST STAY ON THE MASTER AND
ONLY THERE!

When that is done, enable the signature checking in the minions configuration

verify_master_pubkey_sign: True

and restart the minion. For the first try, the minion should be run in manual debug mode.

$ salt-minion -l debug

Upon connecting to the master, the following lines should appear on the output:

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO    ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG   ] Decrypting the current master AES key

If the signature verification fails, something went wrong and it will look like this

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Failed to verify signature of public key
[CRITICAL] The Salt Master server's public key did not authenticate!

In a case like this, it should be checked, that the verification pubkey (master_sign.pub) on the minion is the same as the one on the master.

Once the verification is successful, the minion can be started in daemon mode again.

For the paranoid among us, its also possible to verify the public whenever it is received from the master. That is, for every single auth-attempt which can be quite frequent. For example just the start of the minion will force the signature to be checked 6 times for various things like auth, mine, highstate, etc.

If that is desired, enable the setting

always_verify_signature: True

3.4.5.5. MULTIPLE MASTERS FOR A MINION

Configuring multiple masters on a minion is done by specifying two settings:

  • a list of masters addresses
  • what type of master is defined
master:
    - 172.16.0.10
    - 172.16.0.11
    - 172.16.0.12
master_type: failover

This tells the minion that all the master above are available for it to connect to. When started with this configuration, it will try the master in the order they are defined. To randomize that order, set

master_shuffle: True

The master-list will then be shuffled before the first connection attempt.

The first master that accepts the minion, is used by the minion. If the master does not yet know the minion, that counts as accepted and the minion stays on that master.

For the minion to be able to detect if its still connected to its current master enable the check for it

master_alive_interval: <seconds>

If the loss of the connection is detected, the minion will temporarily remove the failed master from the list and try one of the other masters defined (again shuffled if that is enabled).

3.4.5.6. TESTING THE SETUP

At least two running masters are needed to test the failover setup.

Both masters should be running and the minion should be running on the command line in debug mode

$ salt-minion -l debug

The minion will connect to the first master from its master list

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO    ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG   ] Decrypting the current master AES key

A test.ping on the master the minion is currently connected to should be run to test connectivity.

If successful, that master should be turned off. A firewall-rule denying the minions packets will also do the trick.

Depending on the configured conf_minion:master_alive_interval, the minion will notice the loss of the connection and log it to its logfile.

[INFO    ] Connection to master 172.16.0.10 lost
[INFO    ] Trying to tune in to next master from master-list

The minion will then remove the current master from the list and try connecting to the next master

[INFO    ] Removing possibly failed master 172.16.0.10 from list of masters
[WARNING ] Master ip address changed from 172.16.0.10 to 172.16.0.11
[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.11

If everything is configured correctly, the new masters public key will be verified successfully

[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub

the authentication with the new master is successful

[INFO    ] Received signed and verified master pubkey from master 172.16.0.11
[DEBUG   ] Decrypting the current master AES key
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[INFO    ] Authentication with master successful!

and the minion can be pinged again from its new master.

3.4.5.7. PERFORMANCE TUNING

With the setup described above, the master computes a signature for every auth-request of a minion. With many minions and many auth-requests, that can chew up quite a bit of CPU-Power.

To avoid that, the master can use a pre-created signature of its public-key. The signature is saved as a base64 encoded string which the master reads once when starting and attaches only that string to auth-replies.

DO ME HERE Enabling this also gives paranoid users the possibility, to have the signing key-pair on a different system than the actual salt-master and create the public keys signature there. Probably on a system with more restrictive firewall rules, without internet access, less users, etc.

That signature can be created with

$ salt-key --gen-signature

This will create a default signature file in the master pki-directory

/etc/salt/pki/master/master_pubkey_signature

It is a simple text-file with the binary-signature converted to base64.

If no signing-pair is present yet, this will auto-create the signing pair and the signature file in one call

$ salt-key --gen-signature --auto-create

Telling the master to use the pre-created signature is done with

master_use_pubkey_signature: True

That requires the file 'master_pubkey_signature' to be present in the masters pki-directory with the correct signature.

If the signature file is named differently, its name can be set with

master_pubkey_signature: <filename>

With many masters and many public-keys (default and signing), it is advised to use the salt-masters hostname for the signature-files name. Signatures can be easily confused because they do not provide any information about the key the signature was created from.

Verifying that everything works is done the same way as above.

3.4.5.8. HOW THE SIGNING AND VERIFICATION WORKS

The default key-pair of the salt-master is

/etc/salt/pki/master/master.pem
/etc/salt/pki/master/master.pub

To be able to create a signature of a message (in this case a public-key), another key-pair has to be added to the setup. Its default name is:

master_sign.pem
master_sign.pub

The combination of the master.* and master_sign.* key-pairs give the possibility of generating signatures. The signature of a given message is unique and can be verified, if the public-key of the signing-key-pair is available to the recipient (the minion).

The signature of the masters public-key in master.pub is computed with

master_sign.pem
master.pub
M2Crypto.EVP.sign_update()

This results in a binary signature which is converted to base64 and attached to the auth-reply send to the minion.

With the signing-pairs public-key available to the minion, the attached signature can be verified with

master_sign.pub
master.pub
M2Cryptos EVP.verify_update().

When running multiple masters, either the signing key-pair has to be present on all of them, or the master_pubkey_signature has to be pre-computed for each master individually (because they all have different public-keys).

DO NOT PUT THE SAME master.pub ON ALL MASTERS FOR EASE OF USE.

 

 

 

 https://github.com/saltstack/salt/issues/10732

http://pengyao.org/howto_configure_a_multi_master_saltstack_setup.html

【翻译】如何建立多Master的SaltStack环境

0.16.0版本的发布,带来了minion可以连接多Master的特性. 这种方式称为多master( multi-master )配置, 使环境中的SaltStack冗余。在这种配置下,Salt Minions将连接所有配置的Salt Master. 本文将带你了解如何建立多Master的环境.

Master Keys

在建立多Master的配置中,主要的一点就是所有的Master使用同样的private key. 这些key将在Master第一次启动时自动生成。 因此在多Master环境建立时,需要从原始的(original) Master上拷贝其private key至第二个Master以提供它启动时自动生成的那个, 以此类推.

Master的private key存储在Master本地的 pki_dir 目录下. 默认的目录是/etc/salt/pki/master/master.pem . 将该key拷贝到新增的master上. 需要注意的是,在拷贝的时候,需要确保新增的master上并没有minion连接进来.

Configure Minions

当配置多Master时,Minion需要知道需要连接的每个Master的网络地址. 需要在Minion的配置文件中进行配置,默认的配置文件是 /etc/salt/minion 。 找到master 配置项, 更新需要新增的Master.

下边是一个多Master的配置例子:

master:
  - master1.example.tld
  - master2.example.tld

配置完毕后,需要重启Minion以确保配置生效. 此时所有的Master均可以控制你的minions.

Sharing Files Between Masters

Salt并不会自动在Master间共享文件. 本小节将带你了解Master间哪些文件需要同步以保持一致.

Minion Keys

Minion的keys需要每个Master都进行accept. 可以使用 salt-key 手动接接受minion的key, 也可以在Master间保持key目录的同步. 需要同步的目录有:

  • /etc/salt/pki/master/minions
  • /etc/salt/pki/master/minions_pre
  • /etc/salt/pki/master/minions_rejected

Note

直接共享 /etc/salt/master 目录是强烈反对的. 允许外部访问 master.pem key将带来严重的安全风险

file_roots

file_roots 的内容需要在Master间同步以保持一致. 这里存放Salt State配置管理文件. 推荐同步内容使用 gitfs backend,或者直接将 file_roots 存储在共享存储上.

pillar_roots

同理,对于 pillar_roots 也是如此,需要保持Pillar数据一致.

Master Configuration

最后你需要确保有关Master的配置选项在所有Master间是同步的. 除非你知道你不需要这么做,你需要保证以下的设置Master间是同步的:

  • external_auth
  • client_acl
  • peer
  • peer_run

Conslusion

多Master环境配置提供了控制Minions的冗余性,配置相当简单. 只需要保证key及State文件在你的多Master间是同步的,你就可以透明的在多Master上控制你的Minions

 

 

posted @ 2014-03-13 16:55  陳聽溪  阅读(3805)  评论(0编辑  收藏  举报