本篇文章将继续介绍这个仅有 2MB+ 身材大小的 Linux 软件包缓存和加速工具:APT Proxy。

相比老牌的 apt cacher ng 而言,除了尺寸更小、内存占用更低(10M以内)、它还拥有无需配置,开箱即用等特点。

写在前面

年中的时候,曾写过一篇文章《轻量小巧的零配置 APT 加速工具:APT Proxy》,当时介绍了我写的一款新工具 APT Proxy,2MB 的身材之下,可以为 Ubuntu 和 Debian 的软件下载提速。尤其是当你需要为多台设备更新和安装软件的时候,提升下载软件包的速度非常明显。

Apt Proxy 的概览页面

在文章和程序发布不久,群里有两位同学提出能否支持 CentOS 的下载加速,之后又有一位同学提出了能否支持 Alpine (容器世界亲儿子系统之一)。虽然口头答应了群友,但是因为最初设计只是为 Debian / Ubuntu 系统而写的,如果要支持其他系统,需要费一番功夫,加上事情比较多,这件事就搁置了下来。

临近年终,为了避免失信于人,我重构了 APT Proxy ,代码开源在 https://github.com/soulteary/apt-proxy,有需要的同学可以自取。(开源不易,欢迎一键三连。)

下面,我们来一起看看如何玩转 APT Proxy,来节约日常使用 Linux 下载软件包的时间。

基础使用

APT Proxy 支持两种方式运行,一种是直接运行“可执行文件”,另外一种是使用 Docker 来运行。至于使用哪一种,可以根据你的喜好,或者你要运行程序的机器状况而定。

我们先来聊聊第一种使用方式,因为关于 Docker 的使用方式,其实并没有什么不同。如果你是 Docker 爱好者,可以在阅读完本小节之后,移步文末“玩法五”。

你可以在 GitHub Release 页面 找到包含 32 位和 64 的 x86 或者 ARM 的可执行文件。我们根据设备的类型,下载好可执行文件之后,直接运行 ./apt-proxy 将能得到类似下面的日志:

2022/11/20 00:39:48 running apt-proxy 
2022/11/20 00:39:49 Start benchmarking mirrors
2022/11/20 00:39:49 Finished benchmarking mirrors
2022/11/20 00:39:49 using fastest Ubuntu mirror http://mirror.bjtu.edu.cn/ubuntu/
2022/11/20 00:39:49 Start benchmarking mirrors
2022/11/20 00:39:49 Finished benchmarking mirrors
2022/11/20 00:39:49 using fastest Debian mirror https://mirror.bjtu.edu.cn/debian/
2022/11/20 00:39:49 Start benchmarking mirrors
2022/11/20 00:39:49 Finished benchmarking mirrors
2022/11/20 00:39:49 using fastest CentOS mirror https://mirrors.bupt.edu.cn/centos/
2022/11/20 00:39:49 Start benchmarking mirrors
2022/11/20 00:39:49 Finished benchmarking mirrors
2022/11/20 00:39:49 using fastest Alpine mirror https://mirrors.tuna.tsinghua.edu.cn/alpine/
2022/11/20 00:39:49 proxy listening on 0.0.0.0:3142
2022/11/20 00:39:49 Program has been started 🚀

当我们看到 Program has been started 的字样时,说明程序已经正常运行起来了。从日志中可以看到,程序自动寻找了我们访问速度最快的各个操作系统的软件源。接下来,我们只需要在不同的操作系统中设置使用软件源为运行 APT Proxy 的这台设备的地址即可。

为了行文方便,我们暂定运行 APT Proxy 的这台设备 IP 为 10.11.12.90,如果你在上手试用,需要根据自己的实际情况,调整下文中的命令中的 IP 地址。

当然,如果我们想了解软件的运行状况,可以在浏览器中访问运行 APT Proxy 的设备的 IP + 3142 端口,比如: http://10.11.12.90:3142,就能够看到上文中的界面啦。

为 Ubuntu / Debian 进行缓存软件,加速 APT 下载

在不使用 APT Proxy 的时候,我们想要更新和安装软件(比如 vim),会使用下面的命令:

apt-get update
apt-get install vim -y

