轻松使用SaltStack管理成千上万台服务器(入门教程)

目录树

 引言:一个”非专职运维人员“的烦恼

 Salt快速入门

 1. 安装配置

 2. 安装管理端(master)

 3. 安装被管理端(minion)

 4. 接受minion的托管请求

 5. 测试

 Salt的强大功能

 1. 批量操作(targeting)

 2. 节点分组(nodegroups)

 3. 命令执行(execution)

 4. 节点信息(grains)

 5. 配置管理(state)

 6. 小结

 Salt state实例解析

 1. 目录结构

 2. apache/init.sls

 3. ssh/init.sls

 4. ssh/server.sls

 5. ssh/custom-server.sls


引言:一个”非专职运维人员“的烦恼

加入到某证券公司的IT部门,尽管所在的部门挂了一个“研发部”的名字,但是我发现有大概40%的时间是在做运维工作。

这来自两种情况:
1. 自主开发的应用,需要持续的改进,不断的更新、发布、部署、调整配置,这不是运维部门喜欢的状态。
2. 软件商提供的“产品”无法满足运维部门的要求:无法通过简单的 Q&A 文档保证系统的正常运行,经常需要有一定技术能力的人员解决系统运行过程中各种稀奇古怪的问题。

这种情况下只能自己做一个“非专职运维人员”,需要频繁的登录各种服务器,执行一些命令来查看状态或者更改配置(包括配置文件的变更和软件包的安装部署)。很多操作都是不断的重复,日复一日,让人厌烦。

”重复的工作应该交给程序去做“,所以我自己写过一些脚本。为了避免将脚本上传到几十台服务器并且不时进行更改,我使用Fabric来进行服务器的批量操作。

尽管避免了”批量的人工操作“,但我还是在进行”人工的批量操作“。远远没有实现自动管理。将有限的生命解放出来,投入到更有意义的编码工作是一个奔四程序员应有的追求,所以我又睁大红肿的眼睛,迷茫的搜索这个世界。

我发现了Puppet,Chef和CFEngine,但是并不满意。直到我发现了Salt,我的眼前一亮:这正是我所需要的东西。

如果说Salt有什么独特之处打动了我,那就是:

简单:可能是源于python的简约精神,Salt的安装配置和使用简单到了令人发指的地步。任何稍有经验的linux使用者可以在10分钟之内搭建一个测试环境并跑通一个例子(相比之下,puppet可能需要30--60分钟)。
高性能:Salt使用大名鼎鼎的ZeroMQ作为通讯协议,性能极高。可以在数秒钟之内完成数据的传递
可伸缩:基于ZeroMQ通信,具备很强的扩展性;可以进行分级管理,能够管理分布在广域网的上万台服务器。

尽管twitter、豆瓣、oracle、等著名网站的运维团队都在使用puppet,但是我相信,他们切换到salt只是一个时间问题。毕竟不是所有的人都喜欢操纵傀儡(puppet),但是谁又能离开盐(salt)呢?

关于Salt和Puppet的对比,可以参考这里,或者看看中文版

Salt快速入门

Salt的体系结构中将节点区分为: master, minion, syndic。

1. master: 老大,管理端
2. minion: 马仔,被管理端
3. syndic: 头目,对于老大来说是马仔,对于马仔来说是老大

在入门阶段,先不考虑syndic。

1. 安装配置

如果将操作系统区分为:
*NIX
Linux
Solaris
HP Unix
FreeBSD
OS X
windows

理论上来说,Salt可以安装在任何*NIX系统上,包括master和minion。除了源代码之外, 还可以通过Salt提供的安装脚本,或者PyPI进行安装。

