STATES TUTORIAL - SaltStack STATES使用教程

STATES TUTORIAL - STATES使用教程

或者您也可以参考在GitHub上相同的另一份资料:States-tutorial

PART 1 - BASIC USAGE

第一部分:基本用法

本教程的目的是演示如何快速配置由Salt States管理的系统。 有关状态系统的详细信息,请参阅完整的状态参考

本教程将引导您使用Salt配置minion以运行Apache HTTP服务器并确保服务器正在运行。

在继续之前,请先按照安装配置文档的说明确保您已正确安装Salt。

卡住了?

有很多方法可以从Salt社区获得帮助,包括我们的邮件列表和我们的IRC频道#salt。

SETTING UP THE SALT STATE TREE - 配置和启用Salt State Tree

States状态存储在master上的文本文件中,并通过master文件服务器按需传送到minions。 状态文件的集合即构成State Tree

要在Salt中开始使用集中式的状态系统,必须首先设置Salt File Server。 编辑master配置文件(file_roots)并取消以下行的注释:

file_roots:
  base:
    - /srv/salt

注:如果你通过ports在FreeBSD上部署,则file_roots路径默认为/usr/local/etc/salt/states

重新启动Salt master以使变更生效:

pkill salt-master
salt-master -d

PREPARING THE TOP FILE - 准备top file文件

在master上,在上一步中取消注释的目录(默认情况下为/srv/salt)中,创建一个名为top.sls的新文件并添加以下内容:

base:
  '*':
    - webserver

top file文件被划分为多个不同的环境(稍后讨论)。 默认环境是base。 在base环境下,定义了一系列minion匹配映射关系; 现在只需简单的指定为所有主机(*)。

Targeting minions

表达式可以使用Salt使用的任何目标定位机制。minions可以通过glob、PCRE正则表达式或者grains来匹配。 例如:

base:
 'os:Fedora':
   - match: grain
   - webserver

CREATE AN SLS FILE - 创建一个sls文件

在和 top file 文件同一个目录中, 创建一个名为 webserver.sls 的文件, 包含以下内容:

apache:                 # ID declaration
  pkg:                  # state declaration
    - installed         # function declaration

第一行称为ID声明,可以是一个任意标识符。 在上面的这种情况下,它定义了要安装的包的名称。

注:Apache httpd Web服务器的软件包名称可能因操作系统或发行版而异 - 例如,在Fedora上它是httpd,但在Debian/Ubuntu上它是apache2。

第二行称为state声明,它定义了我们正在使用哪些Salt States。 在此示例中,我们使用pkg state来确保安装了给定的包。

第三行称为Function声明,它定义了在pkg state模块中要调用的函数。

Renderers:渲染器

States sls文件可以用多种格式编写。 Salt只需要一个简单的数据结构,而不关心如何构建数据结构。 模板语言和DSL是一个简单而灵活的实现,每个人都喜欢。

构建预期的数据结构是Salt Renderers的工作,它们写起来很简单。

在本教程中,我们将在Jinja2模板中使用YAML,这是Salt的默认格式。 你可以通过在Master配置文件中编辑渲染器来更改默认值。

INSTALL THE PACKAGE - 安装软件包

接下来,让我们运行我们创建的状态文件。 在master服务器上打开终端并运行:

salt '*' state.apply

我们的Master指示所有目标minions运行state.apply。 在没有任何SLS目标的情况下执行此功能时,minion将下载top file文件并尝试匹配其中的表达式。 当minion与表达式匹配时,将为其列出的模块下载、编译和执行。

注意:上面的操作又称为“highstate”,也可以使用state.highstate函数运行。 但是,为了使用更容易理解(“highstate”不一定是直观的名称),在2015.5.0版本中添加了state.apply函数,在没有任何SLS名称的情况下调用时就会触发highstate。 state.highstate仍然保留且可以使用,但文档(如上所示)已更新为引用state.applystate.apply相当于是一个别名,在不同情况下会调用不同的state函数命令。因此在阅读文档时请记住以下内容:

  • 在没有指定任何SLS文件名称的情况下调用state.apply的效果相当于运行state.highstate
  • 在指定了SLS文件名称的情况下调用的state.apply将运行state.sls

