小编典典

以编程方式检查Docker容器进程是否以非零状态结束

go

我正在使用Go应用程序,该应用程序使用Go Docker SDK启动一些Docker容器。我需要检查容器的进程是否以零(成功)状态代码退出。

这是最小的工作示例:

package main

import (
    "context"
    "io"
    "log"
    "os"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/api/types/container"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.Background()

    cli, err := client.NewEnvClient()
    if err != nil {
        log.Fatal(err)
    }

    reader, err := cli.ImagePull(
        ctx,
        "docker.io/library/alpine",
        types.ImagePullOptions{},
    )
    if err != nil {
        log.Fatal(err)
    }
    io.Copy(os.Stdout, reader)

    resp, err := cli.ContainerCreate(ctx, &container.Config{
        Image: "alpine",
        Cmd:   []string{"sh", "-c", "echo hello world; return 1"},
        Tty:   true,
    }, nil, nil, "")
    if err != nil {
        log.Fatal(err)
    }

    err = cli.ContainerStart(
        ctx,
        resp.ID,
        types.ContainerStartOptions{},
    )
    if err != nil {
        log.Fatal(err)
    }

    statusCh, errCh := cli.ContainerWait(
        ctx,
        resp.ID,
        container.WaitConditionNotRunning,
    )
    select {
    case err := <-errCh:
        if err != nil {
            log.Fatal(err)
        }
    case <-statusCh:
    }

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

    io.Copy(os.Stdout, out)
}

如您所见,容器中的进程以非零状态(sh -c "echo hello world; return 1")结尾。但是,它不会记录任何致命错误,只会hello world在构建和执行时显示:

{"status":"Pulling from library/alpine","id":"latest"}
{"status":"Digest: sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430"}
{"status":"Status: Image is up to date for alpine:latest"}
hello world

如何使用Docker Go SDK检查以非零状态退出的容器进程?


阅读 276

收藏
2020-07-02

共1个答案

小编典典

我认为您应该使用状态通道来获取退出代码。错误通道似乎用于通知与docker守护进程对话时是否有错误,请参阅https://godoc.org/github.com/docker/docker/client#Client.ContainerWait

这对我有用:

select {
case err := <-errCh:
    if err != nil {
        log.Fatal(err)
    }
case status := <-statusCh:
    log.Printf("status.StatusCode: %#+v\n", status.StatusCode)
}
2020-07-02