对于Linux,尤其是企业环境中常用的RHEL,CentOS,Ubuntu,可以通过包管理器非常容易的安装master 和/或 minion。 比如: yum(需要先配置EPEL), apt(需要增加http://debian.madduck.net/repo/库),yaourt,ports。

Mac OS X 先使用HomeBrew解决依赖包:brew install swig zmq,然后用PyPI安装:pip install salt。

对于windows,只能安装minion(windows只适合做马仔)。从官方网站下载合适的安装包。安装过程中可以指定master地址和本机名称。 安装后需要自己启动Salt服务。配置文件在C:\salt\conf\minion。

具体的各操作系统下的安装可以参考官方文档。这里为了简单,只考虑常用的RHEL/CentOS 和 windows。 在下面的例子中,使用一台RHEL/CentOS作为master, 另外一台RHEL/CentOS和一台windows 2003 Server作为 minion。

2. 安装管理端(master)

# 安装EPEL,注意选择合适的版本 rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm yum update  # 安装master yum install salt-master        # 修改配置 vim /etc/salt/master  # 最基本的设定服务端监听的IP(比如使用VIP做master的高可用时): # interface: 服务端监听IP # 其他配置参考[官方文档](http://docs.saltstack.com/ref/configuration/master.html)  # 启动服务(以下命令等效) salt-master -d /etc/init.d/salt-master start service salt-master start

3. 安装被管理端(minion)

# 安装EPEL,注意选择合适的版本 rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm yum update  # 安装minion yum install salt-minion     # 修改配置 vim /etc/salt/minion  # 最基本的设定是指定master地址,以及本机标识符: # master: master的主机名或IP地址 # id: 本机标识符 # 其他配置参考[官方文档](http://docs.saltstack.com/ref/configuration/minion.html)   # 启动服务(以下命令等效) salt-minion -d /etc/init.d/salt-minion start service salt-minion start

4. 接受minion的托管请求

minion向master投诚后,还需要master接受才行。这个过程叫做“授信”。

Salt底层使用公钥-私钥证书来保证通信信道的安全。具体的机制可以参考ZeroMQ的相关内容。Salt已经屏蔽了底层的细节,只需要使用封装好的命令:

# 在master上运行 # 查看所有minion salt-key -L  Accepted Keys: windows bond_app_server_main mac_os_vm salt-master Unaccepted Keys: minion1 minion2 Rejected Keys:  #其中Unaccepted Keys是未许可的minion。可以使用下面的命令通过认证: salt-key -a minion1

5. 测试

安装配置好之后,首先要测试一下联通性:salt '*' test.ping。salt会列出每个认证过的minion的联通状态(true 或 false)。

再举一些例子:

 # 查询主机运行了多长时间 sudo salt '*' cmd.run "uptime"   # 批量重启服务 salt '*' cmd.run "service httpd restart"  # 让多台机器一起,使用Apache Bench进行压力测试 salt '*' cmd.run "ab -n 10 -c 2 http://www.google.com/"

注意,默认情况下master和minion之间使用以下端口进行通信:
1. 4505(publish_port): salt的消息发布系统
2. 4506(ret_port):salt客户端与服务端通信的端口

网络的设置需要保证这些端口可以访问。

Salt的强大功能

上面的例子都是用Salt进行批量操作。但是Salt的功能不仅如此。

认真分析一下我的“非专职运维工作”的内容,发现可以分为以下三个方面:
1. 变更操作:根据需要对节点中某个资源的某种状态进行调整,并检验变更的结果
2. 配置管理:让上述行为变得“可管理”,支持“有关人士”对上述行为的标记、控制、识别、报告、跟踪和归档甚至审批和审计
3. 状态监控:随时掌握状态,发现异常。尽量在系统用户发现问题之前解决麻烦

Salt对上述三个方面提供了完美的支持,事实上,Salt提供的功能比我需要的还要多。下图是Salt的主要功能:

轻松使用SaltStack管理成千上万台服务器(入门教程)- 强大功能

如果想对Salt的功能和使用有一个初步的了解,最好参考官方文档:Salt Stack Walkthrough。

1. 批量操作(targeting)

再回顾一下上文中的例子:

 # 测试连通性 salt '*' test.ping  # 查询主机运行了多长时间 sudo salt '*' cmd.run "uptime"   # 批量重启服务 salt '*' cmd.run "service httpd restart"  # 让多台机器一起,使用Apache Bench进行压力测试 salt '*' cmd.run "ab -n 10 -c 2 http://www.google.com/"

上面的例子都是对多个节点进行批量操作:使用通配符"'*'"对所有注册的节点进行操作。Salt支持多种方式对节点id(minion id)进行匹配。包括:

默认:通配符(globbing))
* E:正则表达式(Regular Expression)
* L:列表
* N: 分组(group)
* C:复合匹配
先看一下通配符、正则表达式和列表的例子:

 # 通配符是最常用的匹配方式。Salt使用[linux风格的通配符](http://docs.python.org/2/library/fnmatch.html) salt '*' test.ping salt '*.example.net' test.ping salt '*.example.*' test.ping salt 'web?.example.net' test.ping salt 'web[1-5]' test.ping salt 'web-[x-z]' test.ping  # 正则表达式可以适应更复杂的情况。使用[python的re模块](http://docs.python.org/2/library/re.html#module-re)进行匹配 salt -E 'web1-(prod|devel)' test.ping  # 最直接的方式是自己指定多个minion,即列表 salt -L 'web1,web2,web3' test.ping

