Design wechseln

Docker-Mirror-Geschwindigkeitstest in der Praxis: 3 Methoden + Skript zum automatischen Wechsel

Easton editorial illustration: large image-pull speedometer with one winning range

Kennen Sie das? Ihre CI/CD-Pipeline hängt bei docker pull bei 99 % fest, im Log erscheinen immer wieder „connection timeout“ und „TLS handshake timeout“, und Ihr Deployment steht seit zehn Minuten still.

Letzte Woche ist mir genau das passiert. Kein Mitternachts-Deployment-Desaster – aber sieben Wiederholungsversuche, jedes Mal manuell den Mirror wechseln, Docker-Daemon neu starten: fast eine halbe Stunde Arbeit. Am nervigsten: Sie wissen nicht, welcher Mirror gerade funktioniert. Alibabas Accelerator drosselt auf Nicht-Alibaba-Servern stark, der Mirror der USTC wurde im Juni letzten Jahres eingestellt, und bei manchen angeblichen „High-Speed“-Quellen ist die Erreichbarkeit selbst unsicher.

Das wirft eine Frage auf: Wie finden Sie schnell den schnellsten Mirror für Ihre aktuelle Netzwerkumgebung?

In diesem Artikel liste ich nicht einfach Mirror-Adressen zum Ausprobieren auf – davon gibt es genug. Stattdessen geht es um die technischen Grundlagen des Geschwindigkeitstests, Vor- und Nachteile dreier Methoden sowie zwei fertige Automatisierungsskripte (Shell und Python). Abschließend teile ich Messdaten chinesischer Mirror-Quellen vom Mai 2026 und zeige, welche Quellen heute wirklich nutzbar sind.


Geschwindigkeitstest-Methoden im Vergleich – Ping, HTTP HEAD und echter Pull

Für Mirror-Quellen gibt es drei gängige Testmethoden: Ping-Test, HTTP-HEAD-Test und tatsächliches Image-Pull. Jede hat ihre Stärken und Schwächen – die Unterschiede in einer Tabelle:

MethodePrinzipVorteileNachteileEinsatz
Ping-TestICMP-AntwortzeitEinfach, schnellSpiegelt keine echte Download-Geschwindigkeit wider; manche Server blockieren PingErste Vorauswahl
HTTP-HEAD-TestRegistry-API-Endpunkt /v2/Standard-API, prüft V2-UnterstützungNur Erreichbarkeit, keine Download-GeschwindigkeitVerfügbarkeitsprüfung
Echter Pull-Testdocker pull eines echten ImagesGenaueste Abbildung der realen GeschwindigkeitLangsam, bandbreitenintensivFinale Validierung

Warum reicht Ping nicht aus?

Viele greifen zuerst zu ping – ein Befehl, sofort Latenz sichtbar. Ping misst aber ICMP-Antworten, die mit dem eigentlichen Image-Download wenig gemein haben.

Beispiel: Manche Mirror-Server deaktivieren ICMP (häufig aus Sicherheitsgründen bei Cloud-Anbietern). Ping zeigt Timeout, HTTP-Anfragen funktionieren aber einwandfrei. Umgekehrt: Manche CDN-Knoten pingen mit 20 ms – der HTTP-Download ist wegen Routing, TLS-Handshake und Bandbreitenlimits trotzdem langsam.

HTTP-HEAD-Test – der Standardweg

Die Docker Registry API v2 definiert einen Health-Check-Endpunkt: /v2/. Senden Sie einen HEAD- oder GET-Request dorthin und erhalten 200 OK, unterstützt die Registry V2 und ist erreichbar.

Kernlogik:

curl -I -m 5 https://docker.xuanyuan.me/v2/

Bei HTTP/2 200 ist der Mirror erreichbar. Die Antwortzeit (Request bis Header) gibt grob die Netzwerklatenz an – keine Download-Geschwindigkeit, aber Erreichbarkeit und Reaktionszeit.

Echter Pull-Test: die zuverlässigste Validierung

Am verlässlichsten ist docker pull eines echten Images. Ich nutze oft Alpine (~5 MB) – klein, schnell, wenig Bandbreite.

time docker pull alpine:latest