为了方便后边进行效果对比,我们在命令前添加一个 time 命令,来进行粗略的计时:

# time (apt-get update && apt-get install -y vim)

Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [522 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [114 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-backports InRelease [99.8 kB]
...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

real	0m20.639s
user	0m4.018s
sys	0m1.991s

在不对系统做任何调整(修改文件等)的前提下,我们可以通过简单改写命令,对系统下载的软件包的目标源进行自动替换,以及缓存下载过的软件包,加速这台和其他设备的软件包下载所需要使用的时间。

# `apt-get update` 改写
http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true update 

# `apt-get install vim -y` 改写
http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true install vim -y

在执行命令的时候,我们可以看到 Ubuntu / Debian 中的日志虽然展示数据下载地址还是“系统默认”的地址,但其实软件已经在后台自动将请求数据切换到了探测到的最快的下载镜像源上了,并对数据进行了缓存(为了方便对比速度提升,同样在命令开头添加一个 time 命令):

# time (http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true update && http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true install vim -y)
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [114 kB]
Get:4 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [767 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-backports InRelease [99.8 kB]
...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

real	0m22.596s
user	0m3.875s
sys	0m2.117s

这里因为软件会先将我们请求的数据进行缓存(磁盘写入)后,再提供给系统使用,所以首次使用的时候,在时间数据上有可能甚至会比直接在系统中执行软件包的下载安装要慢一些(比如这个例子中,要比原始请求慢 1~2s)。

在 APT Proxy 的日志中,我们能看到系统实际请求的外部资源,一旦程序发现资源在本地不存在(MISS)就会进行缓存,并根据资源类型设置不同时间的缓存有效期。

2022/11/20 14:07:58 rewrote "http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease" to "https://mirror.bjtu.edu.cn/ubuntu/dists/jammy/InRelease"
2022/11/20 14:07:58 rewrote "http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease" to "https://mirror.bjtu.edu.cn/ubuntu/dists/jammy-security/InRelease"
2022/11/20 14:07:58 10.11.12.90 "GET https://mirror.bjtu.edu.cn/ubuntu/dists/jammy-security/InRelease HTTP/1.1" (OK) 110337 MISS 88.932983ms
2022/11/20 14:07:58 rewrote "http://security.ubuntu.com/ubuntu/dists/jammy-security/universe/binary-amd64/by-hash/SHA256/332b5fd83a61f44ad15bc053370645ff347d7e29d6fbc12189602929bb25884c" to "https://mirror.bjtu.edu.cn/ubuntu/dists/jammy-security/universe/binary-amd64/by-hash/SHA256/332b5fd83a61f44ad15bc053370645ff347d7e29d6fbc12189602929bb25884c"
2022/11/20 14:07:59 10.11.12.90 "GET https://mirror.bjtu.edu.cn/ubuntu/dists/jammy/InRelease HTTP/1.1" (OK) 270087 MISS 203.295175ms
2022/11/20 14:07:59 rewrote "http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease" to "https://mirror.bjtu.edu.cn/ubuntu/dists/jammy-updates/InRelease"
...

重点来了,当我们为这台 Ubuntu 设备或者其他新设备执行相同命令的时候,如果软件的缓存没有过期,那么我们的下载速度将会得到质的提升(相比上文中,时间缩短到原本的 1/3,数据下载量越大,效果会越明显):

# time (http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true update && http_proxy=http://10.11.12.90:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true install vim -y)
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [114 kB]
...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

real	0m6.485s
user	0m3.558s
sys	0m1.841s

Debian 系统和 Ubuntu 系统的使用方面基本没有区别,这里就不做重复展开啦。

目前,经过测试验证的操作系统有:Ubuntu 16.04、Ubuntu 18.04、Ubuntu 22.04、Debian 10(buster)、Debian 11(bullseye)。

为 CentOS 系统进行软件包下载加速

在这次的更新中,APT Proxy 支持了 CentOS 的软件包加速和缓存,分别支持 CentOS 7 和 CentOS 8。

在 CentOS 7 中,我们需要先使用下面的命令,对系统的软件源进行调整:

cat /etc/yum.repos.d/CentOS-Base.repo | sed -e s/mirrorlist.*$// | sed -e s/#baseurl/baseurl/ | sed -e s#http://mirror.centos.org#http://10.11.12.90:3142# | tee /etc/yum.repos.d/CentOS-Base.repo

而在 CentOS 8 中,命令需要调整为下面这样:

sed -i -e"s#mirror.centos.org#10.11.12.90:3142#g" /etc/yum.repos.d/CentOS-*
sed -i -e"s/#baseurl/baseurl/" /etc/yum.repos.d/CentOS-*
sed -i -e"s#\$releasever/#8-stream/#" /etc/yum.repos.d/CentOS-*

在完成软件源的调整后,我们执行 yum update && yum install -y vim 就可以享受自动选择最快的软件源,以及局域网中其他设备的软件包下载提速啦。

为 Alpine 系统进行软件包下载加速

在这次的 APT Proxy 软件版本更新中,也支持了 Alpine 的软件包加速和缓存,支持 Alpine 全系列的加速。

在 3.13 版本及以上,我们使用下面的命令,调整软件源对系统进行加速:

cat /etc/apk/repositories | sed -e s#https://.*.alpinelinux.org#http://10.11.12.90:3142# | tee /etc/apk/repositories

然后执行 apk add vim 即可完成软件的下载和缓存。

在 3.13 版本一以下的系统中,我们需要使用下面的命令调整软件源:

cat /etc/apk/repositories | sed -e s#http://.*.alpinelinux.org#http://10.11.12.90:3142# | tee /etc/apk/repositories

并在执行 apk add 之前,先执行 apk update 刷新系统的软件包索引文件,再执行 apk add vim 来完成我们想要安装的软件的下载。

聊过了基础使用,下面来聊聊日常开发、学习过程中,APT Proxy 的一些玩法。

玩法一:为本地容器中的 Linux 操作系统加速

日常进行软件开发的过程中,我会经常使用跑在容器里的 Linux 操作系统,比如上面提到的 Ubuntu、Debian、Alpine、CentOS,在构建产物镜像的时候(尤其是调试最小尺寸的 Docker 镜像时),经常会重复下载一些软件包,这个时候,使用 APT Proxy 就能够节约大量的时间

那么,如果我们是在主机上启动的 APT Proxy,在同一台主机运行的容器除了直接像上文一样,访问主机的物理 IP 之外,有没有什么更简单的访问方式呢?尤其是主机是笔记本这类在办公室和家里 IP 会变化的设备。

如果我们的容器是在 APT Proxy 所在的主机上运行的,可以通过访问 http://host.docker.internal:3142 这个 Docker 的“魔术地址”,来替换上文中的 10.11.12.90 这类或许会出现变化的地址。

比如,我们运行了某个基于 Linux 的应用镜像之后(docker run --rm -it ubuntu:22.04 bash),将上文中的命令替换为下面这样:

http_proxy=http://host.docker.internal:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true update && http_proxy=http://host.docker.internal:3142 apt-get -o pkgProblemResolver=true -o Acquire::http=true install vim -y

玩法二:为局域网中多台 Linux 设备加速

许多朋友和我一样,家里、公司都有许多设备(物理机、虚拟机、云服务器),这些设备的日常维护中,有一项就是在设备上批量执行类似 apt update && apt upgrade -y 来升级系统。即时命令能够批量远程执行,但是机器数量一多,软件下载的时间成本也不低。

所以,如果我们在局域网其中的一台设备上运行了 APT Proxy,就可以和上文中一样,在其他的设备中通过调整软件源、或者改写软件包下载命令,来获得非常快速的重复的软件包的下载,节约维护设备软件包所需要的时间。

类似的思路,其实 Windows 和 MacOS 也都有,Linux 中这块做的比好的软件是 Nexus,我在早些时候,有分享过《使用 Docker 搭建私有软件仓库 Nexus 3》等内容,感兴趣的同学可以自行翻阅。不过,APT Proxy 在这个场景下,拥有绝对的优势,不需要 Nexus 几百 MB 的容器大小,以及运行起来大几百 MB 、甚至上 GB 的内存占用,只需要 2MB 的身材,以及最多十来 MB 的内存使用。

玩法三:自动寻找最快的软件源

在玩 Linux 的过程中,Ubuntu 、Alpine 的软件用户经常会羡慕 CentOS 用户,因为 CentOS 拥有一个神奇的插件:Fastest Mirror,会自动选择最快的软件源,来节约用户下载软件包的时间。

Ubuntu、Alpine 用户们,想要达到相同的效果,除了要收集可以用的软件源之外,还得挨着测试哪个软件源对自己来说性价比更高,着实麻烦。

APT Proxy 内置了各种操作系统中的官方的软件源,以及加上了国内常用,但可能没有被操作系统官方收录的软件源。在启动的时候会自动进行速度探测,然后进行选取。如果你像上文一样,将系统软件源切换到了 APT Proxy 的服务地址,那么软件下载的时候,将自动切换到最快的地址,避免了上面的“麻烦”的过程。

你可能会好奇,是否有自动选择软件源的必要,其实是有的。因为在不同的时间段,我们知道的软件源的实时负载是不同的,我们的网络运营商也可能会对我们的网络进行动态的线路调整,自动选择服务器能够让我们避开“排队”,以及少绕弯路,选择此时此刻对我们来说最佳的选择。

玩法四:指定自己想用的软件源

多数场景下,不对 APT Proxy 进行设置,让它使用自动选择出来的软件源就足够使用了。但是,如果你只信任某些软件源,也可以通过参数来进行手动干预,甚至相比一些软件,你可以手动分别定制 Ubuntu、Debian、CentOS、Alpine 的软件源:

./apt-proxy --ubuntu=cn:ustc --debian=cn:huaweicloud --centos=cn:aliyun --alpine=cn:tsinghua

在软件执行之后,我们可以看到类似下面的提示,告诉我们指定的软件源设置成功与否:

2022/11/20 16:02:34 running apt-proxy 
2022/11/20 16:02:34 using specify Ubuntu mirror http://mirrors.ustc.edu.cn/ubuntu/
2022/11/20 16:02:34 using specify Debian mirror http://mirrors.huaweicloud.com/debian/
2022/11/20 16:02:34 using specify CentOS mirror http://mirrors.aliyun.com/centos/
2022/11/20 16:02:34 using specify Alpine mirror http://mirrors.tuna.tsinghua.edu.cn/alpine/
2022/11/20 16:02:34 proxy listening on 0.0.0.0:3142
2022/11/20 16:02:34 Program has been started 🚀

当然,如果你发现某些软件源的访问质量不高,重新启动 APT Proxy,让它进行自动选择,或者你换一个指定的源头就好啦,反正也没有什么成本。

你可以在 soulteary/apt-proxy/tree/main/internal/define 中找到程序内置的官方认可或者国内比较知名的,相对稳定的软件源地址,它们的根域名名称,就是能够使用的“加速别名”,比如 mirrors.tuna.tsinghua.edu.cn 的别名就是去掉域名类型 edu.cntsinghua

玩法五:搭配容器做一个“干净又卫生”的临时加速器

APT Proxy 运行起来,默认会将缓存的文件保存在程序运行目录下的 .aptcache 目录,如果我们使用容器来运行它,不将这个目录进行“数据持久化”,以及在 Docker 运行容器的参数中添加上 --rm ,当我们停止或者重启容器的运行时,APT Proxy 的缓存也就被自动清理啦,不必担心经年累月在磁盘上残留的各种“过时”数据。

至于如何低成本定时清理数据,或许你可以参考上一篇分享的内容《使用 Docker 和 Traefik 搭建轻量美观的计划任务工具》中提到的工具。

# 建议始终执行命令,尝试下载更新软件新版本
docker pull soulteary/apt-proxy:latest
docker run --rm -d --name apt-proxy -p 3142:3142 soulteary/apt-proxy

如果你希望数据能够被持久化,那么可以调整命令,将数据目录挂载出来:

docker run --rm -d --name apt-proxy -p 3142:3142 -v `pwd`/.aptcache:/.aptcache soulteary/apt-proxy

使用方法和上文中提到的没有差别,就不再赘述啦。

最后

好啦,这篇文章就先写到这里。如果你在使用 APT Proxy 的过程中遇到了问题,欢迎反馈。

希望这个小工具,能够让你变的更“懒”一些。

–EOF