一、简介
what is Saltstack?
Saltstack是一个具备puppet与func功能为一身的集中化管理平台,saltstack基于python实现,功能十分强大,适合大规模批量管理服务器,并且它比 Puppet 更容易配置。saltstack具有三种基本功能包括远程命令执行,配置管理(服务,文件,cron,用户,组),云管理。同时,saltstack具有三种运行方式Local、master/minon 、salt ssh。其中master/minion是其最传统的运行方式采用c/s模式,需要在管理端安装Master,被管理节点上安装Minion;而Saltstack salt ssh 运行方式,可以实现无需安Agent,通过SSH进行管理。
Saltstack部署架构
master->minion:master和所有minion连接,minion接收来自master的指令,完成命令执行或配置。如图:
<a href="https://s1.51cto.com/oss/201711/22/28bd649378ba813ad2de8b202881e745.png-wh_500x0-wm_3-wmp_4-s_2322396488.png" target="_blank"></a>
master->syndic->minion:master通过syndic对minion进行管理,该架构可以进行多级扩展。如图:
<a href="https://s4.51cto.com/oss/201711/22/ccb8204d6409a4e5f3b696dc41e84c77.png-wh_500x0-wm_3-wmp_4-s_912416081.png" target="_blank"></a>
无master的minion:minion不受任何master控制,通过本地运行即可完成相关功能。
<a href="https://s2.51cto.com/oss/201711/22/8b3e2f87fb4d6536b3c292cd85f375cf.png-wh_500x0-wm_3-wmp_4-s_2666300786.png" target="_blank"></a>
Saltstack的两种主要设计理念是远程执行和配置管理。在远程执行系统中,salt用python通过函数调用来完成任务。salt中的配置管理系统可以称作state,也是基于远程执行系统之上,通过master的定规可以让对应的minion达到想要的系统状态。
salt远程执行底层原理:
Salt的底层通信是通过ZeroMQ完成的,采用了ZeroMQ的订阅发布模式(Pub和Sub)如下图所示:
简单来讲,Pub/Sub模式类似于广播电台,在订阅发布模式中Pub将消息发送到总线,所有的Sub收到来自总线的消息后,根据自己的条件来接收特定的消息。对应到salt中就是master将事件发布到消息总线,minion订阅并监听事件,然后minion会查看事件是否和自己匹配以确定是否需要执行,匹配条件就是多种主机匹配方法。saltmaster和minion的通信过程中,会启动监听两个端口,默认是4505和4506。
4506的作用:Salt Master Ret接口,支持认证(auth)、文件服务、结果收集等功能;
4505的作用:Salt Master Pub接口,提供远程执行命令发送功能。
Salt minion启动时从配置文件中获取master的地址,如果为域名,则进行解析。解析完成后,会连接master的4506(ret接口)进行key认证。认证通过,会获取到master的publish_port(默认是4505),然手连接publish_port订阅来自master pub接口任务。当master下发操作指令是,所有的minion都能接收到,然后minion会检查本机是否匹配。如果匹配,则执行。执行完毕后,把结果发送到master的4506(ret接口)由master进行处理,命令发送通信完成是异步的,并且命令包很小。此外,这些命令包通过maqpack进行序列化后数据会进一步压缩(Maqpack是一种高效的二进制序列化格式),所以salt的网络负载非常低。
二、Saltstack的安装
2.1 yum源安装
下载Centos6的epol源进行安装:
<code>wget -O </code><code>/etc/yum</code><code>.repos.d</code><code>/epel</code><code>.repo http:</code><code>//mirrors</code><code>.aliyun.com</code><code>/repo/epel-6</code><code>.repo</code>
如果使用Centos7,可以下载此epol源:
<code>wget -O </code><code>/etc/yum</code><code>.repos.d</code><code>/epel</code><code>.repo http:</code><code>//mirrors</code><code>.aliyun.com</code><code>/repo/epel-7</code><code>.repo</code>
安装master端:
<code>yum </code><code>install</code> <code>salt-master</code>
启动master端服务:
<code>/etc/init</code><code>.d</code><code>/salt-master</code> <code>start</code>
<a href="https://s4.51cto.com/oss/201711/22/43fd178ff2fc4e0b809cdd1474b4065c.png-wh_500x0-wm_3-wmp_4-s_3029019880.png" target="_blank"></a>
Agent安装minion端:
<code>Yum </code><code>install</code> <code>salt-minion</code>
2.2 Agent简单配置Saltstack
Agent指定master:
<code>vim </code><code>/etc/salt/mionion</code>
<code># resolved, then the minion will fail to start.</code>
<code>#master: salt</code>
<code>master: 192.168.39.135</code>
修改mionion的id号:
<code># clusters.</code>
<code>#id:</code>
<code>id</code><code>: Agent1</code>
注:id号用于唯一区分mionion的标示,可以不做指定,默认为主机名。
启动minon服务:
<a href="https://s1.51cto.com/oss/201711/22/873ac98c4110b922c7a67abac2091985.png-wh_500x0-wm_3-wmp_4-s_3149570931.png" target="_blank"></a>
2.3 master授权mionion密钥认证
master查看认证请求:
<code># salt-key</code>
<a href="https://s4.51cto.com/oss/201711/22/efbb1f99534bb6dfcb20628e9f4ae489.png-wh_500x0-wm_3-wmp_4-s_604481073.png" target="_blank"></a>
master授权请求:
<code># salt-key -a centos-test1</code>
可以批量授权请求:
<code>[root@centos salt]</code><code># salt-key -A</code>
再次查看请求,可以看到都以授权成功:
<a href="https://s3.51cto.com/oss/201711/22/5315774f7e5de67765b3f0c6ade9acd0.png-wh_500x0-wm_3-wmp_4-s_1935591706.png" target="_blank"></a>
进行测试,可以看到agent端信息:
<a href="https://s4.51cto.com/oss/201711/22/fc16e9796a89da270f46749de6382689.png-wh_500x0-wm_3-wmp_4-s_3969053185.png" target="_blank"></a>
三、Saltstack的数据系统
Saltstack有两个数据系统,分别是Grains和Pillar。本质上它们都是key value型的数据库。
3.1 Grains
Grains是存储在minion上的数据,minion启动后就进行Grains计算。Grains是一种静态数据,包括很多诸如操作系统、操作系统版本或CPU内核数量、内存大小等数据。这些数据不
经常变,即使有所变化重启Minion也会重新计算生成。Grains让salt变得更加灵活。
Grains功能:1)信息查询 ;包括资产管理 2)用于目标选择 3)配置管理中使用
3.1.1 信息查询(包括资产管理)
<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.ls #列出ID为"centos-test1"的主机,grains所有项</code>
<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.items #列出主机的详细信息,可用于资产管理</code>
<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.item host #查询centos-test1的主机名</code>
<code>[root@centos ~]</code><code># salt '*' grains.item fqdn_ip4 #查询左右主机的ip地址</code>
3.1.2 目标选择
<code>[root@centos ~]</code><code># salt -G os:CentOS test.ping #对所有主机系统为"centos"的主机进行Ping测试</code>
<code>[root@centos ~]</code><code># salt -G os:CentOS cmd.run 'w' #对所有主机系统为“centos”的主机查询负载状态</code>
3.1.3 配置管理中的使用
方法一:
通过修改minion的配置文件可以自定义Grains。
<code># vim /etc/salt/minion</code>
<code># cabinet: 13</code>
<code># cab_u: 14-15</code>
<code>grains:</code>
<code> </code><code>roles:</code>
<code> </code><code>- webserver</code>
<code> </code><code>- memcache</code>
重启minion服务:
<code># /etc/init.d/salt-minion restart</code>
通过自定义的item,可以实现对所有角色为memche命令执行"date"命令
<code>[root@centos ~]</code><code># salt '*' grains.item roles #查询所有主机的角色信息</code>
<code>[root@centos ~]</code><code># salt -G 'roles:memcache' cmd.run 'date' #对所有主机roles为memcache的主机,执行"date"命令</code>
方法二:
也可以通过修改/etc/salt/grains文件来实现。
<code># vim /etc/salt/grains</code>
<code>minion: host1</code>
<code>[root@centos ~]</code><code># salt -G 'minion:host1' cmd.run 'w'[object Object]</code>
修改/etc/salt/grains不重启服务的方法,刷新命令如下(备注:方式一和方式二修改配置文件,通过此命令都可以不用重启服务)
<code># salt '*' saltutil.sync_grains</code>
方法三:
Grains在top file中使用(Grains module方式)。
1)创建文件系统路径:
<code>[root@centos ~]</code><code># mkdir -p /srv/salt/</code>
2)修改master配置文件指定top file文件路径
<code>[root@centos ~]</code><code># vim /etc/salt/master</code>
<code># - /srv/salt/prod/services</code>
<code># - /srv/salt/prod/states</code>
<code>#</code>
<code>file_roots:</code>
<code> </code><code>base:</code>
<code> </code><code>- </code><code>/srv/salt</code>
3) 编辑top file文件
<code>[root@centos ~]</code><code># vim /srv/salt/top1.sls base:</code>
<code>base:</code>
<code> </code><code>'web:nginx'</code><code>:</code>
<code> </code><code>- match: grains </code><code>#指定grains进行匹配</code>
<code> </code><code>- apache </code><code>#执行apache.sls</code>
#所有值为nginx的主机,执行apache的状态
<code>[root@centos ~]</code><code># vim /srv/salt/apache.sls</code>
<code>apache-</code><code>install</code><code>:</code>
<code> </code><code>pkg.installed:</code>
<code> </code><code>- names:</code>
<code> </code><code>- httpd</code>
<code> </code><code>- httpd-devel</code>
<code>apache-service:</code>
<code> </code><code>service.running:</code>
<code> </code><code>- name: httpd</code>
<code> </code><code>- </code><code>enable</code><code>: True</code>
<code> </code><code>- reload: True</code>
<code>[root@centos ~]</code><code># salt '*' state.highstate #执行[object Object]</code>
案例:
<code>/srv/salt/webserver</code><code>.sls</code>
<code>apache: </code><code># 标签定义</code>
<code> </code><code>pkg: </code><code># state declaration</code>
<code> </code><code>- installed </code><code># function declaration</code>
<code>第一行被称为(ID declaration) 标签定义,在这里被定义为安装包的名。注意:在不同发行版软件包命名不同,比如 fedora 中叫httpd的包 Debian</code><code>/Ubuntu</code><code>中叫apache2</code>
<code>第二行被称为(state declaration)状态定义, 在这里定义使用(pkg state module)</code>
<code>第三行被称为(</code><code>function</code> <code>declaration)函数定义, 在这里定义使用(pkg state module)调用 installed 函数</code>
3.2 Pillar
Grains很强大,但是其缺点是这些数据相对来说都是静态数据。如果有变化的数据如何处理呢?这时我们就用到了pillar。pillar数据存储在master上。指定的minion只能看到自己pillar数据,其他的minion看不到任何pillar数据,这一点与状态文件正好相反。所有通过认证的minion都可以获取状态文件,但是每隔minion却都有自己的一套pillar数据,而且每台minion的pillar都进行了加密,所以很适用于敏感数据。
3.2.1 开启pillar
现在saltstack已经默认关闭pillar,因此pillar功能需要开启。
<code># the pillar called "master". This is used to set simple configurations in the</code>
<code># master config file that can then be used on minions.</code>
<code>pillar_opts: True</code>
<code>[root@centos ~]</code><code># service salt-master restart</code>
列出minion所有pillar的详细信息。
<code>[root@centos ~]</code><code># salt 'centos-test1' pillar.items</code>
3.2.2 定义pillar目录
<code># - /srv/pillar</code>
<code>pillar_roots:</code>
<code> </code><code>- </code><code>/srv/pillar</code>
<code>[root@centos ~]</code><code># mkdir -p /srv/pillar</code>
1) 创建一个pillar文件(python jinjia2写法)
<code>[root@centos ~]</code><code># vim /srv/pillar/apache.sls</code>
<code>{%</code><code>if</code> <code>grains [</code><code>'os'</code><code>] == </code><code>'CentOS'</code> <code>%}</code>
<code>apache: httpd</code>
<code>{% </code><code>elif</code> <code>grains[</code><code>'os'</code> <code>== </code><code>'Debian'</code><code>] %}</code>
<code>apache: apache2</code>
<code>{% endif %}</code>
2)创建top file文件
<code>[root@centos ~]</code><code># vim /srv/pillar/top.sls</code>
<code> </code><code>'*'</code><code>:</code>
<code> </code><code>- apache</code>
#让所有主机(*),读取apachepillar
<code>[root@centos ~]</code><code># salt '*' saltutil.refresh_pillar #执行刷新pillar</code>
<code>[root@centos ~]</code><code># salt '*' pillar.items</code>
使用pillar定位主机:
<code>[root@centos ~]</code><code># salt -I 'apache:httpd' test.ping</code>
3.3 Grains和Pillar的不同
四、Saltstack远程执行
4.1 远程执行
在远程主机上运行预定义的或任意的命令,亦称为远程执行,是salt的核心功能。了解模块和返回值,是远程执行两个关键要素。
Salt命令由三个主要部分构成:
<code>salt </code><code>'<target>'</code> <code><</code><code>function</code><code>> [arguments]</code>
target部分允许你指定哪些minion应该运行执行. 默认的规则是使用glob匹配minion id. 例如:
<code>salt </code><code>'*'</code> <code>test</code><code>.</code><code>ping</code>
<code>salt </code><code>'*.example.org'</code> <code>test</code><code>.</code><code>ping</code>
Targets可以使用Grains系统来通过minion的系统信息进行过滤:
<code>salt -G </code><code>'os:Ubuntu'</code> <code>test</code><code>.</code><code>ping</code>
参见
<a href="http://docs.saltstack.cn/topics/targeting/grains.html">Grains系统</a>
ip地址或子网掩码进行检测:
<code>salt -S </code><code>'192.168.39.200'</code> <code>test</code><code>.</code><code>ping</code>
Targets也可以使用正则表达式:
<code>salt -E </code><code>'virtmach[0-9]'</code> <code>test</code><code>.</code><code>ping</code>
Targets也可以指定列表:
<code>salt -L </code><code>'foo,bar,baz,quo'</code> <code>test</code><code>.</code><code>ping</code>
或者在一个命令中混合使用多target类型:
<code>salt -C </code><code>'G@os:Ubuntu an webser* or E@database.*'</code> <code>test</code><code>.</code><code>ping</code>
funcation是module提供的功能. Salt内置了大量有效的functions. 列出minions上的所有有效functions?
<code>salt </code><code>'*'</code> <code>sys.doc</code>
这里有一些例子:
显示当前所有有效的minions:
运行一个任意的shell命令:
<code>salt </code><code>'*'</code> <code>cmd.run </code><code>'uname -a'</code>
<a href="http://docs.saltstack.cn/ref/modules/all/index.html">所有模块列表</a>
function通过空格来界定参数:
<code>salt </code><code>'*'</code> <code>cmd.exec_code python </code><code>'import sys; sys.version'</code>
可选的, 也支持keyword参数:
<code>salt </code><code>'*'</code> <code>pip.</code><code>install</code> <code>salt timeout=5 upgrade=True</code>
他们常常在 <code>kwargs=argument</code> form中.
4.2 salt常用模块
下面指列举service模块使用方法:
<code>salt.modules.service.available(name)</code>
判断指定服务是否存在,如果存在返回True,否则返回False。
<code>[root@centos ~]</code><code># salt '*' service.available sshd</code>
<code>centos-test2:</code>
<code> </code><code>True</code>
<code>centos-test3:</code>
<code>centos-test1:</code>
<code>salt.modules.service.get_all()</code>
返回所有服务可用的列表。
<code>[root@centos ~]</code><code># salt '*' service.get_all</code>
<code> </code><code>- abrt-ccpp</code>
<code> </code><code>- abrt-oops</code>
<code> </code><code>- abrtd</code>
<code> </code><code>- acpid</code>
<code> </code><code>- atd</code>
<code> </code><code>- auditd</code>
<code> </code><code>- blk-availability</code>
<code> </code><code>- control-alt-delete</code>
<code> </code><code>- cpuspeed</code>
<code> </code><code>- crond</code>
<code> </code><code>- haldaemon</code>
<code>salt.modules.service.run(name, action)</code>
用动作运行指定的服务。
name --服务名 action --动作名称,如start,stop,reload,restart。
<code># salt '*' service.run apache2 reload</code>
<code># salt '*' service.run postgresql initdb</code>
<code>salt.modules.service.start(name)</code>
启动指定服务。
<code>[root@centos ~]</code><code># salt '*' service.start httpd</code>
<code>salt.modules.service.status(name)</code>
查询指定服务状态。服务启动返回True,服务未启动返回False。
<code>[root@centos ~]</code><code># salt '*' service.status httpd</code>
4.3 模块的ACL(访问控制)
4.3.1 对系统用户允许特定命令执行
1)修改相应目录权限
<code>[root@centos ~]</code><code># chmod 755 /var/cache/salt /var/cache/salt/master /var/cache/salt/master/jobs /var/run/salt /var/run/salt/master/</code>
2)修改master配置文件,开启acl访问控制
<code>client_acl:</code>
<code> </code><code>jerry: </code><code>#用户jerry</code>
<code> </code><code>- </code><code>test</code><code>.</code><code>ping</code> <code>#只允许使用test.ping和network下所有方法</code>
<code> </code><code>- network.*</code>
3)重启服务
<code>[root@centos ~]</code><code># /etc/init.d/salt-master restart</code>
测试:
4.3.2 指定用户在某一台机器上执行特定命令
1)修改配置
<code> </code><code>jerry:</code>
<code> </code><code>- </code><code>test</code><code>.</code><code>ping</code>
<code> </code><code>tom: </code><code>#用户</code>
<code> </code><code>- centos-test1*: </code><code>#主机centos-test1</code>
<code> </code><code>- </code><code>test</code><code>.</code><code>ping</code> <code>#test.ping命令</code>
2)重启服务
测试:
五、Saltstack配置管理
Saltstack包含一个健壮且灵活的配置管理框架,该框架建立在远程执行核心上。这个框架执行的minion端,允许轻松,同时可配置成千上万的主机,通过编写特定于语言的状态文件得以实现。saltstack的配置管理提供了很多的“状态模块”用于实现不同配置管理的需求。以下是配置管理的链接以方便查询:https://docs.saltstack.com/en/latest/topics/states/index.html
1)修改file_root文件目录
<code>[root@centos base]</code><code># vim /etc/salt/master </code>
<code> </code><code>- </code><code>/srv/salt/base</code>
<code> </code><code>test</code><code>:</code>
<code> </code><code>- </code><code>/srv/salt/test</code>
<code> </code><code>prod:</code>
<code> </code><code>- </code><code>/srv/salt/prod</code>
2) 创建文件目录
<code>[root@centos base]</code><code># mkdir -p /srv/salt/base</code>
<code>[root@centos base]</code><code># mkdir -p /srv/salt/test</code>
<code>[root@centos base]</code><code># mkdir -p /srv/salt/prod</code>
<code>[root@centos base]</code><code># /etc/init.d/salt-master restart</code>
批量修改/etc/resolv.conf文件:
<code>[root@centos ~]</code><code># cd /srv/salt/base</code>
<code>[root@centos base]</code><code># vim dns.sls</code>
<code>/etc/resolv</code><code>.conf: </code><code>#标签</code>
<code> </code><code>file</code><code>.managed: </code><code>#状态模块file的mamaged方法,用以实现</code>
<code> </code><code>- </code><code>source</code><code>: salt:</code><code>//files/resolv</code><code>.conf </code><code>#源文件resolv.conf</code>
<code> </code><code>- user: root </code><code>#文件用户属主</code>
<code> </code><code>- group: root </code><code>#文件数组</code>
<code> </code><code>- mode: 644 </code><code>#文件权限</code>
文件目录状态为:
resolv.conf文件内容:
<code>[root@centos base]</code><code># more files/resolv.conf </code>
<code># Generated by NetworkManager</code>
<code>nameserver 192.168.39.2</code>
<code>[root@centos base]</code><code># salt '*' state.sls dns #执行dns状态文件</code>
也可以从top文件上执行。
<code>[root@centos base]</code><code># vim top.sls </code>
<code> </code><code>- dns</code>
<code>[root@centos base]</code><code># salt '*' state.highstate #state高级状态默认从top文件中执行</code>
查看minion端的resolv.conf文件:
5.2 saltstack配置管理之YAML和jinjia
5.2.1 什么是YAML?
YAML语法规则:
规则一:缩紧
1)yaml使用一个固定的缩紧风格表示水层结构关系。salt需要每个缩紧分别由两个空格组成。
2)不要使用tabs。
规则二:冒号
YAML my_key: my_value
first_level dict_key:
second_level dict_key: value_in_second_level_dict
IN Pyton {‘my_key’: ‘my_value’,
{
‘first_level_dict_key’:{
‘second_level_dict_key’: ‘value_in_second_level_dict’
}
规则三:短横线
想要表示列表项:使用一个短横杠加一个空格。多个项使用同样的缩紧级别作为同一列表的一部分。
my_dictionary:
- list_value_one
- list_value_two
- list_value_three
{‘my_dictionary’: [‘list_value_one’,’list_value_two’,’list_value_three’]}
5.2.2 什么是jinja?
1.file状态使用template参数
2.模版文件里面变量使用{{ 名称 }} {{ PORT }}
3.变量列表
-defaults:
PORT:8080
4.Jinjia if-else 语句
{% if grains[‘fqdn’] == ‘lb-node1.unixhot.com’ %}
— ROUTEID: haproxy_master
- STATEID: master
{% elif grains[‘fedn’] == ‘lb-node2.unixhot.com’ %}
- ROUTEID: haproxy_backup
- STATEID: backup
- PRIORITYID: 100
{% endif %}
5.2.2 变量的使用
以上一个示例需改resolv.conf为例
<code>[root@centos ~]</code><code># vim /srv/salt/base/dns.sls </code>
<code>/etc/resolv</code><code>.conf:</code>
<code> </code><code>file</code><code>.managed:</code>
<code> </code><code>- </code><code>source</code><code>: salt:</code><code>//files/resolv</code><code>.conf</code>
<code> </code><code>- user: root</code>
<code> </code><code>- group: root</code>
<code> </code><code>- mode: 644</code>
<code> </code><code>- template: jinja </code><code>#template指定为jinja模版</code>
<code> </code><code>- defaults:</code>
<code> </code><code>DNS_SERVER: 192.168.39.23 </code><code>#变量:默认值</code>
<code>[root@centos ~]</code><code># vim /srv/salt/base/files/resolv.conf </code>
<code>nameserver {{ DNS_SERVER }} </code><code>#{{ DNS_SERVER }} 作为变量,也可以使用单括号,这里使用便于区分</code>
<code>[root@centos base]</code><code># salt '*' state.highstate #执行进行修改minions端配置</code>
可以看到已经修改完成。
参考资料:
<a href="https://docs.saltstack.com/en/latest/">https://docs.saltstack.com/en/latest/</a>
<a href="http://outofmemory.cn/saltstack/salt">http://outofmemory.cn/saltstack/salt</a>
本文转自 SoulMio 51CTO博客,原文链接:http://blog.51cto.com/bovin/1984115,如需转载请自行联系原作者