命令执行完成后,minion将报告所有采取的行动和做的所有更改的摘要。

Warning

如果你创建了自定义的grain模块,则在执了第一次highstate命令之前,它们都将无法在top file文件中使用。 为了及时在minion的第一个highstate操作上提供custom grains数据,建议使用此示例以确保在minion启动时可以自动同步自定义grains数据。

SLS File Namespace

请注意,在上面的示例中,SLS文件webserver.sls简称为webserver。 在top.sls或Include声明中引用时,SLS文件的命名空间遵循一些简单的规则:

  1. .sls 的后缀被丢弃了 (也就是说 webserver.sls 变成了 webserver).
  2. 子目录被做了更好的组织,其中:
  • 每个子目录在Salt状态和命令行中用点(遵循Python导入模型)表示。 文件系统上的webserver/dev.sls,在Salt中称为webserver.dev
  • 由于斜杠表示为点,因此SLS文件不能在名称中包含点(SLS文件后缀的点除外)。 你将无法正确匹配SLS文件webserver_1.0.sls,因为webserver_1.0将与目录/webserver_1/0.sls匹配
  1. 子目录中名为init.sls的文件将通过目录的路径引用。 因此,webserver/init.sls称作webserver

  2. 如果webserver.slswebserver/init.sls都存在,webserver/init.sls将被忽略,webserver.sls将被作为合法的webserver使用。

Troubleshooting Salt

如果未看到预期的输出,以下提示可帮助缩小问题分析范围。

  1. Turn up logging - 打开日志输出

将日志记录设置更改为debug时,Salt可能会输出很繁琐的信息:

salt-minion -l debug
  1. Run the minion in the foreground - 在前台运行minion程序

通过不以守护进程模式启动minion(-d),也可以查看到minion的所有输出:

salt-minion
  1. 运行salt时增加默认超时值。 例如,将默认超时更改为60秒
salt -t 60

为了得到最好的效果,结合使用以上三个方法:

salt-minion -l debug        # On the minion
salt '*' state.apply -t 60  # On the master

NEXT STEPS

本教程重点介绍如何使用简单的Salt States配置。 第2部分将基于此示例构建,以涵盖更高级的sls语法,并将探索更多与Salt一起提供的状态。

PART 2 - MORE COMPLEX STATES AND REQUISITES

第二部分:更复杂的STATES、REQUISITES

注意:本教程章节是以第1部分中介绍的主题为基础。建议您从那里开始阅读。

在Salt States教程的前一部分中,我们介绍了安装软件包的基础知识。 我们现在将修改我们的webserver.sls文件以满足使用要求,并使用更多的Salt状态配置方法。

CALL MULTIPLE STATES

你可以在ID声明下指定多个State声明。 例如,快速修改我们的webserver.sls,检查如果Apache服务没有运行,则启动Apache:

apache:
  pkg.installed: []
  service.running:
    - require:
      - pkg: apache

在运行state.apply之前停止Apache并观察输出,再次运行并观察。

注意:对于那些运行Redhat OS衍生产品(Centos,AWS)的人,你需要将服务名称指定为httpd。 更多关于state service的知识参考这里。 使用上面的示例,只需在require行上方添加 "- name: httpd"并使用相同的间距。

REQUIRE OTHER STATES

我们现在有了一个Apache的安装任务,所以让我们添加一个HTML文件来定制我们的网站。 拥有一个没有网络服务器的网站并不是很有用所以我们不希望Salt在安装和运行Apache之前部署我们的HTML文件。 在webserver/init.sls文件的底部包含以下内容:

apache:
  pkg.installed: []
  service.running:
    - require:
      - pkg: apache

/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

第7行ID 声明。在此示例中,它是我们要安装自定义HTML文件的位置。 (注意:Apache提供的默认位置可能与您的操作系统或发行版上的上述不同./srv/www也可能是一个值得关注的地方。)

第8行state声明。 此示例使用的是Salt file state

第9行Function声明managed function将从master服务器下载文件并将其安装在指定的位置。

