基本概念
- Salt Master
- Salt Minion
- targeting
- nodegroup
- grains
- pillar
配置管理
-
master配置文件: /etc/salt/master :
example 注意file_root设定(default: /srv/salt/): ##### Master file_roots configuration: file_roots:
base: - /srv/salt/base dev: - /srv/salt/dev qa: - /srv/salt/qa prod: - /srv/salt/prod
- minion配置文件: /etc/salt/minion:
- minion配置文件: /etc/salt/minion:
-
根目录(/srv/salt)
-
top.sls:
- master通过配置中file_root的路径去找相应文件夹的top.sls来加载state
-
SaltStack通过top.sls加载所有state配置
- 例如, 对应上文master的file_root配置, top.sls为:
base: '*': - global dev: 'webserver*dev*': - webserver 'db*dev*': - db qa: 'webserver*qa*': - webserver 'db*qa*': - db prod: 'webserver*prod*': - webserver 'db*prod*': - db
- 例如, 对应上文master的file_root配置, top.sls为:
-
top被编译执行的顺序:
-
/srv/salt/base/top.sls和/srv/salt/dev/top.sls中都有关于dev的配置,那么/srv/salt/dev/top.sls中的将被忽略.
-
/srv/salt/dev/top.sls和/srv/salt/qa/top.sls中都有关于qa的配置, 后者会被执行, 因为系统会匹配环境名和qa配置.
-
如果以上匹配没找到,则按alphabetical order进行匹配.
-
-
测试并得到错误输出
# salt-call state.highstate -l debug
-
最后(完成state创建或者修改), 将master加载的states发到各minion去执行:
# salt '*' state.highstate -v
-
state配置
-
基本配置:
apache: # ID declaration pkg: # state declaration - installed # function declaration
-
使用子目录: top.sls中webserver.dev用来表示子目录webserver/dev.sls
-
init.sls 在一个子目录里面表示引导文件,也就表示子目录本身, 所以"webserver/init.sls'' 就是表示''webserver''.
- 例如,在上面apache配置中,为了区分不同系统所提供不同的apache版本:
apache/init.sls
apache: pkg.installed: {% if grains['os'] == 'RedHat'%} - name: httpd {% endif %} service.running: {% if grains['os'] == 'RedHat'%} - name: httpd {% endif %} - watch: - pkg: apache - file: /etc/httpd/conf/httpd.conf - user: apache # add file /var/www/index.html: # ID declaration file: # state declaration - managed # function - source: salt://webserver/index.html # function arg - require: # requisite declaration - pkg: apache # requisite reference * 如果同时存在webserver.sls和webserver.init.sls,后者被忽略 * require和watch:
- service(state declaration)支持 watch.
-
例如, 如apache配置文件发生变化时,apache重启:
/etc/httpd/extra/httpd-vhosts.conf: file: - managed - source: salt://webserver/httpd-vhosts.conf apache: pkg: - installed service: - running - watch: - file: /etc/httpd/extra/httpd-vhosts.conf - require: - pkg: apache * templating模板 * 支持Jinja2 * Grains 模板:
- derive information about the underlying system
- grains are bits of information loaded when the salt minion starts
-
grains are static
-
列出grains:
salt '*' grains.ls salt '*' grains.items
-
grains 也可以在minions里设置:
grains: roles: - webserver - memcache deployment: datacenter4 cabinet: 13 cab_u: 14-15
- 或者在minion的/etc/salt/grains设置
-
在top(pillar中的top.sls)中匹配grains:
'node_type:web': - match: grain - webserver 'node_type:postgres': - match: grain - database
或者用Jinja:
{% set node_type = salt['grains.get']('node_type', '') %} {% if node_type %} 'node_type:{{ self }}': - match: grain - {{ self }} {% endif %} * 在模板中使用模块(**未完成**) * extend declaration:
apache/apache.sls
apache: pkg.installed
apache/mywebsite.sls:
include: - apache.apache extend: apache: service: - running - watch: - file: /etc/httpd/extra/httpd-vhosts.conf /etc/httpd/extra/httpd-vhosts.conf: file.managed: - source: salt://apache/httpd-vhosts.conf * inlcude declaration:
python/python-libs.sls:
python-dateutil: pkg.installed
python/django.sls:
include: - python.python-libs django: pkg.installed: - require: - pkg: python-dateutil * name declaration:
apache/mywebsite.sls:
include: - apache.apache extend: apache: service: - running - watch: - file: mywebsite mywebsite: file.managed: - name: /etc/httpd/extra/httpd-vhosts.conf - source: salt://apache/httpd-vhosts.conf
我的理解为: 给复杂的"/etc/httpd/extra/httpd-vhosts.conf"起了个别名"mywebsite"作为id. * names declaration: 用一个例子可以解释出names declaration的作用和用法:
{% for usr in ['moe','larry','curly'] %} {{ usr }}: user.present {% endfor %} render后内容如下: moe: user.present larry: user.present curly: user.present 用names declaration: stooges: user.present: - names: - moe - larry - curly
-
配置pillar
pillar是配置在master上,用于更为安全的发布数据(高敏感数据)到指定相关的minions. 我的理解是,实际上就是定义了一堆可以用在states的jinja模板里的静态变量.
- 在master的配置文件中设定pillar_roots,并创建pillar文件夹: # mkdir /srv/pillar
- 创建top.sls
- 创建pillar的.sls文件
- pillar is just a Python dict, so Python dict methods such as get and items can be used.
pillar的使用
# /srv/pillar/top.sls
base:
'*':
- users
# /srv/pillar/users/init.sls
users-data:
thatch: 1000
shouse: 1001
utahdave: 1002
redbeard: 1003
# /srv/salt/users/init.sls
#注意, 这里要使用users-data作为字典名因为在/srv/pillar/users/init.sls是这么定义的
{% for user, uid in pillar.get('users-data', {}).items() %}
{{user}}:
user.present:
- uid: {{uid}}
{% endfor %}
notes:
- 配置中
source: salt://webserver/index.html
中salt://
指代 "file_root", 如"/srv/salt/" 好像有点不对"salt://"指向top.sls所在directory应该...... -
prereq: prereq目前还没搞明白, 不过看例子, 部署新代码的时候用的到.
graceful-down: cmd.run: - name: service apache graceful - prereq: - file: site-code site-code: file.recurse: - name: /opt/site_code - source: salt://site/code
-
但是, 部署代码并重启服务(如nginx restart/reload), 这种情况用watch:
ntpd: service.running: - watch: - file: /etc/ntp.conf file.managed: - name: /etc/ntp.conf - source: salt://ntp/files/ntp.conf
-
官方文档给出关于watch的note是:
-
If a state should only execute when another state has changes, and otherwise do nothing, the new onchanges requisite should be used instead of watch. watch is designed to add additional behavior when there are changes, but otherwise execute normally.
If the mod_watch function exists in the watching state module, it will be called in addition to the normal watching state. The return data from the mod_watch function is what will be returned to the master in this case; the return data from the main watching function is discarded.
Not all state modules contain mod_watch. If mod_watch is absent from the watching state module, the watch requisite behaves exactly like a require requisite.
- top.sls 中的targeting匹配用在highstate的时候,state.sls中没有用.
未完待续.....