Salt附带了一个简单的文件服务器,用于将文件分发给Salt minions。 文件服务器是内置在Salt master服务器中的一个无状态ZeroMQ服务器。
Salt文件服务器的主要目的是提供在Salt状态系统中使用的文件。 Salt文件服务器可用于从master服务器到minions的任何常规文件传输。
关于Salt File Server配置说明,也可以浏览Github上的这份资料:SALT FILE SERVER
在Salt 0.12.0中,引入了模块化的文件服务器。 此功能提供了Salt Master集成不同文件服务器后端的能力。 文件服务器端允许Salt文件服务器充当外部资源的透明桥梁。 一个很好的例子是git后端服务,它允许Salt来用来自一个或多个git存储库的文件,此外也有其他可用的后端服务软件。 单击此处获取Salt的文件服务器后端的完整列表。
通过fileserver_backend选项启用文件服务器后端。
fileserver_backend:
- git
请参阅每个后端服务模块的说明文档,以找到配置fileserver_backend所需的正确值。
如果未在master配置文件中定义fileserver_backend
,则Salt将使用roots
后端。fileserver_backend
选项支持同时使用多个后端的文件服务。 当使用多个后端时,来自多个已启用的后端服务的文件将合并到单个虚拟文件系统中。 在请求文件时,将搜索该虚拟服务后端以便查找该文件,并且将使用第一个符合匹配规则的后端服务上的文件。
fileserver_backend:
- roots
- git
使用此配置,将首先搜索file_roots参数中定义的环境和文件,如果找不到该文件,则将搜索gitfs_remotes中定义的git存储库。
正如fileserver_backend
中值的顺序一样,在文件服务器的环境中定义多个服务源时使用的顺序也很重要。 例如,给定以下file_roots
配置,如果master服务器上存在/srv/salt/dev/foo.txt
和/srv/salt/prod/foo.txt
,则salt://foo.txt
文件资源将指向dev
环境中的/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
分支/标记,并且它们都包含该分支/标记的存储库根目录中的文件bar.txt
,那么在访问hotfix23环境中的salt://bar.txt
文件时将会由first
存储库提供。
gitfs_remotes:
- https://mydomain.tld/repos/first.git
- https://mydomain.tld/repos/second.git
注意:环境根据文件服务器后端类型以不同方式映射。 例如,在
roots
后端中是显式定义的,而在VCS后端(git,hg,svn)中,环境是依据branches/tags/bookmarks/
等创建的。 对于minion后端则是一个特例,文件都存放在单个环境中,由minionfs_env选项指定。
有关如何管理环境的映射关系的更详细说明,请参阅每个后端服务模块的文档。
Salt文件服务器支持多种环境,允许隔离SLS文件和其他文件以便更好地组织。
对于默认后端(称为roots
),使用roots选项定义环境。 其他后端(例如gitfs)是以自己的方式定义环境。 可用的文件服务器后端的列表,请参见此处。
任何 salt:// 文件URL都可以使用查询字符串的语法指定其文件服务器环境, 例如:
salt://path/to/file?saltenv=foo
在Reactor配置中,必须使用此方法才能从base以外的环境中提取文件。
可以设定Minions在全局和单个state状态下使用哪个环境,有多种设置方法:
GLOBALLY
可以通过minion配置文件中的environment
选项将minion全局性的锁定到固定的环境中。
此外,可以还可以在以下函数模块中单独指定需要使用的salt环境:
注意:当saltenv参数用于使用state.apply或state.highstate触发highstate的场景时,将仅会应用来自该环境的状态。
ON A PER-STATE BASIS
在单个状态中,有两种指定环境的方法。 第一个是向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状态需要从另一个环境访问文件时,才需要使用上述任一方法指定环境。 如果包含此状态的SLS文件位于
config
环境中,则默认情况下它将在该环境中查找。
Salt文件服务器是用ZeroMQ编写的一个高性能文件服务器。 它可以快速管理很多大文件,而开销很小,因为经过优化,所以也可以非常有效地处理小文件。
Salt文件服务器是一个支持多环境的文件服务器。 这意味着可以把文件分别存放于根目录下的不同目录中,然后通过指定文件路径和要搜索的环境来访问这些文件。 各个环境可以跨多个目录根来进行叠加,允许以多种灵活的方式组织文件。
Salt文件服务器默认为强制使用base
环境。 必须定义此环境,并在未指定环境时用于处理文件下载。
环境允许文件和sls数据在逻辑上分开,但环境间不会相互隔离。 这允许工程师使用Salt对环境进行逻辑隔离,但也允许在多个环境中共享信息。
环境设置是一组要从中获取发布文件的目录列表。 搜索这些目录以查找指定的文件并返回找到的第一个文件。
这意味着目录数据的优先级取决于它们的列出顺序。 在下面的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
目录。
New in version 0.9.8.
可以对文件服务器的访问路由进行设置,以从minion运行。 这主要是为了在没有Salt master的情况下运行Salt状态。 要使用minion本地文件服务器接口,请将文件服务器数据复制到minion,并将minion上的file_roots
选项设置为指向存放了从master服务器复制的数据的目录。 一旦设置了minion的 file_roots
选项,将file_client
选项更改为local以确保使用本地文件服务器接口。
cp模块的主要功能是管理文件服务器对minion侧的文件的各种操作。 cp模块由Salt state系统和salt-cp调用,可用于分发Salt文件服务器提供的文件。
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
由于文件服务器可以与Salt状态系统一起使用,因此它也支持salt 环境。 环境是在master配置文件中定义的,在引用环境时,将基于环境所定义的根目录查找需要的文件。
cp.get_file
函数用于minion从master下载文件,语法是:
# salt '*' cp.get_file salt://vimrc /etc/vimrc
该命令将指示所有的minions去从master上下载 vimrc 文件,并且复制到自己的 /etc/vimrc 。
在源和目的的定义中均可以使用模板渲染语法:
# salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja
在这个示例中,minions将根据{{grains.os}}
值去下载自己适用的 vimrc 文件并复制到本地的 /etc/vimrc 。
对于较大的文件,cp.get_file模块支持gzip压缩。 由于gzip是CPU密集型的,因此仅应在压缩率非常高的情况下使用(例如,pretty-printed JSON 或者 YAML 文件)。
要启用压缩功能,请使用gzip
参数。 有效值是从1到9的整数,其中1是最轻的压缩,9是最重的压缩。 换句话说,1在master(和minion)上使用最少的CPU,而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/ 目录如果不存在,那么它将被创建出来。
可以使用cp.get_dir
函数让minion从master服务器下载整个目录。 语法与get_file非常相似:
# salt '*' cp.get_dir salt://etc/apache2 /etc
cp.get_dir 也同样支持使用模板渲染和gzip压缩功能:
# salt '*' cp.get_dir salt://etc/{{pillar.webserver}} /etc gzip=5 template=jinja
Salt还提供了一个客户端实例,它为编写那些需要使用Salt文件服务器的模块和应用程序提供支持。
该文件服务器客户端实例使用与Salt系统其余部分相同的身份验证和加密进行网络通信。
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)
pygit2和GitPython都支持git的Python接口。 如果安装了两者的兼容版本,则会首选使用pygit2。 在这些情况下,可以使用master配置文件中的gitfs_provider
参数强制指定使用GitPython
。
注意:建议始终运行以上任何依赖项的最新版本。 如果没有所选库的最新版本,GitFS的某些功能可能无法使用。
pygit2的最低支持版本是0.20.3。 虽然SaltStack团队正在努力为尽可能多的平台提供兼容版本,但此版本的pygit2的可用性仍然有限。
对于Fedora/EPEL,如果已经包含了依赖包的较新版本,则使用以下命令安装pygit2:
# yum install python-pygit2
如果Debian/Ubuntu发行版本中打包了一个有效pygit2版本,则包名称将相同,并使用以下命令进行安装:
# apt-get install python-pygit2
如果运行Master的平台没有提供足够新的pygit2安装包,那么在pygit2网站上有安装说明。 需要注意的是,遵循这些说明将安装没有相关系统软件包支持的libgit2和pygit2。 此外,pygit2中的SSH身份验证要求在构建libgit2之前存在libssh2(而不是libssh)开发库。 在一些基于Debian的发行版上,还需要pkg-config来链接libgit2和libssh2。
注意:如果在通过SSH建立连接时在Salt Master日志中收到错误“Unsupported URL Protocol”,请查看上面列出的libssh2详细信息。
另外,pygit2版本0.21.0引入了对python-cffi的依赖,而python-cffi又依赖于较新版本的libffi。 升级libffi是不可取的,因为其他几个应用程序依赖它,因此在较旧的LTS linux版本中,pygit2 0.20.3和libgit2 0.20.0是推荐的组合。
警告:pygit2的开发非常活跃,并经常进行非向后兼容的API更改,即使在minor版本中也是如此。 pygit2升级导致Salt出错的情况并不少见。 升级pygit2时请小心,并密切关注版本变更日志,密切关注API更改。 如果有错误发生,可以在SaltStack问题跟踪器上报告错误。
RedHat/CentOS 7.3的发布升级了python-cffi和http-parser,这两者都是pygit2/libgit2的依赖项。 pygit2和libgit2包(来自EPEL存储库)都应升级到最新版本,至少为0.24.2。
如果安装了不兼容的python-pygit2软件包,则以下错误将显示在主日志中:
2017-02-10 09:07:34,892 [salt.utils.gitfs ][ERROR ][11211] Import pygit2 failed: CompileError: command 'gcc' failed with exit status 1
2017-02-10 09:07:34,907 [salt.utils.gitfs ][ERROR ][11211] gitfs is configured but could not be loaded, are pygit2 and libgit2 installed?
2017-02-10 09:07:34,907 [salt.utils.gitfs ][CRITICAL][11211] No suitable gitfs provider module is installed.
2017-02-10 09:07:34,912 [salt.master ][CRITICAL][11211] Master failed pre flight checks, exiting
如果安装了不兼容的libgit2软件包,则以下错误将显示在主日志中:
2017-02-15 18:04:45,211 [salt.utils.gitfs ][ERROR ][6211] Error occurred fetching gitfs remote 'https://foo.com/bar.git': No Content-Type header in response
可能需要重新启动salt-master守护程序和清空gitfs cache目录,以允许继续获取http(s)存储库。
需要GitPython 0.3.0或更高版本才能将GitPython用于gitfs。 对于基于RHEL的Linux发行版,EPEL中提供了兼容版本,可以使用yum轻松地在master服务器上安装:
# yum install GitPython
Ubuntu 14.04 LTS 和 Debian Wheezy (7.x) 兼容性的安装包:
# apt-get install python-git
GitPython需要git CLI工具才能工作。 如果是从系统软件包方式安装的,那么应该已经同时安装了git,但是如果是通过pip安装的,那么可能仍然需要单独安装git。 对于MacOS用户,GitPython与Salt安装程序捆绑在一起,但仍必须安装git才能使其正常工作。 可以通过多种方式安装Git,包括安装XCode。
警告:请记住,如果先前已经使用pip在master服务器上安装了GitPython(即使它随后被卸载),那么它可能仍然存在于构建缓存中(通常是/tmp/pip-build-root/GitPython),如果缓存在安装后没有清除的话。 构建缓存中的包将覆盖任何需安装包使用需求,因此如果此时尝试通过运行pip install’GitPython == 0.3.2.RC1’升级到版本0.3.2.RC1,那么它将忽略这一点,而会直接安装缓存目录中的版本。 因此,为了确保安装指定的版本,可能需要从构建缓存中删除GitPython目录。
警告:GitPython 2.0.9和更新版本与Python 2.6不兼容。 如果在运行Python 2.6的计算机上使用pip安装GitPython,请确保安装早于2.0.9的版本。 这可以通过运行pip install’GitPython <2.0.9’在CLI上完成,或者使用以下SLS在pip.installed状态下完成:
GitPython:
pip.installed:
- name: 'GitPython < 2.0.9'
要使用gitfs后端,master服务器上只需要进行两个配置更改:
fileserver_backend
配置项的列表中包含gitfs
的值:fileserver_backend:
- gitfs
注意:在这里也可以使用
git
,而且早于2018.3.0发行版本时,仅有git
是有效的
gitfs_remotes
配置项中指定一个或多个 git://, https://, file://, ssh:// URLs,定义使用哪些存储库来缓存和查找文件:gitfs_remotes:
- https://github.com/saltstack-formulas/salt-formula.git
支持使用SSH remotes:
gitfs_remotes:
- git@github.com:user/repo.git
- ssh://user@domain.tld/path/to/repo.git
关于怎样配置SSH认证信息可以参考这里。
注意:在master/minion设置中,来自gitfs远程存储库的文件将由master缓存使用,因此minions不需要直接访问git存储库。
gitfs_remotes
选项可以接受一个git remotes的有序列表,按所列顺序缓存和搜索请求的文件。
一个简单的场景说明了这种级联查找行为:
如果gitfs_remotes
选项指定了三个remotes:
gitfs_remotes:
- git://github.com/example/first.git
- https://github.com/example/second.git
- file:///root/third
并且每个存储库中都包含一些文件:
first.git:
top.sls
edit/vim.sls
edit/vimrc
nginx/init.sls
second.git:
edit/dev_vimrc
haproxy/init.sls
third:
haproxy/haproxy.conf
edit/dev_vimrc
Salt将尝试按照配置中定义的顺序从每个gitfs远程存储库中查找所请求的文件。 首先搜索git://github.com/example/first.git。 如果找到所请求的文件,则将其提供,并且不执行进一步的搜索。 例如:
注意:这个例子被设计用来说明gitfs后端的行为。 不应将此示例视为布局文件和git repos的推荐使用方法。
file://prefix表示本地目录中的git存储库。 它仍将使用给定的file:// URL作为远程地址,而不是将git repo复制到salt缓存中。 这意味着你想要访问的任何引用必须作为指定仓库中的本地引用存在。
警告:2014.1.0之前的Salt版本不能很好地支持变更remotes的顺序或修改现有remotes的URI。 在这些版本中,修改远程URI时,最好在重新启动salt-master服务之前手动删除gitfs的缓存目录(/var/cache/salt/master/gitfs)。
New in version 2014.7.0.
下面列出的这些是master配置中的全局选项 (也就是说,会对配置了的所有gitfs remotes有效):
注意:pygit2仅支持在版本0.23.2及更高版本中禁用SSL验证。
现在可以基于每个remote覆盖这些参数,以按需进行定制。 以下是一些示例用法:
gitfs_provider: pygit2
gitfs_base: develop
gitfs_remotes:
- https://foo.com/foo.git
- https://foo.com/bar.git:
- root: salt
- mountpoint: salt://bar
- base: salt-base
- ssl_verify: False
- update_interval: 120
- https://foo.com/bar.git:
- name: second_bar_repo
- root: other/salt
- mountpoint: salt://other/bar
- base: salt-base
- ref_types:
- branch
- http://foo.com/baz.git:
- root: salt/states
- user: joe
- password: mysupersecretpassword
- insecure_auth: True
- disable_saltenv_mapping: True
- saltenv:
- foo:
- ref: foo
- http://foo.com/quux.git:
- all_saltenvs: master
重要:对于per-remote配置,应该注意两个重要的细节。
gitfs_
。 其中的name,saltenv和all_saltenvs
参数例外,它们仅适用于per-remote配置。注意:all_saltenvs参数是2018.3.0版本中的新参数。
在上面的示例配置中, 下面的描述都是正确的:
all_saltenvs
,因此来自master
分支/标记中的文件将出现在每个文件服务器环境中。注意:此处仅允许使用http://(而不是https://),因为未使用身份验证。 否则,必须使用insecure_auth参数(如在第四个远程中)以强制Salt对http:// remote进行身份验证。
New in version 2016.11.0.
对于更精细的控制需求,Salt允许在给定的repo中为一个saltenv覆盖以下三个内容:
一个示例:
gitfs_root: salt
gitfs_saltenv:
- dev:
- mountpoint: salt://gitfs-dev
- ref: develop
gitfs_remotes:
- https://foo.com/bar.git:
- saltenv:
- staging:
- ref: qa
- mountpoint: salt://bar-staging
- dev:
- ref: development
- https://foo.com/baz.git:
- saltenv:
- staging:
- mountpoint: salt://baz-staging
对于上面的例子,下面的描述都是正确的:
dev
saltenv的文件将位于salt://gitfs-dev下。dev
saltenv,来自第一个remote的文件将是从development
分支获取的,而来自第二个remote的文件将来自develop
分支。staging
saltenv,来自第一个remote的文件将位于salt://bar-staging
下,而来自第二个remote的文件将位于salt://baz-staging
下。salt
目录(及其子目录)提供。New in version 2017.7.0.
默认情况下,GitFS将获取远程分支和标记。 但是,有时获取自定义引用(例如为GitHub拉取请求创建的引用)可能很有用。 要更改引用GitFS的refspec,请使用gitfs_refspecs配置选项:
gitfs_refspecs:
- '+refs/heads/*:refs/remotes/origin/*'
- '+refs/tags/*:refs/tags/*'
- '+refs/pull/*/head:refs/remotes/origin/pr/*'
- '+refs/pull/*/merge:refs/remotes/origin/merge/*'
在上面的示例中,除了获取远程分支和标记之外,还将获取GitHub针对拉取请求的自定义引用,并且还将获取合并的拉取请求。 这些特殊的头部引用表示请求合并的分支的头部,合并引用表示合并后的基本分支的结果。
重要:使用自定义引用时,获取的引用的目标必须位于
refs/remotes/origin/
下,最好位于上例中的子目录中。 这些自定义refspecs将使用它们在refs/remotes/origin/下面的相对路径映射为环境名称。 例如,假设上面的配置,拉取请求12345的head branch将映射到文件服务器环境pr/12345
(包括斜杠)。
可以基于每个remote配置Refspec。 例如,以下配置只会更改第二个GitFS remote的默认refspec。 第一个remote只会获取分支和标签(默认值)。
gitfs_remotes:
- https://domain.tld/foo.git
- https://domain.tld/bar.git:
- refspecs:
- '+refs/heads/*:refs/remotes/origin/*'
- '+refs/tags/*:refs/tags/*'
- '+refs/pull/*/head:refs/remotes/origin/pr/*'
- '+refs/pull/*/merge:refs/remotes/origin/merge/*'
New in version 2018.3.0.
all_saltenvs
per-remote配置参数会覆盖Salt所有用于将分支/标记映射到文件服务器环境(即saltenvs)的逻辑。 这允许单个分支/标记出现在所有GitFS saltenv中。
注意:
all_saltenvs
仅适用于GitFS。 也就是说,使用all_saltenvs
配置的分支中的文件不会显示在通过其他类型文件服务器后端(例如file_roots)定义的文件服务器环境中。
这在使用salt formulas时非常有用。 在添加此功能之前,必须将分支/标签推送到要使用该公式的每个saltenv的远程仓库。 如果需要更新公式,则需要在所有其他分支/标记中反映此更新。 这既不方便又不可扩展。
使用all_saltenvs
,现在可以在一个分支中定义公式,一次性对所有saltenv环境生效。
gitfs_remotes:
- http://foo.com/quux.git:
- all_saltenvs: anything
在2018.3.0版本发布之前,GitFS将更新其文件服务器后端作为专用“维护”过程的一部分,和执行其他各种日常维护任务一起。 这的实现方式中将GitFS更新间隔绑定到loop_interval配置选项,并且还强制要求所有文件服务器以相同的间隔更新。
现在可以使用gitfs_update_interval以自己的间隔更新GitFS了:
gitfs_update_interval: 180
gitfs_remotes:
- https://foo.com/foo.git
- https://foo.com/bar.git:
- update_interval: 120
使用上述配置,第一个remote将每三分钟更新一次,而第二个remote每两分钟更新一次。
GitFS配置的优先顺序如下(每个级别覆盖它下面的所有级别):
saltenv
参数下定义)gitfs_remotes:
- https://foo.com/bar.git:
- saltenv:
- dev:
- mountpoint: salt://bar
gitfs_saltenv
参数下定义)gitfs_saltenv:
- dev:
- mountpoint: salt://bar
gitfs_remotes:
- https://foo.com/bar.git:
- mountpoint: salt://bar
gitfs_mountpoint: salt://bar
注意:上面的一个例外是当使用
all_saltenvs
时。 此值将覆盖将分支/标记映射到文件服务器环境的所有逻辑。 因此,即使使用了gitfs_saltenv
用于全局覆盖给定saltenv的映射,all_saltenvs
中的配置也将会被优先使用。
同时,还需要注意的是,gitfs_saltenv
(或per-saltenv配置)中配置的任何root
和mountpoint
值都不受此影响。
gitfs_root参数允许将存储库中的子目录用于提供文件。 这允许仅将部分存储库公开给Salt文件服务器使用。
假设下面的文件布局:
.gitignore
README.txt
foo/
foo/bar/
foo/bar/one.txt
foo/bar/two.txt
foo/bar/three.txt
foo/baz/
foo/baz/top.sls
foo/baz/edit/vim.sls
foo/baz/edit/vimrc
foo/baz/nginx/init.sls
以下配置仅会使用到foo/baz路径下的文件,而忽略存储库中的其他文件:
gitfs_remotes:
- git://mydomain.com/stuff.git
gitfs_root: foo/baz
仍然可以在基于per-remote级别上为每个remote单独配置root参数。
New in version 2014.7.0.
gitfs_mountpoint
参数将在从gitfs提供的文件前添加上一个指定的路径。 这将允许使用现有存储库,而不是需要重新组织存储库或围绕Salt文件服务器的布局设计它。
在添加此功能之前,如果通过gitfs提供的文件深度嵌套在根目录中(例如,salt://webapps/foo/files/foo.conf
,则需要确保该文件是正确地位于远程存储库中,并且所有父目录都存在(例如,目录webapps/foo/files/
需要存在于存储库的根目录中)。
下面的示例中允许从Salt文件服务器路径salt://webapps/foo/files/foo.conf
提供存储库根目录下的文件foo.conf
。
gitfs_remotes:
- https://mydomain.com/stuff.git
gitfs_mountpoint: salt://webapps/foo/files
Mountpoints 参数同样支持 per-remote配置。
从2014.7.0开始,gitfs可以在masterless模式下使用。 为此,只需在minion配置文件中添加gitfs配置参数,并设置fileserver_backend(而不是在master配置文件中设置)。
有时启用多个后端可能有实际意义; 例如,只是将sls文件存储在git中,但较大的文件直接存储在master本地磁盘上。
用于多个远程的级联查找逻辑也用于多个后端。
例如,如果fileserver_backend选项包含多个后端:
fileserver_backend:
- roots
- git
这时将会首先搜索roots
后端(即位于/srv/salt
中的文件)以查找所请求的文件; 然后,如果在maser服务器上找不到这些文件,则将继续搜索每个配置的git remote。
使用GitFS后端时,分支和标记将使用分支/标记的名称作为标识符映射到环境。
此规则有一个例外:master
分支默认地隐式映射到了base
环境。
因此,对于典型的base, qa,dev
设置,可以使用以下分支:
master
qa
dev
来自不同分支的top.sls
文件将在运行时合并为一个。 由于这会导致配置过于复杂,因此建议的设置是使用单独的存储库,仅使用一个master分支的top.sls文件。
如果需要将master之外的分支映射为base
环境使用,请使用gitfs_base参数。
gitfs_base: salt-base
这个功能同样支持按 per-remote 去分别定义。
New in version 2014.7.0.
gitfs_saltenv_whitelist和gitfs_saltenv_blacklist参数允许更好地控制哪些分支/标记作为文件服务器环境公开。 支持精确匹配、全局和正则表达式,并按此顺序进行评估。 如果使用正则表达式,则必须省略^
和$
,并且表达式必须与整个分支/标记匹配。
gitfs_saltenv_whitelist:
- base
- v1.*
- 'mybranch\d+'
v1.*
,在这个例子中,会与glob和正则表达式进行匹配(不过它将匹配为glob,因为在是正则表达式之前计算globs)。
黑名单/白名单的行为将根据使用的两个选项的组合而有不同的效果:
gitfs_saltenv_whitelist
,则只有与白名单匹配的分支/标签才可用作环境;gitfs_saltenv_blacklist
,则与黑名单匹配的分支/标记将不可用作环境;New in version 2014.7.0.
从版本0.20.3开始支持HTTPS和SSH身份验证,这是Salt for gitfs支持的最早的pygit2版本。
注意:以下示例使用了per-remote配置参数,这是Salt 2014.7.0后的新功能。 有关这些的更多信息可以在这里找到。
HTTPS
对于需要身份验证的HTTPS存储库,可以像这样配置用户名和密码:
gitfs_remotes:
- https://domain.tld/myrepo.git:
- user: git
- password: mypassword
如果存储库是通过HTTP而不是HTTPS提供的,那么Salt默认拒绝对其进行身份验证。 可以通过添加insecure_auth
参数来覆盖此行为:
gitfs_remotes:
- http://domain.tld/insecure_repo.git:
- user: git
- password: mypassword
- insecure_auth: True
SSH
可以使用ssh://协议指定或使用类似scp的语法来配置SSH存储库。 因此,以下两种配置方式的效果相同:
必须配置gitfs_pubkey
和gitfs_privkey
(或在per-remote中配置它们)才能对基于SSH的存储库进行身份验证。 如果私钥启用了密码保护,则可以使用gitfs_passphrase
配置私钥(如果是per-remote方式,则需要配置passphrase
)。 例如:
gitfs_remotes:
- git@github.com:user/repo.git:
- pubkey: /root/.ssh/id_rsa.pub
- privkey: /root/.ssh/id_rsa
- passphrase: myawesomepassphrase
最后,需要把提供远程存储库服务主机的SSH host key添加到salt master的~/.ssh/known_hosts文件中。(如果你不是很确定怎么配置这个,也可以直接从salt master主机使用ssh登录一次远程存储库服务主机即可,一般地,是使用root用户)
注意:使用pygit2对Microsoft Visual Studio(VSTS)进行公钥SSH身份验证时存在已知问题。 这是由于旧的libssh2版本中的VSTS存在错误或缺乏支持。 已知的可以工作的版本包括libssh2 1.7.0及更高版本,已知的不兼容版本包括1.5.0及更早版本。 在撰写本文时,1.6.0尚未经过测试。
由于升级libssh2需要重建许多其他软件包(curl等),然后重建libgit2并重新安装pygit2,对于具有较旧libssh2的系统,更简单的解决方法是使用GitPython和无密码密钥进行身份验证。
HTTPS
对于需要身份验证的HTTPS存储库,可以使用以下两种方法之一配置用户名和密码。 第一种方法是使用格式https://:@将它们包含在URL中,如下所示:
gitfs_remotes:
- https://git:mypassword@domain.tld/myrepo.git
另一种方法是在~/.netrc中配置身份验证:
machine domain.tld
login git
password mypassword
如果存储库是通过HTTP而不是HTTPS提供的,那么Salt默认拒绝对其进行身份验证。 可以通过添加insecure_auth
参数来覆盖此行为:
gitfs_remotes:
- http://git:mypassword@domain.tld/insecure_repo.git:
- insecure_auth: True
** SSH **
GitPython仅支持使用无密码的SSH公钥认证。 上面的pygit2身份验证示例中显示的auth参数(pubkey,privkey等)不适用于GitPython。
gitfs_remotes:
- ssh://git@github.com/example/salt-states.git
由于GitPython调用了git CLI
,因此私钥必须位于~/.ssh/id_rsa
中,供运行Master的用户使用,并且应具有0600的权限。此外,如果repo URL中没有用户, GitPython将(就像SSH一样)尝试以当前用户身份登录(换句话说,也就是正在运行Master的用户,通常是root用户)。
如果需要使用密钥,则可以将~/.ssh/config
配置为使用所需的密钥。 可以通过查看ssh_config
的联机帮助页找到有关如何执行此操作的信息。 下面是一个示例条目,可以添加到~/.ssh/config
以使用gitfs的备用密钥:
Host github.com
IdentityFile /root/.ssh/id_rsa_gitfs
Host
参数应该是与git存储库的域名匹配的主机名(或主机名glob)。
还需要将SSH主机密钥添加到known_hosts
文件中。或者是,也可以禁用 strict host key checking
检查,可以通过在~/.ssh/config
中的条目中添加StrictHostKeyChecking no
来完成
Host github.com
IdentityFile /root/.ssh/id_rsa_gitfs
StrictHostKeyChecking no
但是,这通常被认为是不安全的,不推荐使用。
使用SSH身份验证,必须在~/.ssh/known_hosts
文件中包含远程存储库的SSH主机密钥。 如果master同时也是minion,可以使用ssh.set_known_host函数完成:
# salt mymaster ssh.set_known_host user=root hostname=github.com
mymaster:
----------
new:
----------
enc:
ssh-rsa
fingerprint:
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
hostname:
|1|OiefWWqOD4kwO3BhoIGa0loR5AA=|BIXVtmcTbPER+68HvXmceodDcfI=
key:
AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
old:
None
status:
updated
如果没有,那么添加密钥的最简单方法是使用运行salt-master的用户(通常是root)尝试通过SSH登录存储库服务器:
$ su -
Password:
# ssh github.com
The authenticity of host github.com (192.30.252.128) cant be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added github.com,192.30.252.128 (RSA) to the list of known hosts.
Permission denied (publickey).
登录成败无关紧要,因为回答“是”就会将密钥写入known_hosts文件。
VERIFYING THE FINGERPRINT
要验证是否添加了正确的指纹,最好查找一下。 一种方法是使用nmap:
$ nmap -p 22 github.com --script ssh-hostkey
Starting Nmap 5.51 ( http://nmap.org ) at 2014-08-18 17:47 CDT
Nmap scan report for github.com (192.30.252.129)
Host is up (0.17s latency).
Not shown: 996 filtered ports
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey: 1024 ad:1c:08:a4:40:e3:6f:9c:f5:66:26:5d:4b:33:5d:8c (DSA)
|_2048 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 (RSA)
80/tcp open http
443/tcp open https
9418/tcp open git
Nmap done: 1 IP address (1 host up) scanned in 28.78 seconds
另一种方法是使用这个单行命令检查用户自己的known_hosts
文件:
$ ssh-keygen -l -f /dev/stdin <<<`ssh-keyscan github.com 2>/dev/null` | awk '{print $2}'
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
警告:AWS会跟踪nmap的使用情况,并可能将其标记为滥用。 在AWS主机上,建议使用
ssh-keygen
方法进行主机密钥验证。
注意:从OpenSSH 6.8开始,SSH密钥现在显示为主机密钥的base64编码SHA256校验和。 所以,不是看起来像
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
,它看起来像SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
。
New in version 2014.1.0.
注意:本演练方案假设你已经掌握了Salt和cp.push的基本知识。 需要了解salt基本使用,请查看Salt Walkthrough。
有时需要将位于一个minion上的文件部署到另一个或多个其他minions上去。 这在Salt中是得到支持的,可以分为两部分:
cp.push
)本演练方案将演示如何使用这两个功能。
要将master设置为接受从minions推送的文件,master配置文件中的file_recv
选项必须设置为True
(默认值为False
)。
file_recv: True
需要重启master服务,使配置生效。
完成上面配置操作后,可以使用cp.push
函数将文件推送到master服务器:
salt 'minion-id' cp.push /path/to/the/file
此命令会将文件存储在master的cachedir
下名为minions
的子目录中。 在大多数master服务器上,此路径将是/var/cache/salt/master/minions
。 在这个目录中将是每个minion的一个目录,它将文件推送到master服务器,并在其下面是minion上文件的完整路径。 因此,例如,如果ID为dev1
的minion将文件/var/log/myapp.log
推送到master服务器,则会将其保存到/var/cache/salt/master/minions/dev1/var/log/myapp.log
。
虽然可以将/var/cache/salt/master/minions
添加到master的file_roots
并提供这些文件,但可能只需要公开某些从minions推送的文件。 为需要暴露的每个minion添加/var/cache/salt/master/minions/<minion-id>
可能很麻烦并且容易出错。
通过minionfs,这个文件服务器后端将使得用cp.push推送的文件,也可用于Salt文件服务器,并提供了一种简单的机制来限制哪些minions的推送文件可用。
要使用minionfs
后端,请将minionfs
添加到master上fileserver_backend配置选项中的后端列表中:
file_recv: True
fileserver_backend:
- roots
- minionfs
注意:在这里配置为
minion
也是有效的,minionfs
在较新版本中才得到支持,而且在2018.3.0版本之前,只有minion
会工作。
此外,如前所述,需要file_recv:True
才能使master服务器接收从minions推送来的文件。 与往常一样,对master配置的更改需要重新启动salt-master
服务。
通过minionfs
提供的文件默认位于salt:///path/to/file。 回想一下前面的例子,其中dev1
将文件/var/log/myapp.log
推送到master服务器。 启用minionfs
后,此文件可在Salt中以salt://dev1/var/log/myapp.log
进行寻址。
如果许多minions都推送文件到master服务器,这将导致Salt文件服务器的根目录中有许多的目录。 因此,建议使用minionfs_mountpoint
配置选项在子目录下组织这些文件:
minionfs_mountpoint: salt://minionfs
启用上面的配置项后,上面例子中的示例文件会被存放在 salt://minionfs/dev1/var/log/myapp.log
路径下。
可以通过白名单和黑名单限制哪些minions可以通过minionfs
给master推送文件。 可以使用minionfs_whitelist和minionfs_blacklist配置选项管理这些列表。 单击两者的链接以获取有关如何使用它们的详细说明。
可以在下面找到更复杂的配置示例,它同时使用了白名单和黑名单:
file_recv: True
fileserver_backend:
- roots
- minionfs
minionfs_mountpoint: salt://minionfs
minionfs_whitelist:
- host04
- web*
- 'mail\d+\.domain\.tld'
minionfs_blacklist:
- web21
目前没有提供访问控制策略来限制哪些minions可以访问由minionfs提供的文件。 所有minions都可以访问这些文件。
除非使用minionfs_whitelist和/或minionfs_blacklist配置选项,否则所有minions都可以通过minionfs将文件推送到master服务器,然后向其他minions提供这些文件。