作者言

我也只是SaltStack的初学者,如果文中有错误的地方,请不吝赐教。

在学习的过程,我也做了不少实验,犯了不少错,积累了一些经验,对SaltStack的运行也有一定了解,如果有什么问题,或是不太理解的地方,非常欢迎留言交流!

Salt States

参考链接:官方文档

简洁,简洁,简洁

众多强大而有力的设计都建立在简单的原则之上。Salt SLS系统也努力向K.I.S.S看齐。(Keep It Stupidly Simple)

SLS(代表SaLt State文件)是Salt State系统的核心。SLS描述了系统的目标状态,由格式简单的数据构成。这经常被称作配置管理。

  1. Note
  2. 这篇文章从整体上介绍了Salt States,以后还会增加对各组件的深入介绍。

只是数据而已

深入学习之前,明白SLS文件只是结构化的数据而已是很有用的。看懂和编写SLS文件不需要理解这一点,但会让你体会到SLS系统的强大。

SLS文件本质上只是一些dictionarieslistsstringsnumbers。这种设计让SLS文件非常灵活,可以满足开发者的各种需求,而且可读性很高。写得越多,就越清楚到底写得是什么。

默认的数据 - YAML

Salt默认使用能找到的最简单的序列化数据格式——YAML,来表达SLS数据。典型的SLS文件如下:

  1. apache:
  2. pkg:
  3. - installed
  4. service:
  5. - running
  6. - require:
  7. - pkg: apache

这些数据确保名为apache的软件包处于已安装状态(如果不是,那么就安装apache),服务进程apache处于运行状态。这些数据简洁,易于理解。下面简单解释一下:
第1行是这段数据的ID,被称作ID声明。这个ID是将要执行的这些命令的名字。
第2行和第4行表示State声明开始,使用了pkg和service这两个states。pkg使用系统本地的软件包管理器管理将要安装的软件,service管理系统守护进程。
第3行和第5行是要执行的function。这些function定义了名字为ID的软件包和服务的目标状态。此例中,软件包应当处于已安装状态,服务必须运行。
最后,第6行是关键字require。这被称为必要语句(Requisite),它确保了apache服务只有在成功安装软件包后才会启动。

添加配置文件和用户

部署像apache这样的web服务器时,还需要添加其他的内容。需要管理apache的配置文件,需要添加运行apache服务的用户和组。

  1. apache:
  2. pkg:
  3. - installed
  4. service:
  5. - running
  6. - watch:
  7. - pkg: apache
  8. - file: /etc/httpd/conf/httpd.conf
  9. - user: apache
  10. user.present:
  11. - uid: 87
  12. - gid: 87
  13. - home: /var/www/html
  14. - shell: /bin/nologin
  15. - require:
  16. - group: apache
  17. group.present:
  18. - gid: 87
  19. - require:
  20. - pkg: apache
  21. /etc/httpd/conf/httpd.conf:
  22. file.managed:
  23. - source: salt://apache/httpd.conf
  24. - user: root
  25. - group: root
  26. - mode: 644

这个SLS大大扩展了上面的例子,增加了配置、用户、组,还有一个新的必要语句:watch。

user和group这两个state添加在apache这个ID下,所以增加的user和group名字都是apache。require语句确保了只有在apache这个group存在时才建立user,只有在apache这个package成功安装后才会建立group。

service中的require语句换成了watch,从需要1个软件包改为监视3个state(分别是pkg、file和user)。watch语句和require很相似,都能保证被监视或需要的state在自己之前执行,但是watch还有其他作用。在被监视的state发生变化时,定义watch语句的state会执行自己的watcher函数。也就是说,更新软件包,修改配置文件,修改apache用户的uid都会触发service state的watcher函数。在这个例子中,service state的watcher会重启apache服务。

  1. Note
  2. Saltwatcher概念非常有意思。Puppet中功能类似的是notify,也可以触发服务重启。Saltwatcher非常灵活,watcher本质上是在state的代码中定义的名为mod_watch()的函数,在这个函数中想做什么事情完全就看你的需求了。我没有仔细看Puppetnotify如何实现,不知道是否有这么灵活。

多个SLS文件

在更有扩展性的部署Salt State时,需要用到不只一个SLS。上面的例子中只使用1个SLS文件,2个或多个SLS文件可以结合形成State Tree。上面的例子还使用了一个奇怪的文件来源 —salt://apache/httpd.conf,这个文件究竟在什么位置呢?

SLS文件以一定的目录结构分布在master上;SLS和要下发到minion上的文件都只是普通文件。

上面的例子中的文件在Salt的根目录(见《SaltStack中的文件服务器》)分布如下:

  1. apache/init.sls
  2. apache/httpd.conf