复合匹配(Compound matchers)有点复杂,后续会在其他文章中专门介绍。

2. 节点分组(nodegroups)

好吧,批量操作确实很爽。但是每次都输入匹配规则有点麻烦,对于复杂的匹配规则更是如此。 salt的 nodegroups功能可以将常用的匹配规则保存下来(称之为minion的分组)。批量操作是,只需要使用L标记指定要操作的group名字即可。 groups定义在master的配置文件/etc/salt/master中。

group 的定义可以使用各种匹配规则,比如:

group1: '[email protected], bar.domain.com,baz.domain.com or bl*.domain.com'group2: 'G@os:Debian and foo.domain.com'

3. 命令执行(execution)

Salt生来就有命令编排的功能。据说,Salt最先实现的是远程执行技术,然后才添加的配置管理功能。Salt使用ZeroMQ来处理命令执行的请求和响应消息,安装配置简单,并且性能非常高。

Salt即可以批量执行命令,也可以单机执行。通常单机执行用于测试:
1. 单机(立即)执行。 使用salt-call命令单机执行操作
2. 批量(立即)执行。最常用的操作。使用salt命令,对匹配的minion节点执行操作

Salt可以执行的命令也可以分为两种:
1. 系统命令,使用cmd.run执行
2. Salt模块,将常用的命令/批处理封装到内置的Salt模块(module),使用模块名.功能名的方式执行。

比如:


# 执行系统命令 salt '*' cmd.run 'hostname'  # 执行Salt模块 salt '*' disk.usage

使用Salt模块的好处是能够做到一致。比如同样是查看磁盘使用情况,salt '*' cmd.run "df -h"只能用于NIX节点,而salt '*' disk.usage对NIX和Windows都适用,并且采用相同结构返回数据,便于批量处理。

Salt已经内置了大量的模块,这些模块涵盖了日常管理任务的主要任务,包括:
1. 通用的管理任务,比如apt, at, cp, cron, disk, extfs, file, grains, hosts, iptables, mount, network, pam, parted, pkg, ps, selinux, shadow, ssh, test等
2. 针对特定软件的任务,比如apache, cassandra, djangomod, git, mongodb, mysql, nginx, nova, postgres, solr, sqlite3, 和tomcat

而且,自己开发Salt模块也非常简单,很容易将实际管理操作中的一些经验通过自定义的模块固化下来,并方便分享。

在开发和调试模块的时候,可以使用test=True参数进行模拟执行(Dry run)。比如:

salt 'minion1.example.com' state.highstate -v test=True

4. 节点信息(grains)

grains是Salt内置的一个非常有用的模块。在用salt进行管理客户端的时候或者写state的时候都可以引用grains的变量。

grains的基本使用举例如下:

 # 查看grains分类 salt '*' grains.ls    # 查看grains所有信息 salt '*' grains.items  # 查看grains某个信息 salt '*' grains.item osrelease

5. 配置管理(state)

配置管理是Salt中非常重要的内容之一。Salt通过内置的state模块支持配置管理所需的功能。关于这部分内容,官方文档有很详细的描述,可以参考 part 1,part 2和 part 3。

Salt中可以定义节点的目标状态,称之为state。state对应配置管理中的配置,可以对其进行标识、变更控制、变更识别、状态报告、跟踪和归档以及审计等一些的管理行为。

