Skip to content

02 镜像同步(国内源 → Harbor)

2.1 镜像清单

源镜像(docker.m.daocloud.io)目标(192.168.122.156:30000)用途
jenkins/jenkins:lts-jdk21jenkins/jenkins:lts-jdk21Jenkins Controller
jenkins/inbound-agent:latest-jdk21jenkins/inbound-agent:latest-jdk21JNLP Agent 基础镜像
kiwigrid/k8s-sidecar:2.10.1jenkins/k8s-sidecar:2.10.1JCasC 配置热加载 sidecar
library/maven:3.9-eclipse-temurin-8jenkins/maven:3.9-eclipse-temurin-8Java 8 构建 Agent
library/maven:3.9-eclipse-temurin-21jenkins/maven:3.9-eclipse-temurin-21Java 21 构建 Agent
library/node:21-alpinejenkins/node:21-alpineNode.js 21 Agent
library/golang:1.24-alpinejenkins/golang:1.24-alpineGolang Agent
library/python:3.12-alpinejenkins/python:3.12-alpinePython Agent
library/sonarqube:lts-communitysonarqube/sonarqube:lts-communitySonarQube
library/postgres:16-alpinesonarqube/postgres:16-alpineSonarQube 数据库
library/busybox:1.36sonarqube/busybox:1.36sysctl 初始化容器

2.2 同步方式

使用 skopeo 直接 registry → registry 复制,无需本地 docker daemon, 无需配置 insecure-registry(skopeo 用 --tls-verify=false 即可访问 HTTP Harbor):

bash
skopeo copy --retry-times 3 \
  --src-tls-verify=false \
  --dest-tls-verify=false --dest-creds 'admin:xxx' \
  docker://docker.m.daocloud.io/jenkins/jenkins:lts-jdk21 \
  docker://192.168.122.156:30000/jenkins/jenkins:lts-jdk21

完整脚本见 scripts/sync-images.sh(正向顺序)与 scripts/sync-images-2.sh(并行反向顺序,加速整体进度)。

要点:

  • Harbor 目标项目需预先创建(jenkinssonarqube),或开启"自动创建项目"。
  • skopeo 复制多架构 manifest 时默认全量复制,Harbor 侧无需额外操作。
  • 镜像较大(sonarqube ≈ 750MB、jenkins ≈ 470MB),源站限速时总耗时约 30-60 分钟, 可如本次一样开两个并行任务分别按正/反顺序同步,重复推送已存在的 blob 会被 Harbor 秒过。

2.3 验证同步结果

bash
# 查看 jenkins 项目下所有仓库
curl -s -u 'admin:xxx' \
  'http://192.168.122.156:30000/api/v2.0/projects/jenkins/repositories?page_size=100' | jq -r '.[].name'

# 查看某镜像的 tag(注意仓库名中的 / 要转义为 %2F)
curl -s -u 'admin:xxx' \
  'http://192.168.122.156:30000/api/v2.0/projects/jenkins/repositories/maven/artifacts' \
  | jq -r '.[].tags[]?.name'

同步日志:logs/sync-images.loglogs/sync-images-2.log (最终同步结果见文末"执行记录")

2.4 执行记录

实际同步结果(2026-08-13,日志 logs/sync-images.log / sync-images-2.log / sync-images-3.log / sync-sonarqube.log):

镜像结果耗时参考
jenkins/inbound-agent:latest-jdk2122:21→22:28(约 8 分钟)
jenkins/jenkins:lts-jdk2123:10→23:23
jenkins/maven:3.9-eclipse-temurin-2123:23→00:05
jenkins/maven:3.9-eclipse-temurin-800:05→00:10
jenkins/node:21-alpine / golang:1.24-alpine / python:3.12-alpine小镜像,秒级
sonarqube/postgres:16-alpine / busybox:1.36秒级
sonarqube/sonarqube:lts-community约 750MB,源站限速耗时最长(重试过一次,最终 Storing signatures 完成)
jenkins/k8s-sidecar:2.10.1、jenkins/frpc:0.69.1后续补充同步(JCasC 热加载、公网接入)

验证命令与输出(Harbor API):

bash
curl -s -u 'admin:xxx' \
  'http://192.168.122.156:30000/api/v2.0/projects/jenkins/repositories?page_size=100' | jq -r '.[].name'
# 输出: jenkins/frpc  jenkins/golang  jenkins/inbound-agent  jenkins/jenkins
#       jenkins/k8s-sidecar  jenkins/maven  jenkins/node  jenkins/python

2.5 踩坑记录:节点拉取 Harbor HTTP 镜像失败

部署时发现所有节点拉取 Harbor 镜像报 http: server gave HTTP response to HTTPS client, 但节点上已有 116 个使用 Harbor 镜像的容器在运行(均为本地缓存镜像)。

根因:节点 /etc/rancher/rke2/registries.yaml(当日被 RKE2 升级工作修改)中 configs."192.168.122.156:30000" 只配置了 insecure_skip_verify(仍是 HTTPS), mirrors 只配了不带端口的 192.168.122.156*,导致带端口的镜像地址走了 HTTPS。

修复(所有节点执行,脚本 scripts/fix-node-registry.sh):

  1. registries.yaml 增加 mirrors."192.168.122.156:30000".endpoint: ["http://192.168.122.156:30000"](持久化,RKE2 重启后仍生效)
  2. 同时直接修改 containerd 热加载的 /var/lib/rancher/rke2/agent/etc/containerd/certs.d/192.168.122.156:30000/hosts.tomlserver = "https://..."http://...立即生效,无需重启 rke2

验证:测试 Pod 拉取 jenkins/k8s-sidecar:2.10.1 成功。