httpd.conf只是apache目录下的一个普通文件,可以直接引用。 使用多个SLS文件可以更加灵活方便,以SSH为例:

ssh/init.sls:

  1. openssh-client:
  2. pkg.installed
  3. /etc/ssh/ssh_config:
  4. file.managed:
  5. - user: root
  6. - group: root
  7. - mode: 644
  8. - source: salt://ssh/ssh_config
  9. - require:
  10. - pkg: openssh-client

ssh/server.sls:

  1. include:
  2. - ssh
  3. openssh-server:
  4. pkg.installed
  5. sshd:
  6. service.running:
  7. - require:
  8. - pkg: openssh-client
  9. - pkg: openssh-server
  10. - file: /etc/ssh/banner
  11. - file: /etc/ssh/sshd_config
  12. /etc/ssh/sshd_config:
  13. file.managed:
  14. - user: root
  15. - group: root
  16. - mode: 644
  17. - source: salt://ssh/sshd_config
  18. - require:
  19. - pkg: openssh-server
  20. /etc/ssh/banner:
  21. file:
  22. - managed
  23. - user: root
  24. - group: root
  25. - mode: 644
  26. - source: salt://ssh/banner
  27. - require:
  28. - pkg: openssh-server
  1. Note
  2. ssh/server.sls中,用了两种不同的方式来表示用Salt管理一个文件。在ID为/etc/ssh/sshd_config段中,直接使用file.managed作为state声明,而在ID为/etc/ssh/banner段中,使用file作为state声明,附加一个managed属性。两种表示方法的含义与结果完全一样,只是写法不同。

现在State Tree如下(有些被引用的文件没有给出内容,不影响理解):

  1. apache/init.sls
  2. apache/httpd.conf
  3. ssh/init.sls
  4. ssh/server.sls
  5. ssh/banner
  6. ssh/ssh_config
  7. ssh/sshd_config

ssh/server.sls中使用了include语句。include将别的SLS添加到当前文件中,所以可以require或watch被引用的SLS中定义的内容,还可以extend其内容(马上讲到)。include语句使得state可以跨文件引用。使用include相当于把被引用的内容文件添加到自身。

扩展被引用的SLS数据 Extend

扩展是什么意思呢?比如在ssh/server.sls中定义了一个apache通用的服务器,现在要增加一个带mod_python模块的apache,不需要重头写新的SLS,直接include原来的server.sls,然后增加安装mode_python的state,再在apache service的watch列表中增加mod_python即可。python/mod_python.sls内容如下:

  1. include:
  2. - apache
  3. extend:
  4. apache:
  5. service:
  6. - watch:
  7. - pkg: mod_python
  8. mod_python:
  9. pkg.installed

这个例子中,先将apache目录下的init.sls文件包含进来(在include一个目录时,Salt会自动查找init.sls文件),然后扩展了ID为apache下的service state中的watch列表。

也可以在Extending中修改文件的下载位置。ssh/custom-server.sls:

  1. include:
  2. - ssh.server
  3. extend:
  4. /etc/ssh/banner:
  5. file:
  6. - source: salt://ssh/custom-banner

Extend使得Salt的SLS更加灵活。为什么SLS能够做Extend呢?文章一开始最强调了,SLS中的文件仅仅是结构化的data而已,在处理SLS时,会将其中的内容解析成Python中的dict(当然这个dict中会嵌套dict和list)。修改apache watch的内容,相当于往list里面添加一个元素;修改banner文件的下载路径相当于修改dict中的某个key对应的值。在extending时,会附加加require/watch的内容,而不是覆盖。

理解渲染系统 Render System

因为SLS仅仅是data,所以不是非得用YAML来表达。Salt默认使用YAML,只是因为易学易用。只要有对应的renderer,SLS文件可以用任何方式表达(Salt关心的是最终解析出来的数据结构,只要你的renderer能够按要求返回这个数据结构,Salt干嘛关心你如何书写源文件呢?)。

Salt默认使用yaml_jinja渲染器。yaml_jinjia先用jinja2模板引擎处理SLS,然后再调用YAML解析器。这种设计的好处是,可以在SLS文件使用所有的编程结构(jinja2能怎么用,这里就能怎么用。条件,循环,Python代码,什么都可以)。

其他可用的渲染器还包括:yaml_mako,使用Mako模板引擎;yaml_wempy,使用Wempy模板引擎;py,直接使用Python写SLS文件;pydsl,建立在Python语法基础上的描述语言。

简单介绍默认的渲染器 —— yaml_jinja

关于jinja模板引擎的使用请参考其官方文档