状态描述
Salt使用SLS文件(SaLt State file)描述状态。SLS使用YAML格式进行数据序列化,因此简单明了,可读性也很高。

基本描述(yaml)
下边是一个简单的SLS文件例子:

 apache:   pkg:     - installed   service:     - running     - require:       - pkg: apache


该文件描述一个ID为apache的配置状态:
1. 软件包(pkg)已经安装
2. 服务应该处于运行中
3. 服务的运行依赖于apache软件包的安装

state文件中的所有YAML变量名来自Salt的state模块。

Salt内置了大量的state模块,比如cron, cmd, file, group, host, mount, pkg, service, ssh_auth,user等。 详细清单参考这里。
还可以开发自己的state模块。

扩展描述(jinja)
state可以使用jinja模板引擎进行扩展,其语法可以参考这里。

下面是一个更复杂的例子:

vim:  pkg:        { % if grains['os_family'] == 'RedHat' % }     - name: vim-enhanced        { % elif grains['os'] == 'Debian' % }    - name: vim-nox        { % elif grains['os'] == 'Ubuntu' % }    - name: vim-nox        { % endif % }    - installed

    
该state增加了判断逻辑:如果是redhard系列的就安装 vim-enhanced,如果系统是Debian或者Ubuntu就安装vim-nox。

逻辑关系
state之间可以有逻辑关系。常见的关系举例如下:

1. require:依赖某个state,在运行此state前,先运行依赖的state,依赖可以有多个

 httpd:   pkg:     - installed   file.managed:     - name: /etc/httpd/conf/httpd.conf     - source: salt://httpd/httpd.conf     - require:       - pkg: httpd


watch:在某个state变化时运行此模块

redis:  pkg:    - latest  file.managed:    - source: salt://redis/redis.conf    - name: /etc/redis.conf    - require:      - pkg: redis    service.running:      - enable: True      - watch:      - file: /etc/redis.conf      - pkg: redis


watch除具备require功能外,还增了关注状态的功能

3. order:优先级比require和watch低,有order指定的state比没有order指定的优先级高

vim:  pkg.installed:    - order: 1


想让某个state最后一个运行,可以用last

保存状态
状态描述文件(SLS)要保存在master节点中,并通过指令分发到minion节点。

1. 路径设置
Salt master的配置文件(/etc/salt/master)中可以通过file_roots参数指定状态文件的保存路径。可以为不同的环境(如开发环境、UAT环境、生产环境、灾备环境等)分别指定路径,如下所示:

file_roots:  base:    - /srv/salt/  dev:    - /srv/salt/dev/services    - /srv/salt/dev/states  prod:    - /srv/salt/prod/services    - /srv/salt/prod/states


其中,base环境是必须的。

2. 入口文件
file_roots中必须指定“base”环境的路径,因为该路径中存在Salt state的入口文件: top.sls。

Top文件建立配置环境、节点和状态配置之间的映射关系。比如一个简单的top.sls文件:

base:  '*':    - serversdev:  '*nodb*':    - mongodb


该文件指定了: - 所有节点使用base环境的servers配置 - nodb节点使用dev环境的mongodb配置

结合第一部分的file_roots配置,该top配置意味存在以下的配置文件:

/srv/salt/servers.sls/srv/salt/dev/mongodb.sls


注:这里也可以使用文件夹/srv/salt/servers/和/srv/salt/dev/mongodb/,在文件夹中放置一组状态文件和配置文件,便于建立复杂的状态配置。

top.sls中的可配置内容非常丰富,具体内容可以参考官方文档。

状态生效(State Enforcement)
master上对状态进行定义,最终这些状态要传递到minion节点上。在本节的例子中,如果定义好了状态文件/srv/salt/dev/mongodb.sls:

mongodb:  pkg:    - installed


可以使用命令salt "minion1" state.highstate -v使得所有针对"minion1"的state生效;

在执行状态之前先进行测试是个好主意,需要指定参数test=True。比如,salt "minion1" state.highstate -v test=True。

关于state模块的更多用法,可以参考state模块说明,或官方文档。

更多
Salt的state模块的功能不仅如此,还可以使用模板和变量,以及定义状态的定时自动生效。

