Inhaltsverzeichnis
Frageninhalt
Lösung
Heim Backend-Entwicklung Golang Docker-Image konnte nicht geladen werden

Docker-Image konnte nicht geladen werden

Feb 13, 2024 am 08:20 AM

Docker-Image konnte nicht geladen werden

php-Editor Strawberry kann bei der Verwendung von Docker auf ein häufiges Problem stoßen, nämlich „Laden des Docker-Image fehlgeschlagen“. Dieses Problem hindert uns möglicherweise daran, Docker zum normalen Erstellen und Ausführen von Containern zu verwenden. Aber keine Sorge, für dieses Problem gibt es meist mehrere Lösungen. In diesem Artikel werden einige gängige Lösungen vorgestellt, die Ihnen dabei helfen, das Docker-Image erfolgreich zu laden und dieses lästige Problem zu lösen. Egal, ob Sie Anfänger oder erfahrener Docker-Benutzer sind, ich hoffe, dass dieser Artikel für Sie hilfreich ist.

Frageninhalt

Ich verwende das golangdocker 客户端 加载 .tar Docker-Image-Format.

func loadimagefromtar(cli *client.client, tarfilepath string) (string, error) {
    // read tar file
    tarfile, err := os.open(tarfilepath)
    if err != nil {
        return "", fmt.errorf("failed to open tar file: %w", err)
    }
    defer tarfile.close()

    // create a pipe to stream data between tar reader and docker client
    pr, pw := io.pipe()

    // set up a waitgroup for synchronization
    var wg sync.waitgroup
    wg.add(2)

    // load the docker image in a separate goroutine
    var imageloadresponse types.imageloadresponse
    go func() {
        defer wg.done()
        imageloadresponse, err = cli.imageload(context.background(), pr, false)
        if err != nil {
            err = fmt.errorf("failed to load docker image: %w", err)
        }
    }()

    // read tar file metadata and copy the tar file to the pipe writer in a separate goroutine
    var repotag string
    go func() {
        defer wg.done()
        defer pw.close()

        tarreader := tar.newreader(tarfile)

        for {
            header, err := tarreader.next()
            if err == io.eof {
                break
            }
            if err != nil {
                err = fmt.errorf("failed to read tar header: %w", err)
                fmt.printf("error: %v", err)
                return
            }

            // extract the repository and tag from the manifest file
            if header.name == "manifest.json" {
                data, err := io.readall(tarreader)
                if err != nil {
                    err = fmt.errorf("failed to read manifest file: %w", err)
                    fmt.printf("error: %v", err)
                    return
                }

                var manifest []map[string]interface{}
                err = json.unmarshal(data, &manifest)
                if err != nil {
                    err = fmt.errorf("failed to unmarshal manifest: %w", err)
                    fmt.printf("error: %v", err)
                    return
                }

                repotag = manifest[0]["repotags"].([]interface{})[0].(string)
            }

            // copy the tar file data to the pipe writer
            _, err = io.copy(pw, tarreader)
            if err != nil {
                err = fmt.errorf("failed to copy tar data: %w", err)
                fmt.printf("error: %v", err)
                return
            }
        }
    }()

    // wait for both goroutines to finish
    wg.wait()

    // check if any error occurred in the goroutines
    if err != nil {
        return "", err
    }

    // close the image load response body
    defer imageloadresponse.body.close()

    // get the image id
    imageid, err := getimageidbyrepotag(cli, repotag)
    if err != nil {
        return "", fmt.errorf("failed to get image id: %w", err)
    }

    return imageid, nil
}

// Funktion: getimageidbyrepotag

func getImageIDByRepoTag(cli *client.Client, repoTag string) (string, error) {
    images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
    if err != nil {
        return "", fmt.Errorf("failed to list images: %w", err)
    }

    for _, image := range images {
        for _, tag := range image.RepoTags {
            if tag == repoTag {
                return image.ID, nil
            }
        }
    }

    return "", fmt.Errorf("image ID not found for repo tag: %s", repoTag)
}

getimageidbyrepotag 始终返回 fmt.errorf("未找到存储库标记的图像 id: %s", repotag). Außerdem sehe ich beim Ausführen von docker images nicht, dass das Bild geladen wird. Es sieht so aus, als ob das Laden des Bildes noch nicht abgeschlossen ist.

In meinem anderen Code fügt der Docker-Client cli.imageload 立即返回,但 docker 映像加载通常需要一些时间。我通常会在检查 getimageidbyrepotag jedoch etwa 30 Sekunden Wartezeit hinzu. Auch das Hinzufügen einer Wartezeit hilft in diesem Fall nicht.

Danke

Lösung

Ein paar Fragen:

  • Diese beiden Goroutinen werden gemeinsam genutzt err, sodass möglicherweise ein Teil der Fehlerbehandlung verloren geht
    • Sie sollten hier für jede Goroutine eine eindeutige Fehlervariable verwenden und nach wg.wait()
    • auf beide Fehler prüfen
  • Hauptproblem: Sie erhalten einen Bytestream vom tar 阅读器中读取内容以查找清单文件并提取标签信息 - 这很好 - 但找到后,您将字节流的其余部分复制到管道中。因此,您将丢失一块永远不会到达 dockerClient

