自动化运维之saltstack(二)states深入理解

深入了解SLS的可以参考这篇博文:http://www.ituring.com.cn/article/42238 

个人觉得这篇文章翻译的不错,所以转载过来。


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

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


只是数据而已

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

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


默认的数据  -YAML

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

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


这些数据确保名为Apache的软件包处于已安装状态(如果不是,那么就安装Apache),服务进程Apache处于运行状态。这些数据简洁易于理解。下面简单解释一下:

第1行 是这段数据的ID,被称作ID声明。这个ID是将要执行的这些命令的名字。

第2行和第4行表示State声明的开始,使用了pkg和service这两个states,pkg使用系统本地的软件管理器管理将要安装的软件,service管理系统守护进程。

第3行和第5行是要执行的函数。这些函数定义了名字为ID的软件包和服务的目标状态。此例中,软件包应当处于安装状态,服务必须运行。

最后,第6行是关键字require。这被称为必要语句(Requisite),它确保了Apache服务只有在成功安装软件包后才会启动。


添加配置文件和用户


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

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
apache:
   pkg:
     - installed
   service:
     - running
     watch:
       - pkg: apache
       file/etc/httpd/conf/httpd.conf
       - user: apache
   user.present:
     - uid: 87
     - gid: 87
     - home: /var/www/html
     - shell: /bin/nologin
     - require:
       - group: apache
   group.present:
     - gid: 87
     - require:
       - pkg: apache
 /etc/httpd/conf/httpd.conf:
   file.managed:
     source: salt://apache/httpd.conf
     - user: root
     - group: root
     - 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
2
3
4
Note
Salt的watcher概念非常有意思。Puppet中功能类似的是notify,也可以触发服务重启。Salt的watcher
非常灵活,watcher本质上是在state的代码中定义的名为mod_watch()的函数,在这个函数中想做什么事
情完全就看你的需求了。我没有仔细看Puppet的notify如何实现,不知道是否有这么灵活。


多个SLS文件

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

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

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

apache/init.sls

apache/httpd.conf


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

ssh/init.sls:

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



ssh/server.sls

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
include:
   ssh
 openssh-server:
   pkg.installed
 sshd:
   service.running:
     - require:
       - pkg: openssh-client
       - pkg: openssh-server
       file/etc/ssh/banner
       file/etc/ssh/sshd_config
 /etc/ssh/sshd_config:
   file.managed:
     - user: root
     - group: root
     - mode: 644
     source: salt://ssh/sshd_config
     - require:
       - pkg: openssh-server
 /etc/ssh/banner:
   file:
     - managed
     - user: root
     - group: root
     - mode: 644
     source: salt://ssh/banner
     - require:
       - pkg: openssh-server
1
2
3
4
Note在ssh/server.sls中,用了两种不同的方式来表示用Salt管理一个文件。在ID为
/etc/ssh/sshd_config段中,直接使用file.managed作为state声明,而在ID为/etc/ssh/banner段中,
使用file作为state声明,附加一个managed属性。两种表示方法的含义与结果完全一样,只是写法不同。
现在State Tree如下(有些被引用的文件没有给出内容,不影响立即):


1
2
3
4
5
6
7
apache/init.sls
apache/httpd.conf
ssh/init.sls
ssh/server.sls
ssh/banner
ssh/ssh_config
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
2
3
4
5
6
7
8
9
include:
   - apache
 extend:
   apache:
     service:
       watch:
         - pkg: mod_python
 mod_python:
   pkg.installed

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

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