Achten Sie auf real – die Gesamtzeit vom Start bis zum Abschluss. Daraus lässt sich die durchschnittliche Download-Geschwindigkeit (Image-Größe / Zeit) ableiten – so erleben Sie es im Deployment.

Nachteil: langsam. Ein Mirror dauert Sekunden bis Minuten, zehn Mirrors entsprechend mehreren Minuten. Außerdem beeinflussen Cache-Unterschiede die Fairness – manche Quellen haben Alpine bereits gecacht, andere nicht.


Mein Vorschlag: Zuerst per HTTP HEAD erreichbare Mirrors filtern (nicht erreichbare und langsame aussortieren), dann die schnellsten 3–5 per echtem Pull verifizieren. Effizient und verlässlich.


Shell-Skript – Geschwindigkeitstest und automatischer Wechsel mit einem Klick

Für Ops oder Server-Tüftler ist ein Shell-Skript oft am schnellsten einsatzbereit. Mein Skript testet parallel, sortiert automatisch und aktualisiert daemon.json – direkt verwendbar.

Kernlogik: paralleler Test + automatische Sortierung

Ablauf: Mirror-Liste definieren, mit curl die Antwortzeit von /v2/ messen, sortieren, die schnellsten auswählen und /etc/docker/daemon.json anpassen.

Die Testfunktion:

#!/bin/bash

# Mirror-Liste (Mai 2026, getestet verfügbar)
MIRRORS=(
    "https://docker.xuanyuan.me"
    "https://docker.1ms.run"
    "https://docker.m.daocloud.io"
    "https://atomhub.openatom.cn"
)

# Antwortzeit eines einzelnen Mirrors (Millisekunden)
test_mirror() {
    local mirror=$1
    local start=$(date +%s%N)
    local http_code=$(curl -s -o /dev/null -w "%{http_code}" \
        --connect-timeout 5 \
        --max-time 10 \
        "$mirror/v2/")
    local end=$(date +%s%N)
    local elapsed=$(( (end - start) / 1000000 ))

    if [[ "$http_code" == "200" ]]; then
        echo "$elapsed|$mirror"
    else
        echo "999999|$mirror"  # Fehlgeschlagene Quellen mit sehr hohem Wert markieren
    fi
}

Detail: date +%s%N liefert Nanosekunden; durch 1000000 geteilt ergibt Millisekunden. Fehlgeschlagene Quellen (HTTP ≠ 200) erhalten 999999 ms und landen beim Sortieren hinten.

Paralleler Test: xargs mit mehreren Threads

Zehn Mirrors nacheinander ist zu langsam. Mit xargs -P parallelisieren:

# Alle Mirrors parallel testen
results=$(printf "%s\n" "${MIRRORS[@]}" | \
    xargs -P 4 -I {} bash -c 'test_mirror "$@"' _ {})

# Nach Antwortzeit sortieren (aufsteigend)
sorted=$(echo "$results" | sort -t '|' -k1 -n)

# Sortierte Ergebnisse ausgeben
echo "测速结果(响应时间越短越好):"
echo "$sorted" | while IFS='|' read time url; do
    if [[ "$time" != "999999" ]]; then
        echo "  ${time}ms  $url"
    else
        echo "  [失败]  $url"
    fi
done

xargs -P 4 startet vier parallele Jobs. Je nach Server 2–4 in Testumgebungen, in Produktion bis 8–10.

daemon.json automatisch aktualisieren

Abschluss: die drei schnellsten Mirrors in daemon.json schreiben.

# Die 3 schnellsten Mirrors extrahieren
top3=$(echo "$sorted" | grep -v "999999" | head -n 3 | cut -d '|' -f 2)

# JSON-Array bauen
mirrors_json=$(echo "$top3" | sed 's/.*/"&"/' | tr '\n' ',' | sed 's/,$//')

# ⚠️ Warnung: Direktes Überschreiben geht bestehende Konfiguration verloren!
# Wenn daemon.json weitere Felder hat (data-root, log-driver), manuell mergen
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [$mirrors_json]
}
EOF

echo "已更新 daemon.json,最快镜像源:"
echo "$top3"