Um zu vermeiden, dass der TAR-Byte-Stream zweimal gelesen wird, können Sie io.teereader verwenden. Dadurch können Sie TAR-Archive lesen (Scan manifest 文件 - 但也可以将此流完整写入其他地方(即写入 docker Client).

Erstellen teereader:

tr := io.teereader(tarfile, pw)  // reading `tr` will read the tarfile - but simultaneously write to `pw`

Das Laden von Bildern liest jetzt von hier aus (anstelle von Pipe):

//imageloadresponse, err = cli.imageload(context.background(), pr, false)
imageloadresponse, err = cli.imageload(context.background(), tr, false)

Dann ändern Sie Ihr archive/tar-Lesegerät, um aus der Pfeife zu lesen:

//tarreader := tar.newreader(tarfile) // direct from file
tarreader := tar.newreader(pr) // read from pipe (indirectly from the file)

Sie können dann den io.copy-Block löschen:

// no longer needed:
//
// _, err = io.copy(pw, tarreader)
//

Weil der Tar-Inspektionscode den gesamten Stream in eof einliest.

P.S. Möglicherweise müssen Sie io.eof 重置为 nil 以避免在检查来自任一 goroutine 的任何潜在错误时认为 eof in einen schwerwiegenderen Fehler umwandeln:

header, err = tarReader.Next()
if err == io.EOF {
    err = nil  //  EOF is a non-fatal error here
    break
}

Das obige ist der detaillierte Inhalt vonDocker-Image konnte nicht geladen werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

PHP-Tutorial
1508
276
So erstellen Sie einen Webserver in Go So erstellen Sie einen Webserver in Go Jul 15, 2025 am 03:05 AM

Es ist nicht schwierig, einen in Go geschriebenen Webserver zu erstellen. Der Kern liegt in der Verwendung des NET/HTTP -Pakets zur Implementierung grundlegender Dienste. 1. Verwenden Sie Net/HTTP, um den einfachsten Server zu starten: Registrieren Sie die Verarbeitungsfunktionen und hören Sie Ports über einige Codezeilen an. 2. Routing -Management: Verwenden Sie ServeMux, um mehrere Schnittstellenpfade für eine einfache strukturierte Verwaltung zu organisieren. 3. Häufige Praktiken: Gruppenrouting nach funktionalen Modulen und verwenden Bibliotheken von Drittanbietern, um eine komplexe Übereinstimmung zu unterstützen. 4. Statischer Dateidienst: Geben Sie HTML-, CSS- und JS -Dateien über http.FileServer an; 5. Leistung und Sicherheit: Aktivieren Sie HTTPS, begrenzen Sie die Größe des Anforderungsorganisation und stellen Sie Zeitüberschreitungen ein, um die Sicherheit und Leistung zu verbessern. Nach dem Beherrschen dieser Schlüsselpunkte ist es einfacher, die Funktionalität zu erweitern.

Gehen Sie für Audio-/Videoverarbeitung Gehen Sie für Audio-/Videoverarbeitung Jul 20, 2025 am 04:14 AM

Der Kern der Audio- und Videoverarbeitung liegt darin, die grundlegenden Prozess- und Optimierungsmethoden zu verstehen. 1. Der grundlegende Prozess umfasst Akquisition, Codierung, Übertragung, Decodierung und Wiedergabe, und jeder Link hat technische Schwierigkeiten. 2. Häufige Probleme wie Audio- und Video -Aberration, Verzögerungsverzögerung, Schallgeräusch, verschwommenes Bild usw. können durch synchrone Einstellung, Codierungsoptimierung, Rauschverringerungsmodul, Parameteranpassung usw. gelöst werden; 3.. Es wird empfohlen, FFMPEG, OpenCV, Webrtc, Gstreamer und andere Tools zu verwenden, um Funktionen zu erzielen. 4. In Bezug auf das Leistungsmanagement sollten wir auf die Beschleunigung der Hardware, die angemessene Einstellung der Auflösungsrahmenquoten, die Kontrollverkehr und Speicher -Leckage -Probleme achten. Wenn Sie diese wichtigen Punkte beherrschen, werden die Entwicklungseffizienz und die Benutzererfahrung verbessert.

Wählen Sie mit Standardfall auswählen Wählen Sie mit Standardfall auswählen Jul 14, 2025 am 02:54 AM

Der Zweck von Select Plus -Standard besteht darin, das Auswählen zu ermöglichen, ein Standardverhalten durchzuführen, wenn keine anderen Zweige bereit sind, um das Programmblockieren zu vermeiden. 1. Beim Empfangen von Daten aus dem Kanal ohne Blockierung, wenn der Kanal leer ist, wird direkt die Standardzweigung eingegeben. 2. In Kombination mit der Zeit. Nach oder Ticker versuchen Sie, Daten regelmäßig zu senden. Wenn der Kanal voll ist, wird er nicht blockiert und überspringt. 3. Verhindern Sie Deadlocks, vermeiden Sie das Programm, das nicht sicher ist, ob der Kanal geschlossen ist. Beachten Sie bei der Verwendung, dass die Standardzweig sofort ausgeführt wird und nicht missbraucht wird, und standardmäßig und der Fall sind sich gegenseitig ausschließlich und werden nicht gleichzeitig ausgeführt.

Entwicklung von Kubernetes -Betreibern in Go Entwicklung von Kubernetes -Betreibern in Go Jul 25, 2025 am 02:38 AM

Der effizienteste Weg, um einen Kubernetesoperator zu schreiben, besteht darin, GO zu verwenden, um Kubebuilder und Controller-Runtime zu kombinieren. 1. Verstehen Sie das Bedienermuster: Definieren Sie benutzerdefinierte Ressourcen über CRD, schreiben Sie einen Controller, um auf Ressourcenänderungen zu hören und Versöhnungsschleifen durchzuführen, um den erwarteten Zustand aufrechtzuerhalten. 2. Verwenden Sie Kubebuilder, um das Projekt zu initialisieren und APIs zu erstellen, um automatisch CRDs, Controller und Konfigurationsdateien zu generieren. 1. Definieren Sie die Spezifikation und die Statusstruktur von CRD in API/v1/myapp_types.go und führen Sie MakeManifests aus, um Crdyaml zu generieren. 4.. Versöhnung im Controller

Gehen Sie beispielsweise API -Beispiel Gehen Sie beispielsweise API -Beispiel Jul 14, 2025 am 03:01 AM

Wie implementieren Sie schnell ein RestAPI -Beispiel in Go? Die Antwort ist die Verwendung der NET/HTTP -Standardbibliothek, die gemäß den folgenden drei Schritten abgeschlossen werden kann: 1. Richten Sie die Projektstruktur ein und initialisieren Sie das Modul; 2. Definieren Sie die Datenstruktur- und Verarbeitungsfunktionen, einschließlich des Erhaltens aller Daten, das Erhalten von Einzeldaten basierend auf der ID und das Erstellen neuer Daten; 3. Registrieren Sie die Route in der Hauptfunktion und starten Sie den Server. Der gesamte Prozess erfordert keine Bibliothek von Drittanbietern. Die grundlegende Restapi -Funktion kann über die Standardbibliothek realisiert und über den Browser oder Postboten getestet werden.

So stellen Sie eine HTTP -Anfrage in Go So stellen Sie eine HTTP -Anfrage in Go Jul 14, 2025 am 02:48 AM

Die Methoden zur Initiierung von HTTP -Anforderungen in GO sind wie folgt: 1. Verwenden Sie HTTP.get (), um die einfachste GET -Anforderung zu initiieren. Denken Sie daran, den Fehler zu bewältigen und den Körper zu schließen. 2. Verwenden Sie http.post () oder http.newRequest (), um eine Postanforderung zu senden, und Sie können JSON -Daten oder Formulardaten festlegen. 3. Setzen Sie Zeitüberschreitungen, Header und Cookies, Steuerung und Header. 4. Zu den Hinweisen gehört das Schließen des Körpers, das Nicht-REQ-Objekt und das Einstellen von Benutzer-Ag

GO -Abfrageoptimierungstechniken für PostgreSQL/MySQL GO -Abfrageoptimierungstechniken für PostgreSQL/MySQL Jul 19, 2025 am 03:56 AM

TooptimizeGoapplicationssinteractingwithpostgresqlormysql, FocusonIndexing, Selektivquerien, Verbindungshandling, Caching, Andormeffizienz.1) UseProperIndexing-IdentifizierfrequentqueriedColumns, addIndexesselektiv, andusecomposeFrequent-Formulti-kolumnquerquer

GO VERBERTER ARSICHTUNG ERKENNEN GO VERBERTER ARSICHTUNG ERKENNEN Jul 14, 2025 am 02:57 AM

Die Kernfunktion von Aufschub besteht darin, die Ausführung von Funktionsaufrufen zu verschieben, bis die aktuelle Funktion zurückgibt, die häufig zur Ressourcenreinigung verwendet wird. Insbesondere enthält es: 1. Stellen Sie sicher, dass Dateien, Netzwerkverbindungen, Sperren und andere Ressourcen rechtzeitig veröffentlicht werden; 2. Die Ausführungsreihenfolge ist später zuerst (LIFO), und der zuletzt definierte Aufschub wird zuerst ausgeführt. 3. Die Parameter werden bestimmt, wenn die Aufschub definiert und während der Nichtausnahme bewertet wird. Wenn variable Änderungen benötigt werden, können Schließungen oder Zeiger verwendet werden. V.

See all articles