混合架构 CI 的 APT 源:amd64 与 arm64 为什么要分开
同一套 CI 同时构建 amd64 工具和 arm64 板端包时,apt update 常出现 404、Release file 缺失、错误架构索引或镜像站偶发失败。根因往往不是网络本身,而是把两个 Ubuntu archive 拓扑当成一个源处理。
Ubuntu 的两个归档入口
通常:
- amd64 等主架构使用
archive.ubuntu.com/security.ubuntu.com; - arm64、armhf 等 ports 架构使用
ports.ubuntu.com/ubuntu-ports。
一个镜像站支持 Ubuntu,不等于它同时、完整、及时地镜像了 ubuntu 与 ubuntu-ports。选择镜像前必须分别确认。
用 deb822 明确 Architecture
较新的 Ubuntu 推荐 .sources deb822 格式。可以为不同架构建立独立 stanza:
Types: deb
URIs: https://mirror.example.com/ubuntu
Suites: jammy jammy-updates jammy-security
Components: main restricted universe multiverse
Architectures: amd64
Types: deb
URIs: https://mirror.example.com/ubuntu-ports
Suites: jammy jammy-updates jammy-security
Components: main restricted universe multiverse
Architectures: arm64Architectures 是 APT 官方支持的多值选项,用它限制每个源需要下载的索引,避免 amd64 源去请求 arm64 路径,或反过来。语法可查 Ubuntu sources.list(5)。
Cross compile 与原生 arm64 runner 是两件事
原生 arm64 runner
dpkg --print-architecture 本身就是 arm64,只需要 arm64 archive。
amd64 上 cross compile
主机为 amd64,同时通过:
dpkg --add-architecture arm64安装 :arm64 依赖。此时必须同时配置:
- amd64 source,
Architectures: amd64; - arm64 ports source,
Architectures: arm64。
否则 APT 会把所有 suite/URI 组合都尝试一遍,产生大量误导性的失败。
代理与 DIRECT 规则要和源拓扑一致
CI 网络经常同时有 HTTP 代理、旁路由和内部镜像。排查时先明确每个域名应该走哪条路径:
archive.ubuntu.com → DIRECT 或稳定镜像
security.ubuntu.com → DIRECT 或稳定镜像
ports.ubuntu.com → DIRECT 或 ports 镜像
内部 GitLab / Harbor → 内网直连不要只给 archive.ubuntu.com 配 DIRECT,却让 ports.ubuntu.com 继续经过不稳定代理;arm64 job 仍会失败。
DockerHub 镜像统一走 Harbor 代理
CI 不应让每个 runner 直接访问 DockerHub。Dockerfile 可以把基础镜像地址参数化:
ARG DOCKERHUB_PROXY
FROM ${DOCKERHUB_PROXY}/ubuntu:22.04在 CI 中把 DOCKERHUB_PROXY 指向组织的 Harbor DockerHub proxy,例如 ${HARBOR_HOST}/dockerhub。登录时使用受保护变量和标准输入:
printf '%s' "$HARBOR_PASSWORD" \
| docker login "$HARBOR_HOST" -u "$HARBOR_USERNAME" --password-stdin一套实用诊断顺序
dpkg --print-architecture与--print-foreign-architectures;- 展开所有
.list/.sources,检查 URI、suite、Architectures; - 确认镜像同时覆盖需要的 archive;
- 用
apt-get update -o Debug::Acquire::http=true定位失败域名; - 区分 DNS、代理、403、404 与 Release file 错误;
- 检查 runner 到内部 Harbor/GitLab 是否走直连;
- 最后再讨论换镜像或重试。
混合架构 CI 的关键不是找一个“最快源”,而是让架构、归档路径、网络出口和缓存层一一对应。