软件包代理缓存
如果你需要反复安装相同的 Arch 软件包(例如为了测试目的),如果不需要每次都从互联网获取软件包,将会非常有帮助。本文将向你展示如何共享软件包,从而大幅缩短下载时间。
哪种方案最好取决于你的具体使用场景。这些方法可以分为:在机器之间进行#软件包缓存共享,或者部署一个#代理服务器在单台机器上进行额外缓存,并相应地配置其他机器来使用它。
软件包缓存共享
对于所有共享软件包缓存的方案,请记住,默认情况下,pacman -Sc 会从缓存中删除那些在执行命令的机器上未安装的软件包压缩包。由于 pacman 无法预测共享缓存的所有机器上安装了哪些软件包,它最终会删除不应被删除的文件。
为了清理缓存且仅删除 过时 的压缩包
/etc/pacman.conf
[options] CleanMethod = KeepCurrent
只读缓存
Pacman 直接支持缓存服务器。缓存服务器将在任何非缓存服务器之前被尝试,且不会因为 HTTP 404 下载错误而被从服务器池中移除,并且不会被用于数据库文件。
如果你在寻找一个快速解决方案,你可以简单地运行一个基础的临时 Web 服务器,供其他计算机将其作为缓存服务器使用。
开始提供此目录的服务。例如,使用 Python 的 http.server 模块
$ python -m http.server -d /var/cache/pacman/pkg/
http.server 监听任何接口的 8000 端口。要使用其他端口或仅绑定到特定地址,只需添加一个参数和论据$ python -m http.server -d /var/cache/pacman/pkg/ --bind 127.0.0.1 8080
然后编辑每台客户端机器上的 /etc/pacman.d/mirrorlist 以添加此服务器
/etc/pacman.d/mirrorlist
CacheServer = http://server-ip:port
/repos/$repo/os/$arch,因为此层级结构并不存在,因此查询将会失败。如果寻找一个更独立的解决方案,darkhttpd 提供了一个非常精简的 Web 服务器。用例如以下命令替换之前的 python 命令:
[http]$ darkhttpd /var/cache/pacman/pkg --no-server-id
为了方便,你也可以将 darkhttpd 作为 systemd 服务运行:请参阅 Systemd#编写单元文件。
miniserve(一个用 Rust 编写的小型 Web 服务器)也可以使用
$ miniserve /var/cache/pacman/pkg
然后像上面一样编辑 /etc/pacman.d/mirrorlist,使用 miniserve 可用的第一个 URL。
如果你已经为了其他目的运行了一个 Web 服务器,你可能希望将其复用为你的本地仓库服务器。例如,如果你已经使用 nginx 提供站点服务,你可以添加一个监听 8080 端口的 nginx server 块
/etc/nginx/nginx.conf
server {
listen 8080;
root /var/cache/pacman/pkg;
server_name myarchrepo.localdomain;
try_files $uri $uri/;
}
记得在做出此更改后重启 nginx.service。
只读缓存的叠加挂载 (Overlay mount)
可以通过叠加挂载 (overlay mounting)局域网中某台机器的 /var/cache/pacman/pkg 目录,将其用作只读软件包缓存。如果该服务器上安装了相当全面的、且其他机器也需要的最新软件包,这种配置将非常有优势。这对于在低带宽上行连接环境下维护多台机器非常有用。
作为示例,使用此方法:
# mkdir /tmp/remote_pkg /mnt/workdir_pkg /tmp/pacman_pkg # sshfs remote_username@remote_pkgcache_addr:/var/cache/pacman/pkg /tmp/remote_pkg -C # mount -t overlay overlay -o lowerdir=/tmp/remote_pkg,upperdir=/var/cache/pacman/pkg,workdir=/mnt/workdir_pkg /tmp/pacman_pkg
/tmp/pacman_pkg 叠加目录时出现错误(例如 "Stale file handle"),请尝试使用选项 -o redirect_dir=off -o index=off 进行叠加挂载。之后,使用 --cachedir /tmp/pacman_pkg 选项运行 pacman,例如:
# pacman -Syu --cachedir /tmp/pacman_pkg
分布式只读缓存
有一些 Arch 特有的工具可以自动发现网络中提供软件包缓存的其他计算机。可以尝试 pacredir, pacserve, pkgdistcacheAUR, 或 paclanAUR。pkgdistcache 使用 Avahi 而非纯 UDP,这在某些通过路由而非桥接 Wi-Fi 和以太网的家庭网络中效果更好。
历史上曾有 PkgD 和 multipkg,但它们已不再维护。
读写缓存
为了在多台计算机之间共享软件包,只需使用任何基于网络的挂载协议共享 /var/cache/pacman/。本节将介绍如何使用 SSHFS 在同一局域网的多台计算机之间共享软件包缓存及相关的库目录。请记住,网络共享缓存的速度取决于文件系统的选择及其它因素。
首先,安装任何支持网络的文件系统软件包:sshfs, curlftpfs, samba 或 nfs-utils。
- 要使用 sshfs,建议阅读 使用 SSH 密钥。
- 默认情况下,smbfs 不提供包含冒号的文件名,这会导致客户端重新下载该有问题软件包。为了防止这种情况,请在客户端使用
mapchars挂载选项。
然后,为了共享实际的软件包,将服务器上的 /var/cache/pacman/pkg 挂载到每台客户端机器的 /var/cache/pacman/pkg。
/var/cache/pacman/pkg 或其任何父目录(例如 /var)设置为符号链接。Pacman 要求这些必须是目录。当 pacman 重新安装或升级自身时,它会删除符号链接并创建空目录。详情请参阅议题 pacman/pacman#5。使用 rsync 或 FTP 进行双向同步
本地环境中的另一种方法是使用 rsync。选择一台服务器用于缓存并启用 rsync 守护进程。客户端通过 rsync 协议与该共享目录进行双向同步。包含冒号的文件名对于 rsync 协议没有问题。
客户端的示例草案,在共享名称中使用 uname -m 可确保架构相关的同步
# rsync ... rsync://server/share_$(uname -m)/ /var/cache/pacman/pkg/ # pacman -Syu # paccache --remove --keep 3 # rsync --delete ... /var/cache/pacman/pkg/ rsync://server/share_$(uname -m)/
与其依赖未加密的 rsync 守护进程,更安全的选项是使用 rsync over ssh,Rsync#使用 SSH 自动备份 提供了概览。
如果你的本地环境中无法使用 rsync,简单的 FTP 服务也适用于双向同步。lftp 提供了 --mirror 和 --delete 选项来同步本地与远程存储。
使用同步程序同步 pacman 软件包缓存
使用 Syncthing 或 Resilio Sync 来同步 pacman 缓存目录(即 /var/cache/pacman/pkg)。
代理服务器
对于代理服务器方案,请记住机器应仅使用 HTTP 镜像,因为代理服务器默认无法审查 HTTPS 连接。
使用 nginx 实现动态反向代理缓存
nginx 可用于将软件包请求代理到官方上游镜像,并将结果缓存到本地磁盘。随后对该软件包的所有请求将直接由本地缓存提供,从而最大限度地减少更新大量计算机所需的互联网流量。
在本示例中,缓存服务器将运行在 http://cache.domain.example:8080/ 并将软件包存储在 /srv/http/pacman-cache/ 中。
在将托管缓存的计算机上安装 nginx。创建缓存目录并调整权限,使 nginx 可以向其中写入文件
# mkdir /srv/http/pacman-cache # chown http:http /srv/http/pacman-cache
使用 nginx pacman 缓存配置 作为 /etc/nginx/nginx.conf 的起点。检查 resolver 指令是否满足你的需求。在 upstream server 块中,使用官方镜像地址配置 proxy_pass 指令,具体格式请参考配置文件中的示例。对配置文件满意后,启动并启用 nginx。
为了使用缓存,每台 Arch Linux 计算机(包括托管缓存的那台)必须在 mirrorlist 文件的顶部添加以下行
/etc/pacman.d/mirrorlist
Server = http://cache.domain.example:8080/$repo/os/$arch ...
paccache(由 pacman-contrib 提供)可用于根据你选择的保留标准自动化此过程。例如,find /srv/http/pacman-cache/ -type d -exec paccache -v -r -k 2 -c {} \; 将在缓存目录中保留软件包的最后 2 个版本。Squid
Squid 代理可以设置为仅缓存 Arch 软件包,并且可以在客户端系统上进行极少配置的情况下与 aif/pacman/wget 等配合使用。
安装 Squid
安装 squid。
配置 Squid
这是让 squid 缓存 Arch 软件包的最小配置。
缓存规则
在定义这些规则之前,删除/注释掉所有默认的 refresh_patterns(如果你不需要它们的话)
/etc/squid/squid.conf
refresh_pattern \.pkg\.tar\. 0 20% 4320 reload-into-ims refresh_pattern . 0 0% 0
这应该定义了 *.pkg.tar.* 被缓存,而其他任何内容都不被缓存。
最大文件大小
大于此尺寸的对象将不会被保存到磁盘
/etc/squid/squid.conf
maximum_object_size 256 MB
缓存目录
设置缓存目录及其最大尺寸和子目录
/etc/squid/squid.conf
cache_dir aufs /var/cache/squid 10000 16 256
关闭等待时间
等待所有活动客户端套接字关闭的时间
/etc/squid/squid.conf
shutdown_lifetime 1 seconds
每当你更改 cache_dir 路径(以及在全新安装后),你需要(重新)创建此目录
# squid -z
并且在运行 squid 之前检查配置文件会很有帮助
# squid -k parse
启动 Squid
只需启动 squid.service,或者如果 squid 已经在运行,则重启它。
在运行之前检查配置文件会很有帮助
# squid -k check
查看 Squid 访问日志
查看对 squid 的访问情况
# tail -f /var/log/squid/access.log
对于定向到原始主机的软件包,你应该看到这个
...TCP_MISS/200...DIRECT...
而对于从缓存提供的软件包
...TCP_HIT/200...NONE...
手动 Arch 安装
在单个机器上,为你的代理添加环境变量。为了进行测试:
# export http_proxy='http://your_squid_machine_ip:3128/' # export ftp_proxy='ftp://your_squid_machine_ip:3128/'
现在它应该使用你的代理了。查看 squid 日志以验证。一旦运行成功,在安装系统的适当位置添加 http_proxy 和/或 ftp_proxy 变量,例如在 /etc/profile.d/proxy.sh 中。
拦截本地请求
如果你希望本地机器上的所有 HTTP 请求“自动”经过 squid,我们首先需要为 squid 添加一个拦截端口
/etc/squid/squid.conf
http_port 3127 intercept
以及 iptables 规则,将所有(除了来自 squid 自身的)80 端口请求重定向到 squid
# iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT # iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 3127
virtio 网络设备类型。Pacoloco 代理缓存服务器
Pacoloco 是一个易于使用的 pacman 仓库代理缓存服务器。它还允许自动预取缓存的软件包。
它可以作为 pacoloco 安装。打开配置文件并添加 pacman 镜像
/etc/pacoloco.yaml
port: 9129
repos:
mycopy:
urls:
- http://mirror.lty.me/archlinux
- http://mirrors.kernel.org/archlinux
重启 pacoloco.service,代理仓库将在 http://myserver:9129/repo/mycopy 可用。
Flexo 代理缓存服务器
Flexo 是另一个用于 pacman 仓库的代理缓存服务器。Flexo 可作为 flexo-gitAUR 获取。安装完成后,启动 flexo.service 单元。
Flexo 默认运行在 7878 端口。在你的 /etc/pacman.d/mirrorlist 顶部输入 Server = http://myserver:7878/$repo/os/$arch,这样 pacman 就会通过 Flexo 下载软件包。