saltstack知识点

file server configuration

  salt有一个用ZeroMQ编写的高性能文件服务,它可以用很小的负载快速管理大量的文件。salt的文件服务是一个感知环境(environment aware)的文件服务,什么是环境感知?就是文件可以被分配在多个根目录下,可以在访问时指定文件路径和搜索路径。独特的环境可以跨越多个根目录覆盖,并以灵活的方式来组织文件。
  salt默认的文件服务强制使用base环境,这个base环境必须被定义,当没有写明环境定义的时候,就是从这个base环境下载文件的,环境允许文件和sls数据在逻辑上分离,但彼此都不是孤立的环境。
  环境设置了一系列目录来发布文件,在这些目录中进行文件查找,并返回第一个找到的文件。这意味着文件查找是按照设定的目录顺序进行查找的。eg:

1
2
3
4
file_roots:
  base:
    - /srv/salt/base
    - /srv/salt/failover
 

  假如在查找salt://httpd/httpd.conf文件时,第一个搜索的目录是/srv/salt/base/httpd/httpd.conf。如果在这里找到了这个文件,则返回该文件,如果没有该文件,则继续查找/srv/salt/failover/httpd/httpd.conf。 

salt file server

  salt使用文件服务分发文件到minions上,文件服务是一个内嵌在master里面的无状态ZeroMQ服务构成的。salt的文件服务目前用在salt的state system中,因此,文件服务可以用于任何文件传输。cp模块被用于salt的state system,salt-cp可以让salt的文件服务来分发文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cp.get_file可以用来在minion端下载master上的文件。
 
salt '*' cp.get_file salt://vimrc /etc/vimrc
  这个会通知所有的minion客户端来下载vimrc文件到/etc/vimrc
 
salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja 
  也可以用模版,表示只在OS系统名称一样的机器上下载文件
   
salt '*' cp.get_file salt://vimrc /etc/vimrc gzip=5
  salt在传输大文件时还支持压缩:压缩比率是1-9
 
salt '*' cp.get_file salt://vimrc /etc/vim/vimrc makedirs=True
  cp.get_file默认是不会创建目的端的目录的,如果该目录不存在的时候。要改变这种情况可以使用mkaedirs参数
 
salt '*' cp.get_dir salt://etc/apache2 /etc
salt '*' cp.get_dir salt://etc/{{pillar.webserver}} /etc gzip=5 template=jinja
  cp.get_dir和cp.get_file一样,不过get_dir是用来下载整个目录的,也支持模版和压缩
 

3 file server backends  

  salt在master上引进了一种能力,就是在整合不同的文件服务后端,文件服务后端允许salt的文件服务作为一个传输桥梁连接到外部资源。最好的例子就是git后端,它允许所有的salt文件保存在远程的git仓库中。

  文件服务后端系统可以承担不同的后端类型,这样就可以在file_roots中配置不同的后端类型。文件后端这个功能是被master中的fileserver_backend参数管理的,它列出在后端系统中搜索的优先级顺序。例如:

1
2
3
fileserver_backend:
  - roots
  - git
 

  根据以上的配置,file_roots配置中定义的先被搜索,如果在file_roots没有搜索到,则git后端才会被搜索。 

  内建的fileserver模块:http://docs.saltstack.com/ref/file_server/all/index.html

  其他两个没用过,主要使用fileserver.roots模块。

4 dynamic module distribution

  salt的python模块可以通过salt的文件服务自动的分发。在master通过任何一个file_roots定义的根目录下的模块都可以被使用。
  模块同步:自动的从master到minions传输加载、grains、renderers、returners、states模块信息等等。以下目录被优先考虑:

1
2
3
4
5
_modules
_grains
_renderers
_returners
_states
 

  在python模块被创建到这些目录后,这些目录下的内容需要被同步到minions上,有好几种办法同步模块: 
  1 通过states传输,在minion的配置文件中,有一个autoload_dynamic_modules选项,默认是True,当state运行的时候,它使用state system更新所有的动态模块,当动态模块通过states自动加载的时候,modules only pertinent to the environments matched in the master's top file are downloaded。这很重要,因为模块可以被手动的加载,在指定特定的环境特定的模块。 
   
  2 通过saltutil模块分发,saltutil模块有一些函数可以同步所有的或者指定的动态模块。saltutil.sync_all可以同步所有的模块到minion。

  关于saltutil查看:http://docs.saltstack.com/ref/modules/all/salt.modules.saltutil.html#module-salt.modules.saltutil

