Skip to content

混合架构 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,不等于它同时、完整、及时地镜像了 ubuntuubuntu-ports。选择镜像前必须分别确认。

用 deb822 明确 Architecture

较新的 Ubuntu 推荐 .sources deb822 格式。可以为不同架构建立独立 stanza:

text
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: arm64

Architectures 是 APT 官方支持的多值选项,用它限制每个源需要下载的索引,避免 amd64 源去请求 arm64 路径,或反过来。语法可查 Ubuntu sources.list(5)

Cross compile 与原生 arm64 runner 是两件事

原生 arm64 runner

dpkg --print-architecture 本身就是 arm64,只需要 arm64 archive。

amd64 上 cross compile

主机为 amd64,同时通过:

bash
dpkg --add-architecture arm64

安装 :arm64 依赖。此时必须同时配置:

  • amd64 source,Architectures: amd64
  • arm64 ports source,Architectures: arm64

否则 APT 会把所有 suite/URI 组合都尝试一遍,产生大量误导性的失败。

代理与 DIRECT 规则要和源拓扑一致

CI 网络经常同时有 HTTP 代理、旁路由和内部镜像。排查时先明确每个域名应该走哪条路径:

text
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 可以把基础镜像地址参数化:

dockerfile
ARG DOCKERHUB_PROXY
FROM ${DOCKERHUB_PROXY}/ubuntu:22.04

在 CI 中把 DOCKERHUB_PROXY 指向组织的 Harbor DockerHub proxy,例如 ${HARBOR_HOST}/dockerhub。登录时使用受保护变量和标准输入:

bash
printf '%s' "$HARBOR_PASSWORD" \
  | docker login "$HARBOR_HOST" -u "$HARBOR_USERNAME" --password-stdin

一套实用诊断顺序

  1. dpkg --print-architecture--print-foreign-architectures
  2. 展开所有 .list / .sources,检查 URI、suite、Architectures;
  3. 确认镜像同时覆盖需要的 archive;
  4. apt-get update -o Debug::Acquire::http=true 定位失败域名;
  5. 区分 DNS、代理、403、404 与 Release file 错误;
  6. 检查 runner 到内部 Harbor/GitLab 是否走直连;
  7. 最后再讨论换镜像或重试。

混合架构 CI 的关键不是找一个“最快源”,而是让架构、归档路径、网络出口和缓存层一一对应