在基于模板引擎的渲染器里,可以从3个组件中获取需要的数据:salt,grains和pilla。在模板文件中,可以用salt对象执行任意的Salt function,使用grains访问Grains数据。示例如下:
apache/init.sls:

  1. apache:
  2. pkg.installed:
  3. {% if grains['os'] == 'RedHat'%}
  4. - name: httpd
  5. {% endif %}
  6. service.running:
  7. {% if grains['os'] == 'RedHat'%}
  8. - name: httpd
  9. {% endif %}
  10. - watch:
  11. - pkg: apache
  12. - file: /etc/httpd/conf/httpd.conf
  13. - user: apache
  14. user.present:
  15. - uid: 87
  16. - gid: 87
  17. - home: /var/www/html
  18. - shell: /bin/nologin
  19. - require:
  20. - group: apache
  21. group.present:
  22. - gid: 87
  23. - require:
  24. - pkg: apache
  25. /etc/httpd/conf/httpd.conf:
  26. file.managed:
  27. - source: salt://apache/httpd.conf
  28. - user: root
  29. - group: root
  30. - mode: 644

这个例子很容易理解,用到了jinja中的条件结构,如果grains中的os表明minion的操作系统是Red Hat,那么Apache的软件包名和服务名应当是httpd。

再来一个更NB的例子,用到了jinja的循环结构,在设置MooseFs分布式chunkserver的模块中:
moosefs/chunk.sls:

  1. include:
  2. - moosefs
  3. {% for mnt in salt['cmd.run']('ls /dev/data/moose*').split() %}
  4. /mnt/moose{{ mnt[-1] }}:
  5. mount.mounted:
  6. - device: {{ mnt }}
  7. - fstype: xfs
  8. - mkmnt: True
  9. file.directory:
  10. - user: mfs
  11. - group: mfs
  12. - require:
  13. - user: mfs
  14. - group: mfs
  15. {% endfor %}
  16. '/etc/mfshdd.cfg':
  17. file.managed:
  18. - source: salt://moosefs/mfshdd.cfg
  19. - user: root
  20. - group: root
  21. - mode: 644
  22. - template: jinja
  23. - require:
  24. - pkg: mfs-chunkserver
  25. '/etc/mfschunkserver.cfg':
  26. file.managed:
  27. - source: salt://moosefs/mfschunkserver.cfg
  28. - user: root
  29. - group: root
  30. - mode: 644
  31. - template: jinja
  32. - require:
  33. - pkg: mfs-chunkserver
  34. mfs-chunkserver:
  35. pkg:
  36. - installed
  37. mfschunkserver:
  38. service:
  39. - running
  40. - require:
  41. {% for mnt in salt['cmd.run']('ls /dev/data/moose*') %}
  42. - mount: /mnt/moose{{ mnt[-1] }}
  43. - file: /mnt/moose{{ mnt[-1] }}
  44. {% endfor %}
  45. - file: /etc/mfschunkserver.cfg
  46. - file: /etc/mfshdd.cfg
  47. - file: /var/lib/mfs

这个例子展示了jinja的强大,多个for循环用来动态地检测并挂载磁盘,多次使用salt对象(这里使用了cmd.run这个执行模块)执行shell命令来收集数据。

简单介绍Python和PyDSL渲染器

在任务逻辑非常复杂时,默认的yaml_jinja渲染器不一定满足要求,这时可以使用Python渲染器。如何在State tree中添加使用py渲染器的SLS文件呢?简单。 一个非常简单的基本Python SLS文件:
python/django.sls:

  1. #!py
  2. def run():
  3. '''
  4. Install the django package
  5. '''
  6. return {'include': ['python'],
  7. 'django': {'pkg': ['installed']}}

这个例子也很好理解,第1行告诉Salt不使用默认的渲染器,而是用py。接着定义了函数run,这个函数的返回值必须符合Salt的要求,即HighState数据结构(我接下来就写关于HighState的文章,现在不必关心其细节,反正就是一个dict,key和value都有规定好的含义)。 如果换用pydsl渲染器,上面的例子会更简洁:
python/django.sls:

  1. #!pydsl
  2. include('python', delayed=True)
  3. state('django').pkg.installed()

如果用YAML,会是下面这个样子:

  1. include:
  2. - python
  3. django:
  4. pkg.installed

这也可以看出,正常情况下使用YAML是非常合适的,但如果有需要时,使用纯粹的Python SLS可以非常NB。

运行和调试Salt States

写好的SLS如何才能应用到minion呢?在SaltStack中,远程执行是一切的基础。执行命令salt '*' state.highstate会让所有的minion到master上来取走自己的SLS定义,然后在本地调用对应的state module(user,pkg,service等)来达到SLS描述的状态。如果这条命令只返回minion的主机名加一个':',多半是哪一个SLS文件有错。如果minion是以服务进程启动,执行命令salt-call state.highstate -l debug可以看到错误信息,便于调试。minion还可以直接在前台以debug模式运行:salt-minion -l debug