client acl system

  salt的client acl system意思是允许系统账户(非root)可以在master上访问、执行salt命令到minions。
  client acl system是在master上的client_acl参数配置的,在client_acl下可以设置用户可以使用的命令,也可以通过正则匹配设置一系列命令。例如:

1
2
3
4
5
6
client_acl:
  thatch:
    - .*
  fred:
    - ping.*
    - pkg.*
 

  允许thatch执行任何命令,允许fred使用ping和pkg命令。当然必须要让用户可读相关目录。 

  chmod 755 /var/cache/salt /var/cache/salt/jobs /var/run/salt 

state testing

  在执行salt state run的时候,可能潜在的改变系统,他可能是令人满意的,但也可能识不满意的。salt提供了一个test接口,报告哪些东西将被改变,这个接口可以被使用在任何state运行的func上面。

1
2
salt '*' state.highstate test=True
salt '*' state.sls test=True
 

7 the top file

  top file用来映射什么sls模块会通过state system被安装到minions。top file创建了一些通用的抽象。首先,它把节点映射到某个环境,接下来他定义匹配系统应答从哪个节点拉取。   

  First it maps what nodes should pull from which environments, next it defines which matches systems should draw from.

  top file的环境和设置的file_roots是一致的,在一个简单的,单一环境中,你只设置了base环境,因此你只有一个state tree,例子如下:

 

1
2
3
file_roots:
  base:
    - /srv/salt
 

  以上例子意味着,你的top file只有一个环境可以映射。例子如下:

1
2
3
4
base:
  '*':
    - core
    - edit
 

     这也意味着/srv/salt有一个state tree,如果你想使用多个环境,或者分隔file server到多个state tree,file_roots可以如下设置: 

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

  这时我们的top file可以如下引用多个环境: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dev:
  'webserver*dev*':
    - webserver
  'db*dev*':
    - db
qa:
  'webserver*qa*':
    - webserver
  'db*qa*':
    - db
prod:
  'webserver*prod*':
    - webserver
  'db*prod*':
    - db
 

  在上面的设置中,我们设置了三个state tree,并没有设置在base环境中的state tree。 

  Remember, that since everything is a file in Salt, the environments are primarily file server environments, this means that environments that have nothing to do with states can be defined and used to distribute other files.

  关于top file可以参考:http://docs.saltstack.com/ref/states/top.html

state modules

  State Modules are the components that map to actual enforcement and management of Salt states

  state模块很容易编写,传入到sls数据结构的信息会被直接映射到states modules。
怎样使用定制的states模块?把你编写的state模块,放到_states目录下,该目录的具体路径是由file_roots指定的,这些定制的模块可以通过多种方法分发,当state.highstate运行时、执行saltutil.sync_states时、执行salr
tutil.sync_all函数时都会分发定制的模块。注意:state模块的名称模式就是state模块python脚本的名称。模块必须返回字典类型的数据。

  内建模块:http://docs.saltstack.com/ref/states/all/index.html

salt runners

  salt runners是一个便利的应用,方便使用salt-run的命令。就像salt模块发送到minions执行一样。salt runners在master上执行。一个salt runner可以是一个简单的客户端调用也可以是一个复杂的应用。
  The use for a Salt runner is to build a frontend hook for running sets of commands via Salt or creating special formatted output.
  很容易编写salt runners,它工作起来就和salt模块一样,不同之处在于salt runners在master上运行。一个runner是一个python模块,每个python模块中的共有函数都是一个runner,他可以通过salt-run命令执行。
  如果一个python模块是test.py,存放在runners的目录下,test.py有一个函数是foo,则可以通过一下方法使用:
salt-run test.foo

  系统自带了一些runner模块
     http://docs.saltstack.com/ref/runners/all/index.html
     https://github.com/saltstack/salt/tree/develop/salt/runners

10 startup states

  有时候希望minion启动的时候就执行state,这个减轻了master发起在新的minion上执行state的压力,因为新的minion客户端启动后会自动执行state,就不需要master发起该操作了。在salt的minion配置文件中有一些参数可以定义该功能。
  startup_states 可以传递一个或者多个参数,定义执行哪些states,可用参数如下:
     highstate  执行state.highstate
     sls  读取sls_list选项,然后执行sls文件
     top  读取top_file选项,然后基于master上的top文件执行states
  sls_list
  top_file
  例子:

