我可以固定 docker API 版本吗:客户端版本 1.38 太新了。支持的最大 API 版本是 1.37

Can I pin docker API version : client version 1.38 is too new. Maximum supported API version is 1.37

有没有办法使用 golang 客户端固定 docker API 版本? (缺少使用 dep for vendoring

下面的代码失败

client version 1.38 is too new. Maximum supported API version is 1.37

此代码 运行 直到最近才正常

go version go1.9.5 linux/amd64

这里是:docker version

Client:
 Version:      18.05.0-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   f150324
 Built:        Wed May  9 22:16:25 2018
 OS/Arch:      linux/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.05.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   f150324
  Built:        Wed May  9 22:14:32 2018
  OS/Arch:      linux/amd64
  Experimental: false

这会导致 API 版本不匹配

package main

// kill off some containers

import (
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
    "golang.org/x/net/context"

    "strings"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err) // <--- crashes here due to API mismatch
    }

    containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})
    if err != nil {
        panic(err)
    }

    for _, container := range containers {

        if strings.Contains(container.Image, "enduser") || strings.Contains(container.Image, "admin") {

            fmt.Println("\n we found enduser or admin so lets stop it\n")

            fmt.Print("Stopping container ", container.ID[:10], "... ")
            if err := cli.ContainerStop(ctx, container.ID, nil); err != nil {
                panic(err)
            }
            fmt.Println("Success")
        }
    }
}

在英语中,上述错误是因为 github repo 客户端库的默认客户端版本比 Docker 支持的版本更新...所以要解决评论 - 一种方法works是请求低版本的repo库匹配Docker,而不是请求高版本

下面的谈判方法也很有效

cli, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation())

你可以通过NewClientWithOpts().

来索取具体的版本
package main

import (
    "net/http"

    "github.com/docker/docker/api/types/container"
    "github.com/docker/docker/client"
    "golang.org/x/net/context"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewClientWithOpts(client.WithVersion("1.37"))
    if err != nil {
        panic(err)
    }
}

参见 Versioned API and SDK。在尾端它使用 Go API 和(尝试)到 link 到相关代码:

You can specify the API version to use, in one of the following ways:

文档很难 link 到 master 分支上的行号,它可能已经更改,但上面的代码应该为您提供足够的上下文来理解。

我遇到了完全相同的问题,@zero298 的回答非常适合我 =)

然后我发现 client.WithAPIVersionNegotiation() 也成功了!

如果您不需要固定版本,而只想让代码与您的机器的任何版本一起工作运行,我认为此选项将满足您的需求。

ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
   panic(err)
}
cli.NegotiateAPIVersion(ctx)  // this line can negotiate API version

NegotiateAPIVersion客户端方法可以解决这个API版本不匹配的问题。