注:本模块的内容是根据官方v2018.3.0版本的英文资料翻译得到。
Salt带有一个简单的文件服务器,可以将文件分发给Salt Minion。 文件服务器是内置于Salt主机中的无状态ZeroMQ服务器。
Salt文件服务器的主要目的是管理在Salt状态系统中使用的文件。 这就是说,Salt文件服务器可以用于任何从Master到Minions的一般文件传输。
1、 文件服务器后端
在Salt 0.12.0中,引入了模块化文件服务器。 此功能为Salt Master添加了集成不同文件服务器后端的功能。 文件服务器后端允许Salt文件服务器充当外部资源的透明桥梁。 一个很好的例子就是git后端,它允许Salt提供源自一个或多个git存储库的文件,但也有几个其他可选的后端。 点击这里查看Salt的文件服务器后端的完整列表。
启用一个文件服务器后端 Enabling a Fileserver Backend
可以使用fileserver_backend选项启用文件服务器后端。
fileserver_backend:
- git
请参阅每个后端的文档以找到要添加到fileserver_backend的正确值以启用它们。
使用多个文件服务器后端 Using Multiple Backends
如果在主配置文件中未定义fileserver_backend,则Salt将使用roots后端,但fileserver_backend选项支持多个后端。 当使用多个后端时,来自启用后端的文件将合并到单个虚拟文件系统中。 当一个文件被请求时,将在所有后端中搜索该文件,并且匹配的第一个后端将是返回该文件的那个后端。
fileserver_backend:
- roots
- git
使用此配置,将首先搜索file_roots参数中定义的环境和文件,如果未找到该文件,则会搜索gitfs_remotes中定义的git存储库。
定义环境变量 Defining Environments
正如fileserver_backend中的值的顺序很重要一样,在文件服务器环境中定义不同源的顺序也是如此。 例如,如果在下面的file_roots配置中,如果主服务器上存在/srv/salt/dev/foo.txt和/srv/salt/prod/foo.txt,则在dev环境中salt://foo.txt将指向/srv/salt/dev/foo.txt,在base环境中指向/srv/salt/prod/foo.txt。
file_roots:
base:
- /srv/salt/prod
qa:
- /srv/salt/qa
- /srv/salt/prod
dev:
- /srv/salt/dev
- /srv/salt/qa
- /srv/salt/prod
同样,当使用git后端时,如果下面定义的两个存储库都有一个hotfix23 brahch/tag,并且它们还包含该brahch/tag的存储库根目录中的文件bar.txt,则hotfix23环境中的salt://bar.txt将由第一个存储库提供。
gitfs_remotes:
- https://mydomain.tld/repos/first.git
- https://mydomain.tld/repos/second.git
注意:根据文件服务器后端的不同,所支持的环境变量映射也不同。 例如,在roots backend中是显示定义了的,而在VCS后端(git,hg,svn)中,环境变量映射是根据分支/标记/书签/等创建的。 对于minion后端,这些文件全部位于由minionfs_env选项指定的单个环境中。
请参阅每个后端的文档,以获取有关如何映射环境的更详细说明。
2、 动态模块分发
New in version 0.9.5.
自定义的Salt execution、state和其他模块可以使用Salt文件服务器分发给Salt minions。
任何环境的,在通过Master服务器上的file_roots选项定义的根目录下,都可以使用与模块类型相对应的目录。
这些目录前面加了一个下划线:
- _beacons
- _clouds
- _engines
- _grains
- _modules
- _output
- _proxy
- _renderers
- _returners
- _states
- _tops
- _utils
这些目录中的内容需要在创建Python模块后同步到minions中。 有许多方法可以同步模块。
Sync Via States
minion配置中包含一个选项autoload_dynamic_modules,其默认值为True。 该选项使状态系统在运行状态时刷新所有动态模块。 要禁用此行为,请在minion配置中将autoload_dynamic_modules设置为False。
当动态模块通过状态自动加载时,只下载与Master的top.sls文件中匹配的环境相关的模块。这一点很重要,因为在执行状态运行时,模块可以从任何特定环境手动加载,环境特定模块将会在state状态同步时被加载。
Sync Via the saltutil Module
saltutil模块具有许多可用于同步所有或特定动态模块的功能。 saltutil模块函数saltutil.sync_all将所有类型模块同步到一个minion。 有关更多信息,请参阅:salt.modules.saltutil
3、 从特定环境获取文件
Salt文件服务器支持多种环境,允许将SLS文件和其他文件进行隔离以实现更好的组织。对于默认后端(称为roots),使用roots选项定义环境。 其他后端(如gitfs)以自己的方式定义环境。 有关可用文件服务器后端的列表,请参见此处。
Querystring Syntax
任何salt://file URL都可以使用一个查询字符串语法指定其文件服务器环境,如下所示:
salt://path/to/file?saltenv=foo
在Reactor配置中,必须使用此方法从base以外的环境中提取文件。
In States
可以指示Minions在全局范围内使用哪种环境,也可以仅为单个状态使用,并且支持使用多种方法:
Globally
可以使用minion配置文件中的environment选项将minion关联到指定环境中。另外,环境也可以设置为仅为以下功能提供单个调用的支持:
注意:当使用saltenv参数来使用state.apply或state.highstate来触发highstate时,将只应用来自该环境的状态。
On a Per-State Basis
在单个State内,有两种方式来指定其生效的环境。 首先是向该State添加saltenv参数。 这个例子将从config环境中提取文件:
/etc/foo/bar.conf:
file.managed:
- source: salt://foo/bar.conf
- user: foo
- mode: 600
- saltenv: config
做同样事情的另一种方法是使用上述的查询字符串语法:
/etc/foo/bar.conf:
file.managed:
- source: salt://foo/bar.conf?saltenv=config
- user: foo
- mode: 600
注意:只有在一个环境中的state需要从另一个环境访问文件的情况下,才需要使用上述任一方法来指定环境。 如果包含此state的SLS文件位于config环境中,则默认情况下它就将在该环境中查找。
4、文件服务器配置
Salt文件服务器是用ZeroMQ编写的高性能文件服务器。 它可以快速管理大型文件,而且开销很小,并且已经过优化,能够以非常高效的方式处理小文件。
Salt文件服务器还是一个环境感知的文件服务器。 这意味着可以在许多根目录中分发文件,并通过指定要搜索的文件路径和环境进行访问。 各个环境可跨越多个roots目录以创建叠加层,并允许以许多灵活的方式组织文件。
环境Environments
Salt文件服务器默认为强制使用base环境。 这个环境必须被定义,并且在没有指定环境时用于下载文件。
环境允许文件和sls数据在逻辑上分开,但环境并不是彼此隔离的。 这允许工程师使用Salt进行环境的逻辑隔离,但也允许在多个环境中使用相同的信息。
目录覆盖Directory Overlay
环境的设置就是定义一个用于发布文件的目录列表。 搜索这些目录以查找指定的文件并返回找到的第一个文件。
这意味着根据目录数据的排列顺序对目录数据进行优先级排序。 在下面这个file_roots配置的情况下:
file_roots:
base:
- /srv/salt/base
- /srv/salt/failover
如果文件的URI是salt://httpd/httpd.conf,它将首先在/srv/salt/base/httpd/httpd.conf中搜索该文件。 如果找到该文件,它将被返回。 如果在那里找不到文件,那么/srv/salt/failover/httpd/httpd.conf将用于提供该文件。
这允许根据目录在配置中定义的顺序来覆盖配置和设定目录优先级。
也可以有支持多种环境的file_roots:
file_roots:
base:
- /srv/salt/base
dev:
- /srv/salt/dev
- /srv/salt/base
prod:
- /srv/salt/prod
- /srv/salt/base
这个示例中确保每个环境都会按目录优先级检查关联的环境目录中的文件。 如果在相应的目录中找不到文件,系统将默认使用base目录。
本地文件服务器Local File Server
New in version 0.9.8.
文件服务器可以被指向以从minion上运行。 这主要是为了在没有Salt Master的情况下运行Salt State功能。 要使用minion的本地文件服务器接口,请先将文件服务器的数据复制到minion上面,并在minion上设置file_roots选项以指向原来从Master节点复制的目录。 一旦设置了minion file_roots选项,请将file_client选项更改为local,以确保使用本地文件服务器接口。
5、 cp模块
cp模块是minion文件服务器操作的家目录。 cp模块由Salt state系统、salt-cp所使用,还可用于分发Salt文件服务器提供的文件。
转义特殊字符Escaping Special Characters
Salt://url格式可能包含查询字符串,例如salt://dir/file.txt?saltenv=base。 你可以禁止fileclient/fileserver将?解释为查询字符串的初始标记,方法是使用salt://| 引用该文件 而不是salt://。
/etc/marathon/conf/?checkpoint:
file.managed:
- source: salt://|hw/config/?checkpoint
- makedirs: True
环境Environments
由于文件服务器与Salt状态系统配合使用,因此它支持环境。 环境在Master配置文件中定义,并且在引用环境时,指定的文件将基于环境的根目录。
get_file
可以使用cp.get_file函数从Master下载文件,语法如下所示:
# salt '*' cp.get_file salt://vimrc /etc/vimrc
这将指示所有Salt Minions下载vimrc文件并将其复制到/etc/vimrc中 。
可以在源文件名和目标文件名上使用用模板渲染语法,如下所示:
# salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja
这个例子将指示所有的Salt Minions从一个与他们的OS grain同名的目录下载vimrc,并将它复制到/etc/vimrc。
对于较大的文件,cp.get_file模块还支持gzip压缩。 因为gzip是CPU密集型的,所以只适于在文件压缩率非常高的情况下使用(例如JSON或YAML文件)。
要使用压缩,请使用gzip参数。 有效值是从1到9的整数,其中1是最轻的压缩,9是最重的。 换句话说,1使用最少的CPU在Master(和Minion),而9使用的最多。
# salt '*' cp.get_file salt://vimrc /etc/vimrc gzip=5
最后,请注意,默认情况下,如果目标目录不存在,cp.get_file不会创建新的。 要改变这一点,请使用makedirs参数:
# salt '*' cp.get_file salt://vimrc /etc/vim/vimrc makedirs=True
在这个例子中,如果/etc/vim/不存在,它将被创建。
get_dir
可以使用cp.get_dir函数从Master下载整个目录。 该语法与get_file非常相似:
# salt '*' cp.get_dir salt://etc/apache2 /etc
cp.get_dir支持模板渲染和gzip压缩参数,就像get_file一样:
# salt '*' cp.get_dir salt://etc/{{pillar.webserver}} /etc gzip=5 template=jinja
6、 文件服务器客户端实例
一般来说是通过命令行方式使用cp.get_file,数据通信方向是从Master主动推送文件到Minon。这里还有另外一种pull的文件分发方式。在Minion上有一个文件服务器客户端实例可以使用,它允许编写使用Salt文件服务器的模块和应用程序。这样就把文件分发方式改为了Minion的主动拉取了。而文件服务器使用与Salt系统其余部分相同的认证和加密方法进行网络通信。
fileclient模块 fileclient Module
salt/fileclient.py模块用于设置从Minion到Master的通信。 在使用fileclient模块创建客户端实例时,需要传入minion配置。在minion模块内使用fileclient模块时,可以使用__opts__传递内置的数据:
import salt.minion
import salt.fileclient
def get_file(path, dest, saltenv='base'):
'''Used to get a single file from the Salt master
CLI Example: salt '*' cp.get_file salt://vimrc /etc/vimrc '''
# Get the fileclient object
client = salt.fileclient.get_file_client(__opts__)
# Call get_file
return client.get_file(path, dest, False, saltenv)
在minion模块外部创建fileclient实例,此时__opts__数据不可用,所以需要主动生成它:
import salt.fileclient
import salt.config
def get_file(path, dest, saltenv='base'):
'''Used to get a single file from the Salt master '''
# Get the configuration data
opts = salt.config.minion_config('/etc/salt/minion')
# Get the fileclient object
client = salt.fileclient.get_file_client(opts)
# Call get_file
return client.get_file(path, dest, False, saltenv)