使用Golang API运行`docker run`(Docker文档)

huangapple go评论90阅读模式
英文:

`docker run` using Golang API (Docker docs)

问题

我正在尝试使用Docker的教程来重新创建一个docker run命令。以下是来自在线教程的代码:

package main

import (
	"io"
	"os"

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

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

	_, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})
	if err != nil {
		panic(err)
	}

	resp, err := cli.ContainerCreate(ctx, &container.Config{
		Image: "alpine",
		Cmd:   []string{"echo", "hello world"},
	}, nil, nil, "")
	if err != nil {
		panic(err)
	}

	if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
		panic(err)
	}

	if _, err = cli.ContainerWait(ctx, resp.ID); err != nil {
		panic(err)
	}

	out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
	if err != nil {
		panic(err)
	}

	io.Copy(os.Stdout, out)
}

我发现的问题是,如果本地没有可用的alpine镜像,它不会拉取最新的镜像,而是会抛出错误。例如:

$ go run go_docker.go
panic: Error: No such image: alpine

goroutine 1 [running]:
panic(0x27ffa0, 0xc4202afa50)
	/usr/local/go/src/runtime/panic.go:500 +0x1a1
main.main()
	/Users/rvenkatesh/go_coding/raghu_test_code/go_docker.go:30 +0x592
exit status 2

但是,当我运行等效的命令行命令时,我看到:

$ docker run alpine echo hello world
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
627beaf3eaaf: Pull complete

Digest:sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
Status: Downloaded newer image for alpine:latest
hello world

我尝试查看Go客户端文档,是否需要调整ImagePull函数的任何内容?在这里,任何帮助都将不胜感激!

这是文档的链接:https://docs.docker.com/engine/api/getting-started/

更新:我已经测试了相同的Python版本教程,它正常工作。我想知道Golang页面是否需要更新。

英文:

I am trying to use Docker's tutorial in recreating a docker run. Here is the following code from online tutorial

 package main

 import (
 "io"
 "os"

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

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

_, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})
if err != nil {
	panic(err)
}

resp, err := cli.ContainerCreate(ctx, &container.Config{
	Image: "alpine",
	Cmd:   []string{"echo", "hello world"},
}, nil, nil, "")
if err != nil {
	panic(err)
}

if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{});     err != nil {
	panic(err)
}

if _, err = cli.ContainerWait(ctx, resp.ID); err != nil {
	panic(err)
}

out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
	panic(err)
}

io.Copy(os.Stdout, out)
}

The problem I see with this is, if 'alpine' docker, is not available locally, it doesn't pull the latest and ends up throwing an error.
e.g
XXXXX$ go run go_docker.go
panic: Error: No such image: alpine

    goroutine 1 [running]:
      panic(0x27ffa0, 0xc4202afa50)
    /usr/local/go/src/runtime/panic.go:500 +0x1a1
    main.main()
    /Users/rvenkatesh/go_coding/raghu_test_code/go_docker.go:30 +0x592
    exit status 2

But when I run the commandline equivalent, I see

    XXXX$ docker run alpine echo hello world
    Unable to find image 'alpine:latest' locally
    latest: Pulling from library/alpine 
    627beaf3eaaf: Pull complete
    
        Digest:sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
    Status: Downloaded newer image for alpine:latest
    hello world

I tried looking through Go client, do I need to tweak anything with ImagePull function? Any help here would be appreciated!

Here is the link to the docs https://docs.docker.com/engine/api/getting-started/

Update: I had tested the same tutorial for python version, and it worked just fine. I wonder if the Golang page needs update.

答案1

得分: 1

Image.Pull返回一个io.Reader,你必须读取并关闭它;如果你不这样做,连接将在图像被拉取之前关闭。

你可以只是丢弃它的内容并关闭它,然后拉取就会成功。

英文:

Image.Pull returns an io.Reader which you must read and close; if you do not the connection will be closed before the image is pulled.

You can just discard the contents of it and close it, then the pull will work.

答案2

得分: 1

遇到了相同的问题,"Pull"似乎不起作用。不过找到了解决方法。

1)将你的pull行修改为:

pullstat, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})

并在ImagePull之后添加:

io.Copy(os.StdOut, pullstat)

我还没有尝试过:

io.Copy(nil, pullstat)

但这是我接下来要尝试的事情之一。

英文:

Was having the same issue, the "Pull" didn't seem to be working. Found a Fix though.

  1. Modify your pull line to

    pullstat, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})

and add

io.Copy(os.StdOut,pullstat) 

after the ImagePull

I haven't tried doing an

io.Copy(nil,pullstat) 

but that's on my list of things to try next.

答案3

得分: 0

Docker客户端是开源的,使用Go语言编写,因此你可以看到他们是如何实现的。我相信相关的代码在container/create.go的pullImage函数中。

英文:

The docker client is open source and written in Go, so you can see exactly how they've implemented their version. I believe the relevant code is in the container/create.go pullImage function.

huangapple
  • 本文由 发表于 2017年3月16日 00:57:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/42816132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定