Вступление
Я пытаюсь использовать следующую версию docker
на виртуальной машине Linux (uname -a
возвращает Linux xen 4.1.17-yocto-standard #1 SMP PREEMPT Thu Jun 2 13:29:47 PDT 2016 x86_64 GNU/Linux)
, сборка из рецепта docker_git
docker_git.
Если я пытаюсь запустить docker version
, я получаю следующий вывод:
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
Затем команда зависает.
Как это должно выглядеть
Я попытался выполнить docker version
на работающей установке Docker (Ubuntu 14.04), и я получил следующий вывод:
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
Итак, я предполагаю, что есть какая-то ошибка при получении информации о сервере.
Дополнительные исследования
Я не знаком с Go, так что этот раздел может вызывать недовольство, когда я пытаюсь выяснить, что здесь происходит.
Я начал смотреть на эту часть api/client/version.go
исходного кода Docker:
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}}`
это продолжается в этом разделе:
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(),
},
}
Из engine-api/types/client.go
:
// VersionResponse holds version information for the client and the server
type VersionResponse struct {
Client *Version
Server *Version
}
Таким образом, все, что нужно сделать на этом этапе, это назначить что-то члену Server
(типа *Version
). Это происходит в разделе, следующем за назначением vd
сверху:
serverVersion, err := cli.client.ServerVersion(context.Background())
if err == nil {
vd.Server = &serverVersion
}
Определение функции для ServerVersion
следующее из 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
}
Из того, что я могу собрать, вышеперечисленные функции get
точки вызова для client/request.go
из репозитория engine API
Docker.
// 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)
}
Куда:
ctx
этоcontext.Background()
path
/version
- нет
query
- без
headers
И эта документация для sendRequest
от 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
}
Некоторое время это была догадка, и теперь я обеспокоен тем, что могу искать не в том месте.
Вопросы
- Что приводит к зависанию
docker version
docker run hello-world
,docker images
,docker ps
иdocker info
Docker и как это можно исправить? - Или есть более эффективный способ проверить причину этой ошибки?