前言
文件分发是自动化运维平台设计中不可或缺的原子操作,如何快速的分发文件到目标主机上?如何解决大文件传输的性能和带宽问题?
0.什么是运维原子操作?
在开始之前有必要澄清下什么是运维的原子操作,所有的自动化运维平台,底层通道通过类型区分只有三种原子操作:命令执行、数据采集、文件分发。例如不管你是安装、启动一个软件都是属于命令执行、监控采集和日志采集都属于数据采集。然后就是文件分发。然后通过将这些原子操作组合起来就可以完成非常复杂的作业编排和流程编排。
1.使用Ansible进行文件分发
如果你是Ansible的用户,我们可以快速的执行一个ad-hoc进行文件分发。
# ansible [pattern] -m [module] -a "[module options]"
案例测试:
# ansible all -m copy -a "src=/etc/resolv.conf dest=/etc/resolv.conf"
linux-node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"checksum": "cf9cdfda6eb561a6ec4575ca458c80c9058bb8f1",
"dest": "/etc/resolv.conf",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/resolv.conf",
"size": 24,
"state": "file",
"uid": 0
}
更多用法请参考官方文档:
https://docs.ansible.com/ansible/latest/modules/copy_module.html#copy-module
2.使用SaltStack进行文件分发
如果你是SaltStack的用户,你可以有两种选择。
2.1 salt-cp
首先是可以直接使用salt-cp这个命令进行快速的文件分发:
salt-cp '*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST
案例测试:
# salt-cp '*' /etc/hosts /etc/hosts
linux-node1.example.com:
----------
/etc/hosts:
True
中文支持测试:
# salt-cp '*' 呵呵.txt /tmp/
linux-node1.example.com:
----------
/tmp/呵呵.txt:
True
而且你也可以使用-C, --chunked 采用分块模式进行文件分发,此模式支持大文件、递归目录复制和压缩的功能。
2.2 cp.get_file
对于大文件的分发,SaltStack官方建议使用远程执行模块cp.get_file进行大文件的分发管理,这个需要使用Salt内置的一个轻量级的file server。而且也支持环境的区分。
# vim /etc/salt/master
...
file_roots:
base:
- /srv/salt/base
test:
- /srv/salt/dev
prod:
- /srv/salt/prod
...
更多的使用方式请参考官方文档:
https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.cp.html#salt.modules.cp.get_file
3. 使用蓝鲸作业平台进行文件分发
如果你是蓝鲸的用户,蓝鲸的作业平台提供了分发文件的功能,主要是靠蓝鲸的管控平台来实现的.
蓝鲸管控平台主要提供了三种类型的服务能力:文件传输能力、实时任务执行能力、数据采集与传输的能力。架构图如下:
4.使用P2P工具进行文件分发
不管是使用Ansible还是SaltStack的两种文件分发模式,都无法解决大文件分发的效率和带宽的问题,蓝鲸的管控平台是支持P2P进行文件分发,所以BitTorrent成为了海量大文件分发的首选,这里介绍一下Twitter开源的murder。
不过请注意,该项目在Github上已经不维护了,但不影响使用
https://github.com/lg/murder
Large scale server deploys using BitTorrent and the BitTornado library (NOTE: project no longer maintained) http://twitter.com
Murder是Twitter开源的的一个P2P文件传输工具,主要是解决Twitter内部做应用部署发软件包的问题。
4.1 Murder组件介绍:
- torrent tracker:这是Murder的追踪器,需要独立运行的一个服务,通过运行murder_tracker.py就可以启动,tracker实际上只是一个迷你的httpd,对外提供/announce路径,Bittorrent客户端会将他们的状态更新到这个路径上。
- seeder:这是一个播种机,将文件存放在seeder的节点的一个目录下,通过murder_make_torrent.py会生成一个.torrent的文件,保存着要分发的文件的一些信息,在开始进行P2P传输之前,其它的节点会先从seeder节点来下载文件分片。
- Peers:指的是所有需要接收文件的节点,它们将接收文件并在彼此之间分发文件分片。一旦有节点同伴完成分发文件的下载,它将继续播种一段时间,以防止热点效应的播种机。
4.2 快速实验:
下面快速的做一个小实验,为了方便使用murder,这里简单的编写了一个安装脚本https://github.com/unixhot/filebt.git,使用supervisor来启动tracker服务。
1.下载代码
# cd /usr/local/src
# wget https://github.com/unixhot/filebt/archive/master.zip
2.使用Ansible/SaltStack分发到所有机器上
# ansible all -m copy -a "src=/usr/local/src/master.zip dest=/usr/local/src/master.zip"
3.执行安装
# ansible all -m raw -a 'cd /usr/local/src && unzip master.zip && cd filebt-master/install/ && ./install.sh install'
4.启动tracker服务
本案例就在Ansible/SaltStack的控制节点启动。
# cd /usr/local/src/filebt-master/install/
# ./install.sh tracker
可以查看tracker服务的状态,确保已经启动。
# supervisorctl status
filebt-tracker RUNNING pid 29435, uptime 0:00:02
```
查看监听端口,如果你想修改tracker的端口,可以在/etc/supervisord.d/tracker.ini中修改,修改完毕之后注意重启服务。
netstat -ntlp | grep 8998
tcp 0 0 0.0.0.0:8998 0.0.0.0:* LISTEN 29435/python
5.准备一个测试文件
cd /usr/local/src
dd if=/dev/zero of=bigfile.tar.gz count=1 bs=100M
6.生成种子文件
python /opt/filebt/murder_make_torrent.py bigfile.tar.gz 192.168.56.234:8998 bigfile.tar.gz.torrent
注意:这里需要指定tracker的地址,案例是192.168.56.234:8998。
7.启动seeder
python /opt/filebt/murder_client.py seed bigfile.tar.gz.torrent bigfile.tar.gz 192.168.56.234
done and done
注意:最后一个IP地址,是seed所在服务器的地址,当前是和tracker在同一台主机上。而且执行完命令执行,会一直等待。
8.将文件种子分发到所有要下载的节点上。
ansible all -m copy -a "src=/usr/local/src/bigfile.tar.gz.torrent dest=/usr/local/src/bigfile.tar.gz.torrent"
9.所有节点进行P2P下载
ansible all -m raw -a 'LOCAL_IP=$(hostname -i) && cd /usr/local/src && python /opt/filebt/murder_client.py peer bigfile.tar.gz.torrent bigfile.tar.gz $LOCAL_IP'
注意:最后一个IP为各个节点本地IP地址。
> 警告⚠️如果需要分发的节点比较少,文件也特别小,不要使用P2P的方式进行文件分发,因为速度还没有直接使用Ansible或者SaltStack快。
> 建议:在实际的应用过程中,你可以通过自定义脚本来简化这些操作,通过自定义Web界面也可以很好的隐藏掉复杂的细节,同时也可以根据文件大小和分发节点的数量,自动判断是否开启P2P传输。