1
2
3
4
5
6
include:
   ssh.server
 extend:
   /etc/ssh/banner:
     file:
       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
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
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
   user.present:
     - uid: 87
     - gid: 87
     - home: /var/www/html
     - shell: /bin/nologin
     - require:
       - group: apache
   group.present:
     - gid: 87
     - require:
       - pkg: apache
 /etc/httpd/conf/httpd.conf:
   file.managed:
     source: salt://apache/httpd.conf
     - user: root
     - group: root
     - mode: 644


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

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

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
include:
   - moosefs
 {% for mnt in salt['cmd.run']('ls /dev/data/moose*').split() %}
 /mnt/moose{{ mnt[-1] }}:
   mount.mounted:
     - device: {{ mnt }}
     - fstype: xfs
     - mkmnt: True
   file.directory:
     - user: mfs
     - group: mfs
     - require:
       - user: mfs
       - group: mfs
 {% endfor %}
 '/etc/mfshdd.cfg':
   file.managed:
     source: salt://moosefs/mfshdd.cfg
     - user: root
     - group: root
     - mode: 644
     - template: jinja
     - require:
       - pkg: mfs-chunkserver
 '/etc/mfschunkserver.cfg':
   file.managed:
     source: salt://moosefs/mfschunkserver.cfg
     - user: root
     - group: root
     - mode: 644
     - template: jinja
     - require:
       - pkg: mfs-chunkserver
 mfs-chunkserver:
   pkg:
     - installed
 mfschunkserver:
   service:
     - running
     - require:
 {% for mnt in salt['cmd.run']('ls /dev/data/moose*') %}
       mount/mnt/moose{{ mnt[-1] }}
       file/mnt/moose{{ mnt[-1] }}
 {% endfor %}
       file/etc/mfschunkserver.cfg
       file/etc/mfshdd.cfg
       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
2
3
4
5
6
7
#!py
 def run():
     '''
     Install the django package
     '''
     return {'include': ['python'],
             'django': {'pkg': ['installed']}}

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

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


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

1
2
3
4
include:
  - python
django:
  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







      本文转自027ryan  51CTO博客,原文链接:http://blog.51cto.com/ucode/1935058,如需转载请自行联系原作者



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java里面的 |运算符_Java 中 | ^ 运算符的简单使用

背景今天碰到了代码中的按位与运算,复习一下,先列一个各个进制数据表。顺便复习一下十进制转二进制的计算方式:接下来解释下这三个运算符:&  按位与,都转为二进制的情况下,同为1则为1,否则…

leetcode915. 分割数组

给定一个数组 A,将其划分为两个不相交(没有公共元素)的连续子数组 left 和 right, 使得: left 中的每个元素都小于或等于 right 中的每个元素。 left 和 right 都是非空的。 left 要尽可能小。 在完成这样的分组后返回…

彻底理解正向代理、反向代理、透明代理

套用古龙武侠小说套路来说,代理服务技术是一门很古老的技术,是在互联网早期出现就使用的技术。一般实现代理技术的方式就是在服务器上安装代理服务软件,让其成为一个代理服务器,从而实现代理技术。常用的代理技术分为正向代理、反…

使用showMessageDialog显示消息框

-----------------siwuxie095 工程名:TestJOptionPane 包名:com.siwuxie095.showdialog 类名:TestMessageDialog.java 工程结构目录如下: 代码: package com.siwuxie095.showdialog; import java.awt.BorderLayout;…

将Javascript带到边缘设备

Smart devices today are very similar to labour-saving gadgets a generation ago: Where previously everything got a power cord, now everything gets a chip. 如今的智能设备与上一代的省力小工具非常相似:以前所有设备都配有电源线,而现在所有设…

java 泛型 父子_使用通配符和泛型:完成父子类关系的List对象的类型匹配

泛型和通配符使用泛型和通配符都可以让一个方法所表示的算法逻辑适应多种类型。Java中具备继承关系的类A、B(A extends B)它们的集合List和List之间是没有继承关系的,可以使用泛型或通配符来让一个方法支持同时接受List和List。代码场景这里分别定义类Animal、Dog和…

重定向描述符

文件描符 缩写 描述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 1、重定向错误和数据 1234[rootlogicserver tmp]# ls -al data1 haha 2> qingyun.txt 1&g…

NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证

