Docker-Version hängt vor Server-Info

1260
karobar

Einführung

Ich versuche, die folgende Version von dockerauf einer Linux-VM zu verwenden ( uname -aRückkehr Linux xen 4.1.17-yocto-standard #1 SMP PREEMPT Thu Jun 2 13:29:47 PDT 2016 x86_64 GNU/Linux)aus dem docker_gitBitBake-Rezept) .

Wenn ich versuche zu laufen docker version, erhalte ich folgende Ausgabe:

Client version: 1.6.2 Client API version: 1.18 Go version (client): go1.3 Git commit (client): 7c8fca2-dirty OS/Arch (client): linux/amd64 

Dann hängt der Befehl.

Wie es aussehen soll

Ich habe versucht, docker versionauf einer funktionierenden Docker-Installation (Ubuntu 14.04) auszuführen, und erhalte folgende Ausgabe:

Client version: 1.6.2 Client API version: 1.18 Go version (client): go1.2.1 Git commit (client): 7c8fca2 OS/Arch (client): linux/amd64 Server version: 1.6.2 Server API version: 1.18 Go version (server): go1.2.1 Git commit (server): 7c8fca2 OS/Arch (server): linux/amd64 

Ich gehe also davon aus, dass beim Abrufen von Serverinformationen eine Art Fehler auftritt.

Zusätzliche Forschung

Ich bin mit Go nicht vertraut, daher könnte dieser Abschnitt erschütternd sein, während ich versuche herauszufinden, was zum Teufel hier vor sich geht.

Ich habe mir diesen Teil des api/client/version.goDocker-Quellcodes angesehen:

var versionTemplate = `Client: Version: {{.Client.Version}} API version: {{.Client.APIVersion}} Go version: {{.Client.GoVersion}} Git commit: {{.Client.GitCommit}} Built: {{.Client.BuildTime}} OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{} Experimental: {{.Client.Experimental}}{}{} Server: Version: {{.Server.Version}} API version: {{.Server.APIVersion}} Go version: {{.Server.GoVersion}} Git commit: {{.Server.GitCommit}} Built: {{.Server.BuildTime}} OS/Arch: {{.Server.Os}}/{{.Server.Arch}}{} Experimental: {{.Server.Experimental}}{}{}` 

es geht weiter zu diesem Abschnitt:

vd := types.VersionResponse{ Client: &types.Version{ Version: dockerversion.Version, APIVersion: cli.client.ClientVersion(), GoVersion: runtime.Version(), GitCommit: dockerversion.GitCommit, BuildTime: dockerversion.BuildTime, Os: runtime.GOOS, Arch: runtime.GOARCH, Experimental: utils.ExperimentalBuild(), }, } 

Von engine-api/types/client.go:

// VersionResponse holds version information for the client and the server type VersionResponse struct { Client *Version Server *Version }  

Zu diesem Zeitpunkt müssen Sie also nur noch etwas dem ServerMember (vom Typ *Version) zuweisen . Dies geschieht im Abschnitt nach der vdZuweisung von oben:

serverVersion, err := cli.client.ServerVersion(context.Background()) if err == nil { vd.Server = &serverVersion } 

Die Funktionsdefinition für ServerVersionlautet wie folgt ausengine-api/client/version.go

// ServerVersion returns information of the docker client and server host. func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) { resp, err := cli.get(ctx, "/version", nil, nil) if err != nil { return types.Version{}, err }  var server types.Version err = json.NewDecoder(resp.body).Decode(&server) ensureReaderClosed(resp) return server, err } 

Aus dem, was ich entnehmen kann, weist der obige getFunktionsaufruf auf client/request.goDockers engine APIRepo hin

// getWithContext sends an http request to the docker API using the method GET with a specific go context. func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) { return cli.sendRequest(ctx, "GET", path, query, nil, headers) } 

Woher:

  • ctx ist context.Background()
  • path ist /version
  • Nein query
  • Nein headers

Und diese Dokumentation für sendRequestvon vendor/src/google.golang.org/grpc/call.go:

// sendRequest writes out various information of an RPC such as Context and Message. func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) { stream, err := t.NewStream(ctx, callHdr) if err != nil { return nil, err } defer func() { if err != nil { if _, ok := err.(transport.ConnectionError); !ok { t.CloseStream(stream, err) } } }() // TODO(zhaoq): Support compression. outBuf, err := encode(codec, args, compressionNone) if err != nil { return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err) } err = t.Write(stream, outBuf, opts) if err != nil { return nil, err } // Sent successfully. return stream, nil } 

Das war eine Zeit lang Vermutung, und ich bin jetzt besorgt, dass ich vielleicht am falschen Ort suchen könnte.

Fragen

  • Was verursacht docker version, docker run hello-world, docker images, docker ps, und docker infohängen und wie sie behoben werden?
  • Gibt es eine effektivere Möglichkeit, die Ursache dieses Fehlers zu untersuchen?
3
Welches Betriebssystem laufen Sie? Haben Sie versucht, eine neuere Version des Dockers zu installieren? Ken J vor 7 Jahren 0
Dies ist eine sehr spezifische Frage zu einem ganz bestimmten Projekt, was mir gerade aufgefallen ist: Dieses Paket enthält den Daemon und den Client. Die Verwendung von docker.io auf Nicht-amd64-Hosts wird derzeit nicht unterstützt. `Sind Sie sicher, dass Sie es auf einem AMD-Prozessor und nicht mit Intel ausführen? Vojtěch Dohnal vor 7 Jahren 0
Ich habe es auf einer virtuellen Intel-CPU ausgeführt. Auf Kens Frage ist das Betriebssystem mit Linux 4.1 Kernel homebrew. Ich habe auch versucht, 1.11 mit ähnlichen Effekten zu installieren. Ich werde die Frage bald aktualisieren. karobar vor 7 Jahren 0
Sie sollten den Prozess / Daemon, der den Socket unter `/ var / run / docker.sock` abhört,` strace`. Ihr `docker info`-Befehl schickte eine Anfrage, die mit" GET /v1.18/info HTTP / 1.1 \ r \ nHost: "begann, an den Socket und wartete ewig auf eine Antwort, aber der Server antwortete nicht. Deltik vor 7 Jahren 0

1 Antwort auf die Frage

3
Deltik

Ihre straceAusgabe legt stark nahe, dass der Docker-Client nicht mit dem Docker-Dämon kommunizieren kann, der standardmäßig einen Socket bei erstellt /var/run/docker.sock.

Der Docker-Daemon soll ein Systemdienst sein (auf systemd, bei /lib/systemd/system/docker.serviceder Socket-Konfiguration unter /lib/systemd/system/docker.socket), kann jedoch unabhängig gestartet werden, /usr/bin/docker daemongefolgt von optionalen Optionen.

Sie sollten straceden Dämon und nicht den Client verwenden .

Verwendung straceauf dem Docker-Daemon

  1. Rufen Sie die Prozess-ID Ihres Docker-Daemons ab. Jeder dieser Befehle würde die PID in einer aufgerufenen Variablen speichern $DOCKER_PID.

    • Direkt aus der Steckdose:

      DOCKER_PID=$(sudo lsof -Ua /var/run/docker.sock | awk '/^docker/ ' | head -1) 
    • systemd:

      DOCKER_PID=$(systemctl show -p MainPID docker.service | awk -F'=' '') 
    • Andere:

      DOCKER_PID=$(ps aux | grep 'docker daemon' | grep -v 'grep' | awk '' | head -1) 
  2. Verwenden Sie straceauf dem Docker-Daemon jetzt die PID:

    sudo strace -vvvfts1000 -p $DOCKER_PID 
  3. Führen Sie in einem separaten Terminal einen Befehl aus, der normalerweise im Docker-Client hängt.

    docker version 
  4. Sehen Sie sich den straceDocker-Dämon an, um zu sehen, was am hörenden Ende des Sockets geschieht.

Interpretation der straceAusgabe

Das soll der Daemon beim Ausführen tun docker version:

  1. Lesen Sie, was der Kunde gesendet hat:

    [pid 14291] 12:34:36 <... read resumed> "GET /v1.22/version HTTP/1.1\r\nHost: \r\nUser-Agent: Docker-Client/1.10.3 (linux)\r\n\r\n", 4096) = 81 
  2. Sammeln Sie Informationen zum System:

    [pid 14291] 12:34:36 uname() = 0 
  3. Antworten Sie dem Kunden mit Informationen zum System:

    [pid 14291] 12:34:36 write(3, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nServer: Docker/1.10.3 (linux)\r\nDate: Mon, 13 Jun 2016 17:34:36 GMT\r\nContent-Length: 194\r\n\r\n{\"Version\":\"1.10.3\",\"ApiVersion\":\"1.22\",\"GitCommit\":\"20f81dd\",\"GoVersion\":\"go1.6.1\",\"Os\":\"linux\",\"Arch\":\"amd64\",\"KernelVersion\":\"4.4.0-22-generic\",\"BuildTime\":\"Wed, 20 Apr 2016 14:19:16 -0700\"}\n", 334) = 334 
  4. Der Client ( docker version) zeigt dann die Informationen an, die der Server zurückgegeben hat:

    Server: Version: 1.10.3 API version: 1.22 Go version: go1.6.1 Git commit: 20f81dd Built: Wed, 20 Apr 2016 14:19:16 -0700 OS/Arch: linux/amd64 

In Ihrem Problem hat Ihr Docker-Dämon anscheinend nicht Schritt 3 ausgeführt, da der Client sonst die Antwort gesehen hätte, der Client aber nichts erhalten hat.

Sie sollten diese Informationen verwenden können, um herauszufinden, warum der Docker-Dämon nicht auf Anforderungen des Clients antwortet.

Mögliche Ursachen

Die von Ihnen bereitgestellten Informationen reichen nicht aus, um die Ursache für das Unvermögen Ihres Docker-Clients zu ermitteln, eine Antwort vom Docker-Dämon zu erhalten, aber hier sind einige Tipps:

  • Läuft der Docker-Daemon?
  • Was passiert, wenn Sie den Docker-Dämon im Vordergrund starten ?: sudo docker daemon
  • Hört der Docker-Daemon auf den Socket /var/run/docker.sock? sudo lsof -p $DOCKER_PIDsollte /var/run/docker.sock type=STREAMirgendwo " " angezeigt werden.
  • Gibt es Sicherheitsrichtlinien, die im Client oder Dämon etwas blockieren könnten? Unter Linux können SELinux und AppArmor Verwirrung stiften, da für sie festgelegte Richtlinien den Zugriff verweigern.
  • In dem stracevon dem Dämon, wenn Sie nicht über eine HTTP - GET - Anforderung von dem Client erhalten, bedeutet dies, dass der Server nicht etwas aus der Fassung erhalten hat.
  • Wenn Sie dies docker versionim straceDaemon getan haben und feststellen, dass kein uname()Anruf erfolgt ist, hat der Daemon nicht einmal versucht, Informationen über das System abzurufen.
  • Wenn Sie den write()Aufruf im straceDaemon sehen, bedeutet dies, dass der Daemon geantwortet hat, der Client ihn jedoch nicht gesehen hat.
  • Möglicherweise ist dies ein bekanntes Problem in der von Ihnen verwendeten älteren Docker-Version. Versuchen Sie ein Upgrade.
Für mich lag das daran, dass `docker` nur auf TCP-Socket lauschte und nicht auf docker.sock. Ich wurde verrückt, bis ich das begriff (danke für Ihre vollständige Antwort, die mir sehr hilft). Überprüfen Sie Ihr `/ etc / sysconfig / docker-network`, um sicherzustellen, dass Sie -H unix: /// var / run / docker.sock` haben Doomsday vor 7 Jahren 1