第10行 是一个Function arg的声明,在本例中,它将source参数传递给managed函数。

第11行Requisite的声明

第12行Requisite的参数,它指向了一个state和一个ID。 在这个例子中,它引用了我们在第1部分中的示例中的ID声明。该声明告诉Salt在安装Apache服务之前不要安装HTML文件。

接下为, 创建 index.html 文件并把它保存在 webserver 目录中:

<!DOCTYPE html>
<html>
    <head><title>Salt rocks</title></head>
    <body>
        <h1>This file brought to you by Salt</h1>
    </body>
</html>

最后, 再次调用state.apply,minion将从master获取数据并执行highstate,以及从Salt的文件服务器获取我们的HTML文件:

salt '*' state.apply

检查一下Apache是否可以正确地为我们自定义的HTML网页提供服务。

require vs. watch

有两个Requisite declaration,“require”和“watch”。 并非每个state都支持“watch”。 service state支持“watch”,并可以根据监视条件重新启动服务。

例如,如果您使用Salt安装Apache虚拟主机配置文件并希望在更改该文件时重新启动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

如果您的操作系统或发行版的pkg和服务名称不同,您可以使用第3部分中说明的Name declaration单独指定每个名称。

NEXT STEPS

在第3部分中,我们将讨论如何使用includes、extends和templating来创建更完整的状态树配置。

PART 3 - TEMPLATING AND INCLUDES AND EXTENDS

第三部分:模板、包含和扩展

注意:这一章节的教程是在前面两部分主题内容的基础上进行的,建议从那里开始阅读。

本教程的这一部分将介绍sls文件的更高级模板和配置技术。

TEMPLATING SLS MODULES

在处理复杂业务逻辑时,SLS模块可能需要编程逻辑或内联执行。 这是通过模块模板实现的。 使用的默认模块模板系统是Jinja2,这可以通过更改master配置中的renderer值来配置。

所有状态在最初读取时都通过模板系统。 要使用模板系统,只需添加一些模板标记即可。 带模板标记的sls模块的示例可能如下所示:

{% for usr in ['moe','larry','curly'] %}
{{ usr }}:
  user.present
{% endfor %}

这个模板化的sls文件一旦生成将如下所示:

moe:
  user.present
larry:
  user.present
curly:
  user.present

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

# Comments in yaml start with a hash symbol.
# Since jinja rendering occurs before yaml parsing, if you want to include jinja
# in the comments you may need to escape them using 'jinja' comments to prevent
# jinja from trying to render something which is not well-defined jinja.
# e.g.
# {# iterate over the Three Stooges using a {% for %}..{% endfor %} loop
# with the iterator variable {{ usr }} becoming the state ID. #}
{% for usr in 'moe','larry','curly' %}
{{ usr }}:
  group:
    - present
  user:
    - present
    - gid_from_name: True
    - require:
      - group: {{ usr }}
{% endfor %}

USING GRAINS IN SLS MODULES - 在SLS模块中使用grains

通常情况下,state状态需要在不同系统上表现不同的行为。 Salt grains对象在模板上下文中可以使用。 在sls模块中使用grains:

apache:
  pkg.installed:
    {% if grains['os'] == 'RedHat' %}
    - name: httpd
    {% elif grains['os'] == 'Ubuntu' %}
    - name: apache2
    {% endif %}

USING ENVIRONMENT VARIABLES IN SLS MODULES - 在SLS模块中使用环境变量

你可以使用 salt['environ.get']('VARNAME') 的方式在一个Salt state中使用环境变量参数。

MYENVVAR="world" salt-call state.template test.sls
Create a file with contents from an environment variable:
  file.managed:
    - name: /tmp/hello
    - contents: {{ salt['environ.get']('MYENVVAR') }}

带错误检测的配置方法:

{% set myenvvar = salt['environ.get']('MYENVVAR') %}
{% if myenvvar %}

Create a file with contents from an environment variable:
  file.managed:
    - name: /tmp/hello
    - contents: {{ salt['environ.get']('MYENVVAR') }}

{% else %}

Fail - no environment passed in:
  test.fail_without_changes

{% endif %}