目录 开发环境  1、建立工程  2、目录结构  3、Express配置文件  4、Ejs模板  5、安装常用库及页面分离  6、路由  7、session  8、页面访问控制及提示JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里 的JS,浏览器充…

LeetCode-208 Implement Trie (Prefix Tree)

题目描述 Implement a trie with insert, search, and startsWith methods. 题目大意 实现对一棵树的插入、搜索以及前序查找操作。 (树的每个节点代表一个小写字母,从根节点到叶节点代表一个完整的单词) 示例 E Trie trie new Trie();trie.…

react组件生命周期_React组件生命周期-挂钩/方法介绍

react组件生命周期React components have several lifecycle methods that you can override to run your code at a particular time in the process.React组件具有几种生命周期方法,您可以重写它们以在流程中的特定时间运行代码。 In this video, Nick Karnik de…

(马世龙)Linux下CACTI完全搭建技术文档二

续(马世龙)Linux下CACTI完全搭建技术文档一 6.完成cacti的安装1. 首先检查一下rra/下面,有没有数据2. snmpwalk -v 2c -c public ServerIP if 用来测试被控对象(serverIP)是否开启了SNMP服务3. snmpwalk -v 2c ServerIP -c public .1.3.6.1.4…

项目经理如何管理情绪?这三本书管理书籍你必须要看

本文主要是介绍三本管理的书籍,需要全部书籍的可以加Q群375508415去拿走。里面很多大神的PMP资料。 大家有没有觉得项目经理有时像个政委,做员工思想工作; 有时像个HR,操心员工的稳定和发展; 有时像个咨询顾问&#xf…

java 外部接口调用 设计模式_《Java设计模式》之接口模式

-----------模式是思想的体现,而非具体的实现。抽象的讲,类的接口是类允许其他类对象访问的方法与字段集。接口通常代表一种承诺,即方法需要实现接口方法名表示的操作,遵循代码注释和其他文档说明,类的实现就是方法体中…

BFS(广度优先搜索)

Catch That Cow Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer …

leetcode111. 二叉树的最小深度(队列)

给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7],3/ \9 20/ \15 7 返回它的最小深度 2.代码 /*** Definition for a binary tree no…

企业网站6个常见的优化漏洞

导读:企业做营销网站目的,就是希望通过网络营销,挖掘目标客户。目标客户怎么来,那就需要通过网站优化,把网站关键词优化排名到首页,这样才能更多的机会被潜在客户点击。很多企业网站上线之前,没…

aspx 微型_最初的十亿分钟:正在向世界授课的微型非营利组织背后的数字

aspx 微型by Quincy Larson昆西拉尔森(Quincy Larson) 最初的十亿分钟:正在向世界授课的微型非营利组织背后的数字 (The First Billion Minutes: The Numbers Behind the Tiny Nonprofit That’s Teaching the World to Code) People have now spent more than 1 b…

[RN] React Native 自定义导航栏随滚动渐变

React Native 自定义导航栏随滚动渐变 实现效果预览: 代码实现: 1、定义导航栏 NavPage.js import React, {Component} from react; import {View, Text, Image, StyleSheet, TouchableOpacity, Platform, Dimensions} from react-native;/*** 自定义导航…

【CSS 技能提升】 :before和:after的使用

前几天的晚上较全面的去看了下css的一些文档和资料,大部分的样式运用都没什么大问题了,只是有些许较陌生,但是也知道他们的存在和实现的是什么样式。今天主要想在这篇学习笔记中写的也不多,主要是针对:before和:after写一些内容&a…

c语言模拟java面向对象_纯c语言实现面向对象分析与示例分享

#include #include //接口#ifndef Interface#define Interface struct#endif//类#ifndef Class#define Class struct#endif//抽象形状类Class Shape;typedef Class Shape shape;//抽象形状类的方法声明shape* Shape(int edges);int shape_getEdges(shape *);int shape_getArea(…