1
2
3
4
startup_states: sls
sls_list:
  - edit.vim
  - hyper
 

11 salt syndic

  一个master控制多个master,同时被控制的master又可以控制很多的minion
    1 首先在中心节点的master上启动order_masters
    2 在次级mastert上启动syndic_master,指定为中心master,启动salt-syndic

    比如总的master为master,syndic节点为syndic1,将minion1的master制定为syndic,启动minion服务,然后在syndic1节点就可以看到未接受的key,接受后,syndic就可以管理minion1了,同时master也可以管理minion1了。

    参考:http://docs.saltstack.com/ref/syndic.html

12 grains

   salt用一个接口收集系统的信息,这个接口称为grains,grains收集到的信息是在minion第一次启动的时候获取的信息,所以必须认识到grains收集到的信息是静态的,是minion第一次启动的时候获取的,这些信息不会变化。grains收集的是客户端的信息,不同的客户端可以有不同的grains,grains.ls则可以列出目标机器上可用的grains的名称。
   你可以在minion配置文件总静态的设置grains。如果不想把grains配置在minion文件中,也可以把grains配置在/etc/salt/grains文件中,如果在两边都设置了grains,则minion配置文件中的优先级高。

1
2
3
4
5
6
7
8
9
10
11
12
#匹配系统是ubuntu的 进行ping测试
salt -G 'os:Ubuntu' test.ping
 
#获取有效可用的grains
salt '*' grains.ls
 
#获取grains的数据,所有的。
salt '*' grains.items
 
#要获取单个的数据,如下:
salt '*' grains.item shell
salt '*' grains.item osfullname osrelease
 

  上文说过,可以自己设置grains,既可以设置在minion中也可以设置在grains文件中,先看在minion中的格式:

 

1
2
3
4
5
6
7
grains:
  roles:
    - webserver
    - memcache
  deployment: datacenter4
  cabinet: 13
  cab_u: 14-15
 

  接着看在/etc/salt/grains文件中的格式:

 

1
2
3
4
5
6
roles:
  - webserver
  - memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15
 

  切记:重启minion后才会生效

  不过每次都修改客户端配置文件中的grains很麻烦,我们可以用python编写一些动态的grains来执行。minion启动时会自动执行grains包所带的模块和自定义grains中的函数,不过grains模块中的函数必须返回字典类型的值。这些动态的grains很显然是在master上设置的,放置在file_roots设置下的_grains目录中,然后需要执行 state.highstate或者altutil.sync_grains或者saltutil.sync_all,把_grains中的模块分发到minion上。

  动态grains例子:https://github.com/saltstack/salt/blob/develop/salt/grains/core.py

  参考:http://docs.saltstack.com/topics/targeting/grains.html

13 pillar

   所有通过pillar传输的信息能够保证被提交给目标主机,pillar传输的数据是与特定的minion关联的,每个minion只能看到自己的数据,这使得Pillar引擎在Salt中被用来管理安全的信息。pillar能够包含任意基本的数据结构,如:列表数据,或者k/v数据。可以让数据容易在SLS文档中使用。默认情况下,Pillar已经运行在了Salt系统中。
   默认情况下,主服务器的配置文件内容装载在pillar中,对所用的从服务器来说,通过配置主服务器的配置文件来使全局的从服务器生效。Pillar的数据创建在Salt主服务器上并且安全的分发到从服务器上。Salt当定义pillar的时候 并不局限于pillar sls文件,可以从其他额外的源取得数据。对于那些把基础结构信息存储在其他地方的会很有用。如果想禁止该功能,则可以设置master中的pillar_opts参数。

   pillar使用和state相似的配置,pillar文件子啊地址是在master配置文件中通过pillar_roots参数定义的:

 

1
2
3
pillar_roots:
  base:
    - /srv/pillar
 

   这段代码的意思是base环境下的pillar文件存放在/srv/pillar目录下,与state类似,pillar也有top file,使用相同的匹配方式将数据发送到minion上:/srv/pillar/top.sls

 