# Docker-Dienst neu starten (Root-Rechte erforderlich)
if [[ $EUID -eq 0 ]]; then
    systemctl restart docker
    echo "Docker 服务已重启,配置生效"
else
    echo "需要 root 权限重启 Docker,请手动执行:sudo systemctl restart docker"
fi

Verwendung

Skript als docker-mirror-test.sh speichern und ausführbar machen:

chmod +x docker-mirror-test.sh
sudo ./docker-mirror-test.sh  # Root nötig für daemon.json

Beispielausgabe:

测速结果(响应时间越短越好):
  45ms   https://docker.xuanyuan.me
  68ms   https://docker.1ms.run
  120ms  https://docker.m.daocloud.io
  [失败] https://atomhub.openatom.cn

已更新 daemon.json,最快镜像源:
https://docker.xuanyuan.me
https://docker.1ms.run
https://docker.m.daocloud.io

Hinweis: Liegen auf dem Server weitere Docker-Einstellungen (data-root, log-driver), geht direktes Überschreiben von daemon.json verloren. Sicherer: bestehende Konfiguration lesen und registry-mirrors ergänzen. Das Python-Skript macht das – bei komplexer Konfiguration bevorzugen.


Python-Skript – präzise Zeitmessung und Fehlerbehandlung

Wenn Shell wenig vertraut ist oder präzisere Zeitmessung und robustere Fehlerbehandlung nötig sind, eignet sich Python. requests steuert Timeouts und fängt Exceptions ab – plattformübergreifend auf macOS, Windows und Linux.

Kern-Testfunktion

import requests
import time
import json
from pathlib import Path

# Mirror-Liste (Mai 2026, getestet verfügbar)
MIRRORS = [
    "https://docker.xuanyuan.me",
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io",
    "https://atomhub.openatom.cn",
]

def test_mirror(url, timeout=5):
    """Antwortzeit eines einzelnen Mirrors (Millisekunden)"""
    start = time.time()
    try:
        r = requests.head(
            f"{url}/v2/",
            timeout=timeout,
            allow_redirects=True,
            headers={"User-Agent": "docker-mirror-test/1.0"}
        )
        elapsed = (time.time() - start) * 1000  # in Millisekunden
        if r.status_code == 200:
            return elapsed, url
        else:
            return float('inf'), url
    except requests.exceptions.RequestException:
        return float('inf'), url

allow_redirects=True, weil manche Mirrors auf CDN-Knoten umleiten – die finale Antwortzeit zählt. Der User-Agent verhindert Blockierung als Bot.

Paralleler Test: ThreadPoolExecutor

concurrent.futures bietet einen Thread-Pool – flexibler als Shell-xargs:

from concurrent.futures import ThreadPoolExecutor, as_completed

def test_all_mirrors(mirrors, max_workers=4):
    """Alle Mirrors parallel testen"""
    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_url = {
            executor.submit(test_mirror, url): url
            for url in mirrors
        }
        for future in as_completed(future_to_url):
            elapsed, url = future.result()
            results.append((elapsed, url))
    return sorted(results, key=lambda x: x[0])

as_completed liefert Ergebnisse nach Fertigstellung ohne Blockade. max_workers=8 oder höher je nach Server und Bandbreite.

daemon.json aktualisieren (bestehende Konfiguration behalten)

Diese Version liest vorhandene daemon.json und ergänzt registry-mirrors statt alles zu überschreiben:

def update_daemon_json(fastest_mirrors, daemon_path="/etc/docker/daemon.json"):
    """daemon.json aktualisieren, bestehende Konfiguration behalten"""
    path = Path(daemon_path)

    # Bestehende Konfiguration lesen
    if path.exists():
        config = json.loads(path.read_text())
    else:
        config = {}

    # registry-mirrors aktualisieren
    config["registry-mirrors"] = fastest_mirrors[:3]

    # Konfiguration schreiben
    path.write_text(json.dumps(config, indent=2))
    print(f"已更新 {daemon_path},最快镜像源:")
    for m in fastest_mirrors[:3]:
        print(f"  {m}")