CALLING SALT MODULES FROM TEMPLATES - 在模板中调用Salt模块的方法

由minion加载的所有Salt模块都可在模板系统中使用。 这允许在目标系统上实时收集数据。 它还允许从sls模块中轻松运行shell命令。

Salt模块函数也可以在模板上下文中以salt:形式提供。

以下示例说明中使用名为some_group_that_exists的单个位置参数调用文件执行模块中的group_to_gid函数。

moe:
  user.present:
    - gid: {{ salt['file.group_to_gid']('some_group_that_exists') }}

考虑这种情况的一种方法可能是为gid键分配了一个等价于以下python伪代码的值:

import salt.modules.file
file.group_to_gid('some_group_that_exists')

请注意,要使上述示例起作用,在模板引擎处理状态文件之前,some_group_that_exists必须是存在的。

下面是一个使用network.hw_addr函数检索eth0的MAC地址的示例:

salt['network.hw_addr']('eth0')

要检查每个执行模块函数的可以使用的参数,可以检查模块参考文档

ADVANCED SLS MODULE SYNTAX - 高级SLS模块语法

最后,我们将介绍一些非常有用的技术,用于更复杂的状态树。

INCLUDE DECLARATION

前面的示例演示了如何在多个文件中构建Salt树。 同样的,Requisites and Other Global State Arguments可以使用Include declaration跨越多个文件。 例如:

python/python-libs.sls:

python-dateutil:
  pkg.installed

python/django.sls:

include:
  - python.python-libs

django:
  pkg.installed:
    - require:
      - pkg: python-dateutil
EXTEND DECLARATION

您可以使用Extend声明修改以前的声明。 例如,以下内容修改了Apache状态树,以便在更改vhosts文件时重新启动Apache:

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

Using extend with require or watch

extend语句对requirewatch的工作方式不同。 它是附加,而不是替换requiste的组件。

NAME DECLARATION

你可以使用Name声明覆盖ID声明。 例如,如果像下面这样重写,前面的示例会更易于维护:

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
NAMES DECLARATION

更强大的是使用Names声明一次覆盖多个状态的ID声明。 这通常可以消除模板中循环的需要。 例如,本教程中的第一个示例可以在没有循环的情况下重写:

stooges:
  user.present:
    - names:
      - moe
      - larry
      - curly

NEXT STEPS

在第4部分中,我们将讨论如何使用salt的file_roots来设置一个工作流,在该工作流中,状态可以从开发、QA到生产依次“升级”。

PART 4 - Set Up a Workflow by Salt states

第四部分:使用salt的file_roots来设置一个工作流,在该工作流中,状态可以从开发、QA到生产依次“升级”。

注意:这一章节的教程是在前面三部分主题内容的基础上进行的,建议从那里开始阅读。

SALT FILESERVER PATH INHERITANCE - Salt文件服务器的路径继承关系

Salt的文件服务器允许每个环境拥有多个根目录,如下例所示,它使用本地目录和通过NFS共享给salt master服务器的第二个目录:

# In the master config file (/etc/salt/master)
file_roots:
  base:
    - /srv/salt
    - /mnt/salt-nfs/base

Salt的文件服务器会将根目录的列表合并到包含每个根的所有文件的单个虚拟环境中。 如果同一文件存在于多个根目录中的相同相对路径中,则最顶部先匹配上的“胜出”。 例如,如果/srv/salt/foo.txt/mnt/salt-nfs/base/foo.txt都存在,那么salt://foo.txt将指向/srv/salt/foo.txt

注意:使用多个文件服务器后端时,它们在fileserver_backend参数中列出的顺序也很重要。 如果rootsgit后端包含一个具有相同相对路径的文件,并且’roots’目录出现在fileserver_backend列表中的git之前,那么roots中的文件将“win”,并且gitfs中的文件将被忽略。

有关Salt的模块化文件服务器如何工作的更全面的解释可以在这里找到。 我们建议阅读此内容。

ENVIRONMENT CONFIGURATION - 环境配置

一个多环境的文件服务后端配置会像下面这样:

