Skip to content

Rancher Monitoring 109.0.4+up80.9.1-rancher.18 镜像离线收集推送手册

  • 日期:2026-08-01
  • Chartrancher-monitoring 109.0.4+up80.9.1-rancher.18(appVersion v0.87.1,上游 kube-prometheus-stack)
  • 目标仓库:Harbor 192.168.122.156:30000,项目 rancher(HTTP 明文,已在 docker daemon insecure-registries 中注册)
  • 镜像源:DaoCloud 镜像站 docker.m.daocloud.io / 华为云 SWR swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/(免翻墙拉取 docker.io)
  • 结果:22 个镜像全部推送成功,主架构(linux/amd64,windows-exporter 为 windows/amd64)可用

1. 背景与目标

内网/离线环境部署 Rancher Monitoring 时,集群无法直接访问 docker.io。需要:

  1. 从 chart 包中完整提取该版本依赖的全部镜像清单(不能漏掉 init 容器、sidecar 等);
  2. 通过国内镜像源拉取,推送到内网 Harbor;
  3. 保持 rancher/xxx:tag 原始路径不变,部署时只需设置全局 systemDefaultRegistry,无需逐条改 values。

2. 工具准备

工具版本用途
helmv3.19.4下载 chart、渲染模板
skopeo1.4.1跨仓库复制镜像(无需 docker pull,省本地磁盘)
python3 + pyyaml3.x / 6.0.2解析 values.yaml 提取镜像
curl-Harbor API 验证
bash
# 登录目标仓库(skopeo 凭据与 docker 独立存储)
skopeo login --tls-verify=false -u <用户> -p '<密码>' 192.168.122.156:30000

# 确认 Harbor 项目存在(push 前项目必须先创建, Harbor 不会自动建项目)
curl -s -u '<用户名>:<密码>' \
  "http://192.168.122.156:30000/api/v2.0/projects?name=rancher"

3. 提取镜像清单

3.1 下载 chart

bash
mkdir -p ~/monitoring-images && cd ~/monitoring-images
helm repo add rancher-charts https://charts.rancher.io
helm repo update
helm pull rancher-charts/rancher-monitoring --version "109.0.4+up80.9.1-rancher.18"
tar xzf rancher-monitoring-109.0.4+up80.9.1-rancher.18.tgz

3.2 渲染模板 + 解析 values 双保险

只用 helm template 会漏掉默认未启用组件的镜像(windows-exporter、thanos、image-renderer 等);只 grep values 又处理不了 repository + tag 拼接和子 chart。因此两步结合:

bash
# ① 渲染默认模板,抓字面值 image:
helm template monitoring ./rancher-monitoring --namespace cattle-monitoring-system > rendered.yaml

# ② Python 遍历主 chart 与全部子 chart 的 values.yaml,
#    提取 {registry, repository, tag} 组合与字面值 image,与 ① 合并去重
python3 extract.py | sort -u > images.txt   # 脚本见附录 A

本版本提取结果共 22 个镜像,全部位于 docker.io/rancher/ 命名空间下(清单见附录 B)。

4. 推送镜像到私有仓库

4.1 推送脚本(skopeo 免本地存储)

bash
#!/bin/bash
SRC_REGISTRY="docker.m.daocloud.io"          # DaoCloud 国内源
# SRC_REGISTRY="swr.cn-north-4.myhuaweicloud.com"  # 或华为云 SWR(源地址需拼 ddn-k8s/docker.io/ 前缀)
DST_REGISTRY="192.168.122.156:30000"
LIST="./images.txt"

while IFS= read -r img; do
  [ -z "$img" ] && continue
  skopeo copy --all --retry-times=3 \
    --dest-tls-verify=false \
    "docker://${SRC_REGISTRY}/${img}" \
    "docker://${DST_REGISTRY}/${img}" \
  && echo "OK  $img" || echo "FAIL $img"
done < "$LIST"

使用 SWR 源时源地址为: docker://swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/rancher/xxx:tag

4.2 踩坑记录(重点)

问题现象原因与解法
skopeo 1.4.1 复制含证明层镜像失败unsupported MIME type for compression: application/vnd.in-toto+jsonbuildkit 构建的镜像带有 in-toto attestation 层,--all 重建 manifest 列表时老版本 skopeo 无法处理。解法:放弃 --all,按架构单独复制:skopeo copy --override-os linux --override-arch amd64 ...
skopeo 1.4.1 无 --preserve-digestsunknown flag该参数为新版 skopeo 才有;--format oci 也不能绕过上述 bug
华为云 SWR 匿名拉取限流denied: You may not login yetSWR 对匿名 token 请求限频,隔几分钟后重试即可;--retry-times 对该错误无效(发生在取 token 阶段)
SWR ddn-k8s 镜像为扁平单架构推送后 skopeo inspect --raw 只见一个 manifestddn-k8s 同步时只保留了单架构。若需多架构请用 DaoCloud 源 + --all
Harbor API 列表"缺仓库"假象/projects/rancher/repositories 返回不全接口分页默认每页 100,项目已有 100+ 仓库时须翻页;以 artifact 级查询为准
Windows 镜像复制默认按 host 平台(linux)选 manifest 失败显式指定 --override-os windows --override-arch amd64