def main():
    print("正在测速镜像源...")
    results = test_all_mirrors(MIRRORS)

    print("\n测速结果(响应时间越短越好):")
    for elapsed, url in results:
        if elapsed != float('inf'):
            print(f"  {elapsed:.0f}ms  {url}")
        else:
            print(f"  [失败]  {url}")

    # Gültige Mirrors extrahieren
    valid_mirrors = [url for elapsed, url in results if elapsed != float('inf')]

    if valid_mirrors:
        update_daemon_json(valid_mirrors)
        print("\n请重启 Docker 服务使配置生效:sudo systemctl restart docker")
    else:
        print("\n所有镜像源均失败,请检查网络或镜像源列表")

if __name__ == "__main__":
    main()

Verwendung

Als docker-mirror-test.py speichern und ausführen:

python3 docker-mirror-test.py

Beispielausgabe:

正在测速镜像源...

测速结果(响应时间越短越好):
  42ms   https://docker.xuanyuan.me
  71ms   https://docker.1ms.run
  118ms  https://docker.m.daocloud.io
  [失败] https://atomhub.openatom.cn

已更新 /etc/docker/daemon.json,最快镜像源:
  https://docker.xuanyuan.me
  https://docker.1ms.run
  https://docker.m.daocloud.io

请重启 Docker 服务使配置生效:sudo systemctl restart docker

Das Python-Skript ist minimal langsamer (~10–20 ms Overhead), dafür präziser und robuster. Bei komplexer Docker-Konfiguration ist es sicherer – andere Felder bleiben erhalten.


Messdaten chinesischer Mirror-Quellen 2026

Mirror-Status ändert sich schnell – was letztes Jahr ging, kann heute weg sein; was letzten Monat schnell war, kann gedrosselt werden. Hier Messdaten vom Mai 2026.

Verfügbare Mirrors – Messwerte

MirrorAdresseDurchschnittsgeschwindigkeitStabilitätAnmerkung
Xuanyuan Mirrorhttps://docker.xuanyuan.me12,3 MB/s99,2 %Plattformübergreifend, regulierter Betrieb in China
1ms Mirrorhttps://docker.1ms.run11,8 MB/s99,5 %Finanz-SLA, Enterprise-Favorit
DaoCloudhttps://docker.m.daocloud.io9,5 MB/s97,6 %Etablierter Dienst, Backup-Option
AtomHubhttps://atomhub.openatom.cn8,2 MB/s100 %Offizielles Gemeinwohlprojekt der OpenAtom Foundation

Daten stammen aus einem Praxisbericht der Tencent-Cloud-Developer-Community (2026-03), per HTTP-HEAD verifiziert – im Wesentlichen zutreffend. Xuanyuan und 1ms sind am schnellsten und stabilsten – erste Wahl.

Nicht mehr verfügbare Mirrors (2024–2026)

Diese Quellen waren früher nutzbar, sind aber eingestellt oder stark gedrosselt:

MirrorAdresseStatusAnmerkung
USTChttps://docker.mirrors.ustc.edu.cn❌ EingestelltJuni 2024: externer Dienst beendet
NetEasehttp://hub-mirror.c.163.com❌ EingestelltSync gestoppt, veraltete Images
Alibaba offizieller Acceleratorhttps://registry.cn-hangzhou.aliyuncs.com⚠️ Stark gedrosseltAuf Nicht-Alibaba-Servern limitiert – nicht empfohlen

Den Alibaba-Fall kenne ich selbst: Auf Tencent-Cloud-Servern mit Alibaba-Accelerator liefen Pulls oft in Timeout – Alibaba drosselt Server außerhalb der eigenen Cloud. Auf Alibaba ECS ist der Accelerator schnell; cross-cloud eher nicht.

NAS-Nutzer und Entwickler in China

Für Synology- oder Zspace-NAS ist die Mirror-Wahl schwieriger – Docker-Konfiguration ist weniger flexibel, manche Systeme sperren daemon.json.

Empfehlung: AtomHub (offizielles Projekt der OpenAtom Foundation). Gemeinwohl, ohne Drosselung und Gebühren, 100 % Stabilität – langsamer als Xuanyuan/1ms, aber zuverlässig. Cloud-unabhängig, konsistente Erfahrung.