1
2
3
4
base:
  '*':
    - data
    - packages
 

/srv/pillar/data.sls内容是:

 

1
2
3
4
5
6
7
{% if grains['os'] == 'RedHat' %}
apache: httpd
git: git
{% elif grains['os'] == 'Debian' %}
apache: apache2
git: git-core
{% endif %}
 

/srv/pillar/packages/init.sls内容是:

 

1
2
3
4
5
{% for user, uid in pillar.get('users', {}).items() %}
{{user}}:
  user.present:
    - uid: {{uid}}
{% endfor %}
 

  上面的代码表示base环境中的而所有minion都具有data和packages中定义的数据,pillar采用与file server相同的文件映射方式,在上例中data映射到文件/srv/pillar/data.sls,packages映射到文件/srv/pillar/packages/init.sls。

  pillar模块有两个函数:pillar.data、pillar.raw,要查看所有的数据,可以如下:

 

1
salt '*' pillar.items
 

  在master上修改pillar下的文件后,要刷新一下,minion上的才能更新

 

1
salt '*' saltutil.refresh_pillar
 

   在使用pillar.items后,得出的额数据是python字典格式的,可以直接使用字典方法访问其中的数据。

下面展示一个官方提供的例子:

  /srv/pillar/pkg/init.sls

 

1
2
3
4
5
6
7
8
9
10
11
pkgs:
  {% if grains['os_family'] == 'RedHat' %}
  apache: httpd
  vim: vim-enhanced
  {% elif grains['os_family'] == 'Debian' %}
  apache: apache2
  vim: vim
  {% elif grains['os'] == 'Arch' %}
  apache: apache
  vim: vim
  {% endif %}
 

  /srv/pillar/top.sls

 

1
2
3
4
5
base:
  '*':
    - data
    - users
    - pkg
 

   /srv/salt/apache/init.sls

 

1
2
3
apache:
  pkg.installed:
    - name: {{ pillar['pkgs']['apache'] }}
 

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

14 Highstate data structure definitions

   top file :主要的state入口文件,指定minions在state执行期间可以使用那些环境、模块。
   state tree : 一些sls文件,存放在file_roots指定的目录下,使用sls模块的形式组织state tree。
   incluede 声明 :定义了一系列modules reference包含在该sls文件中。例如

1
2
3
include:
  - edit.vim
  - http.server
 

   module reference:sls模块的名称,定义在单独分开的sls文件中。一个模块edit.vim,意思是它的sls文件在salt://edit/vim.sls. 
   id 声明:定义一个独特的highstate元素。经常代表一个字典数据,包含state声明和requisite声明。不过可以被name声明覆盖。如果有重复的id声明,则第一个生效。 
   extend 声明:扩展被引用的sls模块中的name声明,extend的值必须是在被引用的sls模块中定义的id。例如:

 

1
2
3
4
5
6
7
8
include:
  - apache
 
extend:
  apache:
    service:
      - watch:
        - file: mywebsite
 

   state 声明:是一个列表,值是function声明定义的。

   requisite 声明:是一个列表,其成员是requisite reference。用来生成动作依赖书,salt states被设计成按顺序执行,作为list组件用在state声明的下一级。

   requisite reference:只有一个值,值是被引用的state声明的名字,只能是requisite声明的成员。 

   function 声明:state中要执行的function,一个state声明中只能有一个function声明。例如:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
#简写
httpd:
  pkg.installed
   
#或者完整写法
httpd:
  pkg:
    - installed
     
#注意下面连续两个简写是不生效的
httpd:
  pkg.installed
  service.running
 

   function arg 声明:作为参数传递给function声明。用在function声明的下一级。

 

1
2
3
4
5
/etc/http/conf/http.conf:
  file.managed:
    - user: root
    - group: root
    - mode: 644
 

   name 声明:覆盖state声明中的name参数,name参数的默认值是ID声明,例如:

 

1
2
3
4
mywebsite:
  file.managed:
    - name: /etc/apache2/sites-available/mywebsite.com
    - source: salt://mywebsite.com
 

   很明显mywebsite这个名词比/etc/apache2/sites-available/mywebsite.com方便。

   参考:http://docs.saltstack.com/ref/states/highstate.html

posted @ 2015-03-29 23:45  不尽长江滚滚来  阅读(308)  评论(0编辑  收藏  举报