6. 小结

本文介绍Salt的主要功能和基本使用,包括minion节点的管理,批量操作,以及非常重要的配置管理。 掌握了这些内容,可以使用Salt极大提高运维的效率(事实上,Salt对于开发阶段也能提供很大的帮助,开发和运维的界限正在逐渐模糊)。

后续会介绍一些使用案例以及Salt的高级功能。

Salt state实例解析

在Salt的官方教程中,以apache和sshd的state配置作为例子。掌握这两个例子,就能够触类旁通,处理日常工作中大部分的配置管理问题。 本文对这两个例子进行详细的分析和注释。

1. 目录结构

文档 中的例子包含了多个文件。这些文件之间互相引用和关联。目录结构及文件清单如下:

  • apache/init.sls

  • apache/httpd.conf


  • ssh/init.sls


  • ssh/server.sls

  • ssh/banner

  • ssh/ssh_config

  • ssh/sshd_config

  • ssh/custom-server.sls

两个配置分别放在了apache和ssh文件夹。一个Salt状态可以使用单个的SLS文件,或者使用一个文件夹。后者更加灵活方便。

2. apache/init.sls

 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      - template: jinja      - context:        custom_var: "override"      - defaults:        custom_var: "default value"        other_var: 123

说明:
1. sls文件使用YAML格式定义,最外面的层级定义配置项。
2. 一个sls文件中可以有多个配置项,配置项的ID可以起任意的名字。本例中包含ID为apache和/etc/httpd/conf/httpd.conf两个配置项。
3. 配置项内是一系列的状态声明。所有的状态项来自Salt状态模块。即可以使用Salt内置的状态模块,也可以编写自定义的状态模块
4. 状态声明内部指定状态函数的调用。状态函数是每个Salt状态模块中定义的函数。
5. apache配置项
1) pkg模块,使用操作系统的包管理器(如yum, apt-get)安装软件包
salt.states.pkg.installed函数, 验证软件包是否安装以及是否为指定的版本
2) service模块管理服务/守护进程(daemon)的启动或停止
    salt.states.service.running函数检查服务是否已经启动
    service模块定义了salt.states.service.mod_watch函数,可以使用watch要素监控其他的模块是否满足。这里监控以下情况:
        apache软件包(pkg)是否已安装
        /etc/httpd/conf/httpd.conf文件(file)是否存在
        apache用户(user)是否存在
    user.present是简写形式,直接调用user模块的present函数检查是否存在如下属性的apache用户:
        uid=87
        gid=87
        home目录为/var/www/html
        登录脚本为/bin/nologin
        检查依赖项:apache用户组
    group.present是简写形式,直接调用group模块的present函数检查是否存在如下属性的apache用户组:
        gid=87
        检查依赖项:apache软件包
6. /etc/httpd/conf/httpd.conf配置项
file.managed是简写形式,直接调用file模块的managed方法根据需要从master获取文件并可能会通过模板系统(templating system)进行渲染。文件要满足如下要求:

  • 使用master上面的apache/httpd.conf文件

  • user=root

  • group=root

  • mode=644

  • 使用jinja模板渲染

  • 上下文变量:

  • custom_var="override"

  • 默认值:

  • custom_var="default value"

  • other_var=123

3. ssh/init.sls

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

4. ssh/server.sls

 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. include语句将别的state添加到当前文件中,使得state可以跨文件引用。
使用include相当于把被引用的内容文件添加到自身,可以require、watch或extend被引用的SLS中定义的内容。
这里引用了sshstate。
2. openssh-server配置项
3. sshd
4. /etc/ssh/sshd_config配置项
5. /etc/ssh/banner配置项

5. ssh/custom-server.sls

include:   - ssh.server  extend:   /etc/ssh/banner:     file:       - source: salt://ssh/custom-banner

说明:
1. 引用sshstate的server配置项
2. extend可以复用已有的state,在原来的基础上进行扩展,增加新的配置或修改已有的配置。
    将/etc/ssh/banner配置项的文件修改为salt://ssh/custom-banner


你可能感兴趣的:(入门,管理,服务器,saltstack,千,万)