共计 3681 个字符,预计需要花费 10 分钟才能阅读完成。
本人家里有好几台运行 Debian GNU/Linux testing 的计算机,共处于一个小局域网内。因为 Debian testing 是滚动更新的,所以我每隔几天就要把它们全部更新一遍。但是一来中国家庭的网速还是说不上很快,每台机器都要从上游软件源的服务器上下载成百上千兆字节的软件包要花不少时间;二来这样操作也给软件源的服务器造成不小的负担。
后来我想起 Debian 曾开发过一个叫 apt-p2p 的软件,它的设计初衷是缓存已下载的软件包提供给其他同样运行着 apt-p2p 的 peers,作为从软件源下载的补充。那么是否可以用这个软件在局域网内搭建一个 Debian 软件包缓存呢?
apt-p2p 由 Python 写成,安装好后默认监听于 TCP 和 UDP 的 9977 端口,可通过 /etc/apt-p2p/apt-p2p.conf
改变其行为。TCP 端口同时用于本机 apt 下载软件包,而 UDP 端口用于组建在 p2p 文件共享工具中常见的 DHT 网络。只需要在 /etc/apt/sources.list
文件中软件源的 url,例如 http://mirror.server/debian/
的服务器域名前面插入 localhost:9977,即成为http://localhost:9977/mirror.server/debian/
,具体从互联网上获取软件包的工作便交给 apt-p2p 负责了:
- 当收到来自本机 apt 的文件下载请求时,apt-p2p 会先检测文件是否已经存在于缓存的目录树中
- 如果已存在,则还要检查是否为最新(通过向软件源服务器发出 HEAD 请求来实现)
- 如果是,则直接返回缓存的文件
- 否则从互联网上下载文件供给 apt,同时存入缓存并记录其散列值
- 下载文件会首先尝试从 peer 处下载,不成再到软件源服务器处下载
- 缓存下来的文件和散列值可供其他 peer 使用。可以通过 apt-p2p 的日志文件 /var/log/apt-p2p.log 深入观测这一过程。
以下是我安装了 apt-p2p 的主机 mycastle
的 sources.list:
deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing main
deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing main
deb http://localhost:9977/mirrors.ustc.edu.cn/debian-security/ testing/updates main
deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian-security testing/updates main
deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ unstable main
deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ unstable main
然而 apt-p2p 的缓存只能给本机使用,其他主机若试图直接访问 9977 端口只会得到 404 错误。因此还需要在安装 apt-p2p 的主机上架设一个 http 反向代理,使得在 apt-p2p 看来,所有的请求均来自本机。
我使用的反向代理是 Pound,它在安装好后默认是禁用的。在 /etc/pound/pound.cfg 中配置好服务器后再到 /etc/default/pound 中启用它,然后使用 service 启动服务器即可。
我使用的配置如下:
...(keep default)
ListenHTTP
Address0.0.0.0
Port9978
## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
xHTTP 0
Service
BackEnd
Address127.0.0.1
Port9977
End
End
End
监听于 9978 端口,后台服务器在本机的 9977 端口。
这样一来,其他主机便也可以通过 9978 端口使用 apt-p2p 的缓存了。我的做法是在打算使用缓存的其他主机上将 /etc/apt/sources.list
移动到 /etc/apt/sources.list.d/50_main.list
,然后仿照缓存主机的软件源列表建立/etc/apt/sources.list.d/10_apt-p2p-home.list
,只是要把 url 中的localhost:9977
换成 <hostname-of-cache-server>.local:9978
即可,当然最好保持软件源服务器相同。这样 apt 会优先通过反向代理使用 apt-p2p 的缓存,当缓存不可用时仍可直接连接软件源服务器获取软件包:
10_apt-p2p-home.list:
deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing main
deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing main
deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian-security/ testing/updates main
deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian-security testing/updates main
deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ unstable main
deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ unstable main
50_main.list:
deb http://mirrors.ustc.edu.cn/debian/ testing main
deb-src http://mirrors.ustc.edu.cn/debian/ testing main
deb http://mirrors.ustc.edu.cn/debian-security/ testing/updates main
deb-src http://mirrors.ustc.edu.cn/debian-security testing/updates main
deb http://mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb-src http://mirrors.ustc.edu.cn/debian/ testing-proposed-updates main
deb http://mirrors.ustc.edu.cn/debian/ unstable main
deb-src http://mirrors.ustc.edu.cn/debian/ unstable main
如安装了 apt-transport-https,可以将 50_main.list 中的 http 换成 https。
这种以主机名加“.local”的域名格式是 mDNS/DNS-SD 协议提供的一种在广播域内定位主机和发布服务的方法,主要实现有 Avahi 和 Mac OS X 的 Bonjour。
这样一来,在局域网内,任何一台主机都优先通过 apt-p2p 获取软件包,一台更新可以惠及全家;即使短时间内更新多台主机,也只需要向软件源索取一次;而且大规模的数据流动发生在带宽很高的局域网内,更缩短了更新时间,提高了效率。
只是这样一来相当于在非缓存主机上配置了两个软件源,而当这两个软件源重复部分的信息不同步时(如笔记本计算机在局域网外更新了直连软件源服务器的软件包列表),apt-get source
是无法使用的,因为 apt 对源码包的检查更严格。
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-12/126548.htm