file_roots:
  base:
    - /srv/salt/prod
  qa:
    - /srv/salt/qa
    - /srv/salt/prod
  dev:
    - /srv/salt/dev
    - /srv/salt/qa
    - /srv/salt/prod

鉴于上述路径继承关系,/srv/salt/prod中的文件将在所有环境中可用。 /srv/salt/qa中的文件可以在qadev中使用。 最后,/srv/salt/dev中的文件只能在dev环境中使用。

根据定义roots的顺序,可以将新files/states放在/srv/salt/dev中,然后推送到开发主机进行测试。

然后可以将这些files/states移动到/srv/salt/qa中的相同相对路径,它们现在可以在devqa环境中使用,允许它们被推送到QA主机并进行测试。

最后,如果移动到/srv/salt/prod中的相同相对路径,则文件现在可在所有三种环境中使用。

REQUESTING FILES FROM SPECIFIC FILESERVER ENVIRONMENTS - 从特定的FILESERVER环境中请求文件

有关如何从特定环境请求文件的文档,请参见此处

PRACTICAL EXAMPLE - 一个实际的例子

例如,考虑一个安装到/var/www/foobarcom的简单网站。 以下是可用于部署网站的top.sls:

/srv/salt/prod/top.sls:

base:
  'web*prod*':
    - webserver.foobarcom
qa:
  'web*qa*':
    - webserver.foobarcom
dev:
  'web*dev*':
    - webserver.foobarcom

使用pillar, 为各主机指定角色:

/srv/pillar/top.sls:

base:
  'web*prod*':
    - webserver.prod
  'web*qa*':
    - webserver.qa
  'web*dev*':
    - webserver.dev

/srv/pillar/webserver/prod.sls:

webserver_role: prod

/srv/pillar/webserver/qa.sls:

webserver_role: qa

/srv/pillar/webserver/dev.sls:

webserver_role: dev

最后, 定义一个SLS,用于部署website。

/srv/salt/prod/webserver/foobarcom.sls:

{% if pillar.get('webserver_role', '') %}
/var/www/foobarcom:
  file.recurse:
    - source: salt://webserver/src/foobarcom
    - env: {{ pillar['webserver_role'] }}
    - user: www
    - group: www
    - dir_mode: 755
    - file_mode: 644
{% endif %}

鉴于上述SLS,网站的源文件最初应放在/srv/salt/dev/webserver/src/foobarcom中。

首先,让我们部署到dev。 鉴于top file文件中的配置,可以使用state.apply完成:

salt --pillar 'webserver_role:dev' state.apply

但是,如果不希望应用top file文件中配置的所有状态(可能在更复杂的设置中),则可以通过调用state.apply来仅应用为foobarcom网站定义的配置状态。 将期望的SLS目标作为参数:

salt --pillar 'webserver_role:dev' state.apply webserver.foobarcom

一旦站点通过了dev环境中的测试,就可以将文件从/srv/salt/dev/webserver/src/foobarcom移动到/srv/salt/qa/webserver/src/foobarcom,并使用以下命令进行部署:

salt --pillar 'webserver_role:qa' state.apply webserver.foobarcom

最后,一旦站点在qa中通过了测试,那么文件可以从/srv/salt/qa/webserver/src/foobarcom移动到/srv/salt/prod/webserver/src/foobarcom,并使用以下内容进行部署:

salt --pillar 'webserver_role:prod' state.apply webserver.foobarcom

感谢Salt的文件服务器继承功能,即使文件已经移动到/srv/salt/prod中,它们仍然可以在qadev环境中使用相同的salt://URI。

CONTINUE LEARNING

继续学习Salt States的最佳方法是阅读参考文档并查看现有状态树的示例。 许多预先配置的状态树可以在GitHub上saltstack-formula集合的存储库的中找到。

如果你有任何问题、建议或只是想与使用Salt的其他人聊天,我们有一个非常活跃的社区,我们很乐意听取您的意见。

此外,通过继续阅读Orchestrate Runner文档,你可以了解Salt所具备的强大的编排功能。

PART 5 - ORCHESTRATION WITH SALT

第五部分:使用Salt进行服务编排

这个部分的内容已经整合到了 Orchestrate Runner 中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值