接下来是什么?

接下来是关于Pillar的内容,官方文档在此,关于Pillar的文章发表在此

Salt States概览的更多相关文章

  1. salt.states.file试用

    从master往linux上的minion复制文件参考http://netkiller.sourceforge.net/linux/management/saltstack.html后半部分,他已经写 ...

  2. Salt Stack 官方文档翻译 - 一个想做dba的sa - 博客频道 - CSDN.NET

    OSNIT_百度百科 Salt Stack 官方文档翻译 - 一个想做dba的sa - 博客频道 - CSDN.NET Salt Stack 官方文档翻译 分类: 自动运维 2013-04-02 11 ...

  3. Salt状态管理

    Salt状态管理   前言 上一篇文章概括性的介绍了Salt的用途和它的基本组成和实现原理,也深入的的介绍了Salt的命令编排和批量执行,但是对于状态管理只是简单的介绍了一下,因为状态管理是一个比较重 ...

  4. 集群管理工具Salt

    集群管理工具Salt 简介 系统管理员(SA)通常需要管理和维护数以百计的服务器,如果没有自动化的配置管理和命令执行工具,那么SA的工作将会变得很繁重.例如,要给集群中的每个服务器添加一个系统用户,那 ...

  5. 死磕salt系列-salt入门

    saltstack简介 SaltStack是一种新型的基础设施管理软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位.SaltStack提供了一个动态基础 ...

  6. 死磕salt系列-salt配置文件

    这篇文件主要用来解释一下salt配置中常用的参数,其他的参数可以参考官网文档. 基础参数 interface: 服务器监听地址. ipv6: 是否启用ipv6. max_open_files: 最大文 ...

  7. 死磕salt系列-salt 常用modules

    saltstack 常用模块介绍 file模块 被控主机文件常见操作,包括文件读写.权限.查找.校验等 salt '*' file.get_sum /etc/resolv.conf md5 salt ...

  8. salt命令

    salt-key -L list在master上所有收到的公钥连接请求 -A accept所有pending的请求. -D 删除所有 在minion上启动服务后,几十秒后会在/etc/salt/pki ...

  9. Salt Highstate数据结构定义

    作者言 这篇文档详细解释了SLS文件中,每个部分的名称与含义,以及SLS中的数据处理后的数据结构. 我只是SaltStack的初学者,如果文中有错误的地方,请不吝赐教.在学习的过程,我做了一些实验,犯 ...

随机推荐

  1. 面试题:android的安全机制有哪些

    1 uid . gid . gids Android 的权限分离的基础是建立在 Linux 已有的 uid . gid . gids 基础上的 . UID: Android 在 安装一个应用程序,就会 ...

  2. Java集合学习(5):LinkedHashMap

    一.概述 HashMap是无序的,HashMap在put的时候是根据key的hashcode进行hash然后放入对应的地方.所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟 ...

  3. echart绘制GDP数据

    {% extends "base.html" %} {% block self_head_css_js %} {% endblock %} {% block main_conten ...

  4. Linux chage命令详解

    原文 chage命令用于密码实效管理,该是用来修改帐号和密码的有效期限,接下来通过本文给大家介绍Linux chage命令相关知识,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起学习吧 lin ...

  5. BBS之文章详情页搭建

    博客评论相关 博客文章详情页搭建 {% extends 'base.html' %} {% block css %} <style> #div_digg { float: right; m ...

  6. Prometheus(五):Prometheus+Alertmanager 配置企业微信报警

    此处默认已安装Prometheus服务,服务地址:192.168.56.200  一.设置企业微信 1.1.企业微信注册(已有企业微信账号请跳过) 企业微信注册地址:https://work.weix ...

  7. maven nexus 私服搭建 Windows版

    准备工作 已安装jdk,并配置好了环境变量 已安装maven,并配置好了环境变量 下载Nexus Repository OSS:https://www.sonatype.com/download-os ...

  8. C++学习(12)—— 运算符重载

    运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 1.加号运算符重载 作用:实现两个自定义数据类型相加的运算 #include <iostream> #i ...

  9. 遗传算法介绍并附上Python代码

    之前介绍过遗传算法,参见:https://www.cnblogs.com/LoganChen/p/7509702.html 我们用Python实现同样的问题解答. y=10*sin(5*x)+7*ab ...

  10. Discuz通过修改文章标题更好的实现SEO的方法

    找到: /source/module/forum/forum_viewthread.php 代码如下: $navtitle = get_title_page($_G['forum_thread'][' ...