使用docker Go客户端并行构建docker映像

使用docker Go客户端并行构建docker映像,docker,go,dockerfile,Docker,Go,Dockerfile,我正在使用Docker的Go客户端来构建我的项目。这突出说明了如何使用Go客户端实现这一点。我在我的三个Dockerfile(1.Dockerfile、2.Dockerfile和3.Dockerfile)上调用ImageBuild,作为测试。这是我的密码: func GetContext(filePath string) io.Reader { // Use homedir.Expand to resolve paths like '~/repos/myrepo' filePat

我正在使用Docker的Go客户端来构建我的项目。这突出说明了如何使用Go客户端实现这一点。我在我的三个Dockerfile(
1.Dockerfile
2.Dockerfile
3.Dockerfile
)上调用
ImageBuild
,作为测试。这是我的密码:

func GetContext(filePath string) io.Reader {
    // Use homedir.Expand to resolve paths like '~/repos/myrepo'
    filePath, _ = homedir.Expand(filePath)
    ctx, err := archive.TarWithOptions(filePath, &archive.TarOptions{})
    if err != nil {
        panic(err)
    }

    return ctx
}

func testImageBuild() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        log.Fatal(err, " :unable to init client")
    }

    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            dockerFile := fmt.Sprintf("%d.Dockerfile", i)
            imageBuildResponse, err := cli.ImageBuild(
                ctx,
                GetContext("."),
                types.ImageBuildOptions{
                    Dockerfile: dockerFile,
                    Tags:       []string{fmt.Sprintf("devbuild_%d", i)},
                })
            if err != nil {
                log.Fatal(err, " :unable to build docker image"+string(1))
            }
            defer imageBuildResponse.Body.Close()
            _, err = io.Copy(os.Stdout, imageBuildResponse.Body)
            if err != nil {
                log.Fatal(err, " :unable to read image build response "+string(1))
            }
        }(i)
    }
    wg.Wait()
}

func main() {
    testImageBuild()
}
func GetContext(文件路径字符串)io.Reader{
//使用homedir.Expand解析像“~/repos/myrepo”这样的路径
filePath,u=homedir.Expand(filePath)
ctx,err:=archive.TarWithOptions(filePath,&archive.TarOptions{})
如果错误!=零{
恐慌(错误)
}
返回ctx
}
func testImageBuild(){
ctx:=context.Background()
cli,err:=client.NewEnvClient()
如果错误!=零{
log.Fatal(错误,“:无法初始化客户端”)
}
var wg sync.WaitGroup
对于i:=0;i<3;i++{
工作组.添加(1)
go func(i int){
推迟工作组完成()
dockerFile:=fmt.Sprintf(“%d.dockerFile”,i)
imageBuildResponse,错误:=cli.ImageBuild(
ctx,
GetContext(“.”),
types.ImageBuildOptions{
Dockerfile:Dockerfile,
标记:[]字符串{fmt.Sprintf(“devbuild_u%d”,i)},
})
如果错误!=零{
log.Fatal(错误,“:无法生成docker映像”+字符串(1))
}
延迟imageBuildResponse.Body.Close()
_,err=io.Copy(os.Stdout,imageBuildResponse.Body)
如果错误!=零{
log.Fatal(错误:“:无法读取映像生成响应”+字符串(1))
}
}(一)
}
wg.Wait()
}
func main(){
testImageBuild()
}
GetContext
用于将目录路径作为Docker的上下文进行tar
testImageBuild
派生三个不同的goroutine来构建三个不同的映像


我的问题是:当我运行这个程序时,stdout的输出总是相同的,而且似乎是确定的,这让我觉得这些图像实际上并不是并行构建的。我不熟悉docker是如何构建映像的,而且这种方法完全可能只是将请求并行发送到docker服务器,而不是实际并行构建。这是真的吗?如果是这样,我如何并行构建我的项目?

如果我正确理解了您的问题,您有一台docker机器,您希望在该机器上同时使用GO程序构建图像

我试图对正在构建的具有相同映像的DockerFile做同样的事情,根据我的理解,它们都是同时构建的

这是我用来复制场景的go包-


现在,在您的案例中,如果您使用3个不同的docker文件,那么它们肯定会有不同的构建时间,这意味着输出似乎是确定性的

您如何能够通过检查docker机器中创建映像的时间戳来验证它们是同时构建的。您可以ssh到docker机器中,然后执行
docker映像ls-a | grep dev
,我共享的代码中的应该打印出创建容器的时间戳。