美文网首页saltstack
二、Salt文件服务器与salt-cp以及cp模块

二、Salt文件服务器与salt-cp以及cp模块

作者: 037251a7c483 | 来源:发表于2017-03-07 23:45 被阅读1480次

在配置管理系统中,从中心服务器向客户端推送文件是基本需求。SaltStack使用内建的ZeroMQ服务器作为文件服务器。文件服务器主要用于在state系统中将SLS文件推送到客户端,当然也可以用于其他文件的传输。
  运维工作中,经常会有文件同步的情况。我在日常工作中,由于权限限制,只能自己写程序分发文件。我使用的是Python+paramiko+threading+Queue,paramiko用于远程执行命令或者分发文件,threading+Queue实现并发分发文件(如果是串行的话,效率十分低下)。最近研究SaltStack时,发现有两种方法可以做到文件分发,第一只是使用SaltStack命令:salt-cp;第二种是使用SaltStack提供的:Salt文件服务器,这两种方法都可以实现文件分发的功能。

一、 salt-cp

1. salt-cp简述

salt-cp命令用于复制一个文件到多个minion系统中。指定minion可以使用通配符、正则表达式、Grains等方法

salt-cp '*' [ options ] SOURCE DEST
salt-cp -E '.*' [ options ] SOURCE DEST
salt-cp -G 'os:CentOS*' [ options ] SOURCE DEST

minion匹配
   -E 目标选择;表示以正则表达式匹配minion
  -G 目标选择表示使用minion上的Salt Graings系统的返回值来匹配特定minion
  -L 目标minion别解析成用逗号分隔的列表

2. salt-cp 用例

  • 将irq.py 文件 发送到 OS为CentOS的minion的 /usr/local目录下

salt-cp -G 'os:centos' irq.py /usr/local/

返回值:{'192.168.1.223': {'/usr/local/irq.py': True}} 表示成功

  • 将salt.doc文件发送到所有的minion的/usr/local目录下

salt-cp '*' salt.doc /usr/local/

返回值:{'192.168.1.223': {'/usr/local/salt.doc': True}} 表示成功

salt-cp -L '192.168.1.223' install.log /usr/local/

返回{'192.168.1.223': {'/usr/local/install.log': True}} 表示成功

二、Salt 文件服务器

Salt内置了一个简单的文件服务器用于分发文件给Salt minions。

1. 文件服务器的base环境

由于文件服务器是为Salt state system工作的,所以文件服务器也是支持环境的概念的。
  Salt文件服务器/etc/salt/master配置文件中的flie_roots选项管理。Salt文件服务器的默认环境为为base环境,base环境必须定义,因为当环境没有明确指定时,文件下载就是从base环境中去找的。其配置如下:

file_roots:
  base:
    - /srv/salt/base
    - /srv/salt/failover

/srv/salt/base和/srv/salt/failover这些目录是不存在,需要手动创建。这里还需要说明的是下载文件时的搜索顺序。文件服务器在给minions传输文件时,是有搜索顺序的。这里用上述配置说明:如果文件URL为:salt://httpd/httpd.conf。那么传输文件时,首先搜索/srv/salt/base/httpd/httpd.conf,如果找到了,则下载;否则就使用/srv/salt/failover/httpd/httpd.conf

2. 文件服务器多环境配置

多环境配置也是更改master配置达成,如下:

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

在这个配置中,处了base环境外。还有dev环境和prod环境。配置文件修改后,需要重启master才能生效。

3. cp模块

cp模块被用于用于Salt state system、salt-cp命令(如上所述)以及可用于Salt文件服务器。

3.1 cp.get_fle

cp.get_file用于minion从master下载一个文件,语法:

  • 文件在base环境下

salt '*' cp.get_file salt://testfile /root/testfile

该命令表示minion从master端下载文件并拷贝到到/root/testfile文件中。注意:salt://表示的base环境。因此,testfille是位于base环境下——即/srv/salt/base目录中。

  • 文件在base环境的多级目录下

salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf

salt://httpd/httpd.conf表示** /srv/salt/base/httpd/httpf.conf**

  • 实例
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root
192.168.1.223:
    The minion function caused an exception: Traceback (most recent call last):
      File "/usr/lib/python2.6/site-packages/salt/minion.py", line 1412, in _thread_return
        return_data = executor.execute()
      File "/usr/lib/python2.6/site-packages/salt/executors/direct_call.py", line 28, in execute
        return self.func(*self.args, **self.kwargs)
      File "/usr/lib/python2.6/site-packages/salt/modules/cp.py", line 227, in get_file
        gzip)
      File "/usr/lib/python2.6/site-packages/salt/fileclient.py", line 1112, in get_file
        fn_ = salt.utils.fopen(dest, 'wb+')
      File "/usr/lib/python2.6/site-packages/salt/utils/__init__.py", line 1288, in fopen
        fhandle = open(*args, **kwargs)
    IOError: [Errno 21] Is a directory: '/root'