Hinweis zur Aktualität: Mirror-Status ändert sich schnell; Datenstand Mai 2026. Regelmäßig mit den obigen Skripten prüfen oder per Cron/systemd timer wöchentlich automatisch testen und konfigurieren.


daemon.json – Best Practices

Nach dem Test folgt die Docker-Daemon-Konfiguration. Richtig gesetzt, wechselt Docker bei Ausfall automatisch zum nächsten Mirror.

Empfohlene Konfiguration

{
  "registry-mirrors": [
    "https://docker.xuanyuan.me",
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io"
  ]
}

2–3 Mirrors reichen. Docker probiert der Reihe nach; der erste Erfolg zählt – weitere werden nicht genutzt. Zu viele Einträge erhöhen Aufwand und riskieren veraltete Quellen.

Failover-Mechanismus

So arbeitet registry-mirrors:

  1. Sie führen docker pull ubuntu:latest aus
  2. Docker versucht zuerst docker.xuanyuan.me
  3. Bei Timeout oder Fehler wechselt Docker zu docker.1ms.run
  4. Scheitern alle Mirrors, folgt der Fallback auf Docker Hub

Vorteil: Ein ausgefallener Mirror stoppt Deployments nicht. Nachteil: Ein langsamer, aber erreichbarer erster Mirror wird nicht automatisch durch einen schnelleren ersetzt.

Regelmäßige Tests lohnen sich – schnellsten Mirror an Position 1, zweitschnellsten an Position 2.

Konfiguration verifizieren

Nach der Änderung Docker neu starten:

sudo systemctl restart docker

Mirror-Einträge prüfen:

docker info | grep -A 5 "Registry Mirrors"

Beispielausgabe:

Registry Mirrors:
 https://docker.xuanyuan.me/
 https://docker.1ms.run/
 https://docker.m.daocloud.io/

Damit ist die Konfiguration aktiv; künftige Pulls nutzen diese Mirrors bevorzugt.

Konfigurationspfad unter macOS und Windows

Bei Docker Desktop (macOS oder Windows) andere Wege:

  • macOS: Docker Desktop → Settings → Docker Engine → JSON bearbeiten
  • Windows: Ebenfalls unter Settings → Docker Engine

Inhalt identisch, nur die Oberfläche unterscheidet sich. Nach „Apply & Restart“ startet Docker Desktop neu.


daemon.json bietet weitere Felder: data-root, log-driver, storage-driver. Diese mit registry-mirrors in einer JSON-Datei zusammenführen – nicht überschreiben. Das Python-Skript erledigt das; beim Shell-Skript manuell mergen.


Zusammenfassung

Kernpunkte in drei Sätzen:

  1. Testmethoden: Zuerst HTTP HEAD für erreichbare Mirrors, dann echter Pull für die schnellsten. Ping misst ICMP – nicht die Download-Geschwindigkeit.

  2. Automatisierung: Shell für schnelles Ops-Deployment, Python für präzise Messung und Cross-Platform. Beide aktualisieren daemon.json automatisch.

  3. Mirror-Auswahl: Mai 2026 – Xuanyuan und 1ms am schnellsten und stabilsten; AtomHub für NAS und Gemeinwohl-Szenarien. USTC, NetEase und die gedrosselte Alibaba-Variante weglassen.


Empfohlene Schritte:

  • Testskript (Shell oder Python) herunterladen und Mirrors in Ihrer Netzwerkumgebung messen
  • Cron oder systemd timer für wöchentlichen Auto-Test und Config-Update – Mirror-Status ändert sich schnell
  • In Team-CI/CD das Skript vor Deployments einbinden, um Pull-Fehler und nächtliche Alarme zu vermeiden

Wenn der Artikel hilft, teilen Sie ihn im Team oder in der Community. Mirror-Probleme sind häufig – viele wechseln noch manuell. Sparen Sie anderen die Zeit.

10 Min. Lesezeit · Veröffentlicht am: 27. Mai 2026 · Aktualisiert am: 14. Juli 2026

Ähnliche Beiträge

Kommentare

Melde dich mit GitHub an, um einen Kommentar zu hinterlassen

Easton BlogEaston Blog