本次实际操作中,22 个镜像经 DaoCloud 源推送 16 个成功;6 个含 attestation 层的镜像(kuberlr-kubectlgrafana-image-rendererkube-webhook-certgennginxwindows-exporterpushprox)改用 --override-os/--override-arch 单架构推送成功。本环境集群为 amd64,单架构满足需求。

5. 验证

artifact 级查询为准(不受分页影响):

bash
miss=0
while IFS= read -r img; do
  [ -z "$img" ] && continue
  repo_name="${img#rancher/}"; repo_name="${repo_name%:*}"; tag="${img##*:}"
  code=$(curl -s -o /dev/null -w "%{http_code}" -u '<用户名>:<密码>' \
    "http://192.168.122.156:30000/api/v2.0/projects/rancher/repositories/${repo_name}/artifacts/${tag}")
  [ "$code" != "200" ] && { echo "MISSING: $img"; miss=$((miss+1)); }
done < images.txt
echo "缺失: $miss / $(grep -c . images.txt)"   # 期望输出: 缺失: 0 / 22

查看镜像架构:

bash
skopeo inspect --tls-verify=false \
  docker://192.168.122.156:30000/rancher/prom-prometheus:v3.8.1 | python3 -c \
  "import json,sys; d=json.load(sys.stdin); print(d['Os'], d['Architecture'])"

6. 集群侧使用

镜像路径与 docker.io 原始路径完全一致,部署时只需指向私有仓库:

  • Rancher UI:全局设置 → System Default Registry 设为 192.168.122.156:30000
  • 或 Helm values:
yaml
global:
  cattle:
    systemDefaultRegistry: 192.168.122.156:30000

节点 containerd 需将 192.168.122.156:30000 配置为 HTTP 仓库(insecure),或在 registries.yaml 中声明。

附录 A:镜像提取脚本 extract.py

python
#!/usr/bin/env python3
"""提取 rancher-monitoring chart 全部容器镜像(values + 渲染模板)"""
import yaml, glob, re, sys

images = set()

def walk(node):
    if isinstance(node, dict):
        if isinstance(node.get("repository"), str):
            repo = node["repository"]
            tag = node.get("tag")
            registry = node.get("registry")
            if tag not in (None, ""):
                full = f"{repo}:{tag}"
                if isinstance(registry, str) and registry:
                    full = f"{registry}/{full}"
                images.add(full)
        if isinstance(node.get("image"), str) and ":" in node["image"] and " " not in node["image"]:
            images.add(node["image"])
        for v in node.values():
            walk(v)
    elif isinstance(node, list):
        for v in node:
            walk(v)

files = ["rancher-monitoring/values.yaml"] + glob.glob("rancher-monitoring/charts/*/values.yaml")
for f in files:
    for d in yaml.safe_load_all(open(f)):
        if d:
            walk(d)

for m in re.finditer(r'image:\s*"?([^\s"]+)"?', open("rendered.yaml").read()):
    if "{{" not in m.group(1):
        images.add(m.group(1))

for img in sorted(images):
    img = img.lstrip("/")
    if ":" in img.split("/")[-1]:
        print(img)

附录 B:完整镜像清单(22 个)

rancher/appco-alertmanager:0.30.0-12.16
rancher/appco-grafana:12.3.1-1.12
rancher/appco-k8s-sidecar:2.1.2-1.10
rancher/appco-kube-rbac-proxy:0.20.1-16.14
rancher/appco-kube-rbac-proxy:0.20.1-16.15
rancher/appco-kube-state-metrics:2.17.0-10.14
rancher/appco-node-exporter:1.10.2-14.3
rancher/appco-thanos:0.40.1-8.1
rancher/kuberlr-kubectl:v7.1.1
rancher/mirrored-curlimages-curl:8.20.0
rancher/mirrored-grafana-grafana-image-renderer:v5.10.1-1
rancher/mirrored-jkroepke-kube-webhook-certgen:1.7.4
rancher/mirrored-library-busybox:1.31.1
rancher/mirrored-library-busybox:1.37.0
rancher/mirrored-library-nginx:1.31.3-alpine
rancher/mirrored-prometheus-adapter-prometheus-adapter:v0.12.0
rancher/mirrored-prometheus-operator-admission-webhook:v0.87.1
rancher/mirrored-prometheus-operator-prometheus-config-reloader:v0.87.1
rancher/mirrored-prometheus-operator-prometheus-operator:v0.87.1
rancher/mirrored-prometheus-windows-exporter:0.31.3
rancher/prom-prometheus:v3.8.1
rancher/pushprox:v0.1.11