[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf
192.168.1.223:
    /root/httpd.conf

这里注意下,根据报错可以发现:目标路径必须是一个文件,而不是目录。这点有区别去salt-cp命令。

  • cp.get_file gzip格式
      对于大文件传输,cp.get_file支持gzip压缩格式。因为gzip是CPU密集型的工具,因此cp.get_file开启gzip是适用于高压缩率的情况下,如JSON或者YAML文件。
      语法:

salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf gzip=5

gzip后的数字表示压缩比,范围在1-9之间,1表示最小压缩比,9为最大压缩比。换句话说,gzip=1情况下, 消耗的CPU小;gzip=9时,消耗的CPU则更多。

  • cp.get_file makedirs=True
       注意,也就是时候,cp.get_file过程中,如果目录不存在,cp.get_file是不会主动创建目录的,如果要做到这点,可以使用makedirs=True 参数。测试如下:
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/test/httpd.conf
192.168.1.223:
    False
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/test/httpd.conf makedirs=True
192.168.1.223:
    /root/test/httpd.conf

3.2 cp.get_dir

顾名思义,cp.get_dir就是下载目录,用法基本同cp.get_file一直。直接举个例子吧

  • 将master端的httpd目录下载到minion端的/root目录下
[root@master ~]# salt '*' cp.get_dir salt://httpd /root
192.168.1.223:
    - /root/httpd/httpd.conf

3.3 cp.push

cp.push 模块允许minion上传文件到master端。注意事项:

  • cp.push功能默认不开启,需要修改配置文件中的file_recv 环境,默认为False
  • 上传的文件存放在master端的 /var/cache/salt/master/minions/<minion_id>/files/ 目录下
修改master配置文件并重启。
file_recv: True
以上传httpd.conf为例
[root@logan ~]# salt '192.168.159.241' cp.push /etc/httpd/conf/httpd.conf 
192.168.159.241:
    True

# 查看文件
[root@logan conf]# pwd
/var/cache/salt/master/minions/192.168.159.241/files/etc/httpd/conf
[root@logan conf]# ls
httpd.conf

三、利用Salt API分发文件

In [10]: import salt.client

In [11]: local = salt.client.LocalClient()

In [12]: local.cmd('*', 'cp.get_file', ['salt://httpd/httpd.conf', '/root/aaaaaaa'])
Out[12]: {'192.168.1.223': '/root/aaaaaaa'}

最近在写运维管理平台时,要做一个文件分发的功能,因此就用到了Salt的文件服务器以及cp模块来做,再调用下Salt开放的API,达到的效果也是十分理想的。当然,前提是要把文件准备在特定的目录下,这点只要自己做一个规范,也是很好管理的。

相关文章

网友评论

  • 9dbe76abdb8d:请教个问题,salt.client.LocalClient(),当执行多个异步命令的时候,要依次执行才行。如果前一个命令没有执行完成,紧接着又执行一个命令,前一个命令根据jod id判断 是否执行成功时,会收到第二个命令执行的结果。难道只能串行执行吗? 我才接触不久,请指教。
    9dbe76abdb8d:我测试了salt-api,执行多个异步请求时,结果并没有产生混乱。那就不用client api,就直接用salt-api了。
    9dbe76abdb8d:@燕涛 异步的怎么会直接给你返回结果呢,肯定是返回的一个job id, 然后你每隔一定时间去获取结果,get_cli_returns(jid,'*'),返回的是一个generator。我用的测试环境:一个python执行cp.get_file,从Master到minion,拷一个800M这么大的文件,此时每隔一秒调用get_cli_returns输出执行结果。 然后另开个ssh终端在ipython里面, 也使用同样的异步命令对所有minion执行,test.ping操作。 在监测文件是否拷贝完成的过程中,他会输出ssh终端中执行的test.ping操作。你可以测试一下,我在网上也没找着这方面的资料。 saltstack官方文档也提了这个问题,似乎client api异步操作本身就会有这个问题存 在。
    037251a7c483:LocalClient用的是tornado的IOLoop,是异步的。而且LocalClient是直接给你返回结果的吧?为啥你需要用job id判断呢?

本文标题:二、Salt文件服务器与salt-cp以及cp模块

本文链接:https://www.haomeiwen.com/subject/qrddgttx.html