liman sürümü sunucu bilgisinden önce kilitleniyor


3

Giriş

Aşağıdaki dockerVM sürümünü bir VM'de kullanmaya çalışıyorum ( uname -adöner Linux xen 4.1.17-yocto-standard #1 SMP PREEMPT Thu Jun 2 13:29:47 PDT 2016 x86_64 GNU/Linux), docker_gitBitBake tarifinden oluşturulmuş) .

Çalıştırmaya çalışırsam docker versionaşağıdaki çıktıyı alıyorum:

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

Sonra komut kilitleniyor.

Nasıl olması gerektiği

docker versionÇalışan bir liman işçisi kurulumunda çalıştırmayı denedim (Ubuntu 14.04) ve aşağıdaki çıktıyı alıyorum:

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

Yani, sunucu bilgisi alınırken bir çeşit hata olduğunu farz ediyorum.

Ek araştırma

Go ile aşina değilim, bu yüzden haltların neler olup bittiğini anlamaya çalışırken bu bölüm zorlayıcı olabilir.

api/client/version.goDocker kaynak kodunun bu bölümüne bakmaya başladım :

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}}{{if .Client.Experimental}}
 Experimental: {{.Client.Experimental}}{{end}}{{if .ServerOK}}
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}}{{if .Server.Experimental}}
 Experimental: {{.Server.Experimental}}{{end}}{{end}}`

bu bölüme devam ediyor:

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(),
    },
}

Kimden engine-api/types/client.go:

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

Dolayısıyla bu noktada yapılması gereken tek şey Serverüyeye bir şey atamaktır (tür *Version). Bu vdyukarıdan atamanın ardından gelen bölümde gerçekleşir :

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

İçin işlev tanımı ServerVersionşudur:engine-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
}

Anladığım kadarıyla, yukarıdaki getişlev çağrısı noktaları client/request.goDocker en dan engine APIrepo

// 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)
}

Nerede:

  • ctx dır-dir context.Background()
  • path dır-dir /version
  • Hayır query
  • Hayır headers

Ve bu belgeler sendRequestarasından 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
}

Bu bir süredir tahminde bulunuldu ve şimdi yanlış yere bakıyor olabileceğimden endişeleniyorum.

Sorular

  • Yol açan nedir docker version, docker run hello-world, docker images, docker ps, ve docker infoasmak ve nasıl tamir edilebilir?
  • Veya bu hatanın nedenini incelemenin daha etkili bir yolu var mı?

Hangi işletim sistemini kullanıyorsunuz? Docker'ın daha yeni bir sürümünü yüklemeyi denediniz mi?
Ken J

Bu çok özel bir projeyle ilgili çok özel bir soru, beni en This package contains the daemon and client. Using docker.io on non-amd64 hosts is not supported at this time.çok etkileyen şey AMD işlemcide Intel'den çalıştığınızdan emin misiniz?
Vojtěch Dohnal

Sanal bir Intel işlemcisinde çalıştırıyordum. Ayrıca, Ken sorusuna göre, OS linux 4.1 çekirdeği ile homebrew. Ben de benzer efektlerle 1.11 yüklemeyi denedim. Soruyu yakında güncelleyeceğim.
karobar

straceSokette dinleyen bir işlem / arka plan programı yapmalısınız /var/run/docker.sock. Kişisel docker infosokete ve bir cevap için sonsuza kadar bekledi, ancak sunucu cevap vermedi: "GET /v1.18/info HTTP / 1.1 \ r \ nHost" komutu ile başlayan bir istekte bulundu.
Deltik

Yanıtlar:


3

Sizin straceçıkış kuvvetle Docker istemci varsayılan olarak bir soket oluşturur Docker cini, konuşmak mümkün olmadığını göstermektedir /var/run/docker.sock.

Docker arka planının bir sistem hizmeti olması gerekiyordu (sistemde /lib/systemd/system/docker.service, soket yapılandırmasının bulunduğu yerde /lib/systemd/system/docker.socket), ancak /usr/bin/docker daemonisteğe bağlı seçeneklerle takip edilerek bağımsız olarak başlatılabilir .

You should cin yerine istemci .strace

straceDocker daemon'da kullanma

  1. Docker daemon'unuzun işlem kimliğini alın. Bu komutlardan herhangi biri PID'yi bir değişkende saklar $DOCKER_PID.

    • Doğrudan soketten:

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

      DOCKER_PID=$(systemctl show -p MainPID docker.service | awk -F'=' '{print $NF}')
      
    • Diğer:

      DOCKER_PID=$(ps aux | grep 'docker daemon' | grep -v 'grep' | awk '{print $2}' | head -1)
      
  2. Kullanım stracePıD'YI var artık, Docker daemon'ıdır:

    sudo strace -vvvfts1000 -p $DOCKER_PID
    
  3. Ayrı bir terminalde, Docker istemcisine normalde asılı olan bir komutu çalıştırın.

    docker version
    
  4. straceSoketin dinleme sonunda başlayanlara tanıklık etmek için Docker daemon'unu izleyin .

straceÇıktıyı yorumlama

İşte koşarken koşunun yapması gerekenler docker version:

  1. Müşterinin ne gönderdiğini okuyun:

    [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. Sistem hakkında bilgi toplayın:

    [pid 14291] 12:34:36 uname({sysname="Linux", nodename="node51", release="4.4.0-22-generic", version="#40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016", machine="x86_64", domainname="(none)"}) = 0
    
  3. Sistem hakkında bilgi veren müşteriye cevap verin:

    [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. Client ( docker version) daha sonra sunucunun döndürdüğü bilgiyi görüntüler:

    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
    

Sorununuzda, Docker daemon'unuz görünüşte 3. adımı atmadı, çünkü öyleyse müşteri yanıtı görmüş olacaktı, ancak müşteri hiçbir şey alamadı.

Docker arka plan programının istemciden gelen istekleri neden yanıtlamadığını anlamak için bu bilgileri kullanabilmelisiniz.

Muhtemel sebepler

Sağladığınız bilgiler, Docker istemcinizin Docker daemon'undan yanıt alamamasının nedenini belirlemekte yeterli değildir, ancak işte bazı ipuçları:

  • Docker arka plan programı çalışıyor mu?
  • Docker arka planını ön planda başlatırsanız ne olur ?: sudo docker daemon
  • Docker arka plan programı soketi dinliyor /var/run/docker.sockmu? orada bir yerde sudo lsof -p $DOCKER_PID" /var/run/docker.sock type=STREAM" göstermeli .
  • İstemcide veya servisteki bir şeyi engelleyecek güvenlik politikaları var mı? Linux'ta SELinux ve AppArmor, onlar için belirlenen politikaların erişimi engelleyebileceği için karışıklığa neden olabilir.
  • Gelen straceEğer istemciden bir HTTP GET isteği alamazsanız cini, bu sunucu soketi bir şey almadı anlamına gelir.
  • Eğer cenaze töreninde arama olmadığını docker versiongörüyorsanız strace, cennet uname()sistem hakkında bilgi toplamaya çalışmadı bile.
  • Eğer write()çağrıyı stracedaemon içinde görürseniz , bu daemonun cevap verdiği anlamına gelir, ancak müşteri bunu görmedi.
  • Belki de bu, kullandığınız Docker'ın eski sürümünde bilinen bir sorundur. Yükseltmeyi dene.

1
Bana göre, bunun nedeni dockersadece TCP soketinde dinlemekti ve docker.sock'ta değil. Bunu anlayana kadar çıldırıyordum (tam cevabınız için bana çok yardımcı olan teşekkür ederiz). Yaptığınızdan /etc/sysconfig/docker-networkemin olmak için iki kez kontrol edin-H unix:///var/run/docker.sock
Doomsday
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.