从Docker buildkit获取用于交互式调试的容器ID

从Docker buildkit获取用于交互式调试的容器ID,docker,Docker,众所周知,您可以对失败的生成过程运行docker commit,以获取容器的快照,以进行调试。容器ID是从运行在文本中的中收集的。但是,在使用Docker较新的BuildKitbuildx功能进行构建时,不会发出此文本 我试着在Docker build命令上使用--progress plain,但没有显示容器ID。另外,我无法从吐出的图像层ID(SHA哈希)运行新容器 构建工具包输出示例 使用此命令: #1 [internal] load build definition from Docker

众所周知,您可以对失败的生成过程运行
docker commit
,以获取容器的快照,以进行调试。容器ID是从运行在文本中的
中收集的。但是,在使用Docker较新的BuildKit
buildx
功能进行构建时,不会发出此文本

我试着在Docker build命令上使用
--progress plain
,但没有显示容器ID。另外,我无法从吐出的图像层ID(SHA哈希)运行新容器

构建工具包输出示例 使用此命令:

#1 [internal] load build definition from Dockerfile
#1 sha256:0e70418d547c3ccb20da7b100cf4f69564bddc416652e3e2b9b514e9a732b4aa
#1 transferring dockerfile: 32B done
#1 DONE 0.0s

#2 [internal] load .dockerignore
#2 sha256:396b2cfd81ff476a70ecda27bc5d781bd61c859b608537336f8092e155dd38bf
#2 transferring context: 34B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/node:latest
#3 sha256:1c0b05b884068c98f7acad32e4f7fd374eba1122b4adcbb1de68aa72d5a6046f
#3 DONE 0.0s

#4 [1/4] FROM docker.io/library/node
#4 sha256:5045d46e15358f34ea7fff145af304a1fa3a317561e9c609f4ae17c0bd3359df
#4 DONE 0.0s

#5 [internal] load build context
#5 sha256:49d7a085caed3f75e779f05887e53e0bba96452e3a719963993002a3638cb8a3
#5 transferring context: 35.17kB 0.0s done
#5 DONE 0.1s

#6 [2/4] ADD [trevortest/*, /app/]
#6 sha256:6da32965a50f6e13322efb20007ff49fb0546e2ff55799163b3b00d034a62c57
#6 CACHED

问题:在每个步骤中,特别是在使用Docker BuildKit时,如何获取构建过程的容器ID?

BuildKit的工作方式与传统Docker构建系统不同。目前,还没有直接的方法从构建中的一个步骤生成一个容器并对其进行故障排除

为了最大限度地利用BuildKit的潜力,最好的方法是在较小的逻辑阶段组织构建。以这种方式组织生成后,在运行生成时,可以使用
--target
指定要在某个阶段停止。指定目标后,Docker将创建一个包含该阶段构建结果的图像。您可以使用此容器以与旧构建系统相同的方式进一步进行故障排除

就拿这个例子来说。这里我有4个阶段,其中2个是平行阶段:

FROM debian:9.11 AS stage-01
# Prepare for installation
RUN apt update && \
    apt upgrade -y

FROM stage-01 as stage-02
# Install building tools
RUN apt install -y build-essential

FROM stage-02 as stage-02a

RUN echo "Build 0.1" > /version.txt

FROM stage-02 as stage-03

RUN apt install -y cmake gcc g++
现在,您可以使用
--target
选项告诉Docker您想在
阶段02停止,如下所示:

$ docker build -f test-docker.Dockerfile -t test . --target stage-02                                                                                                                                   [+] Building 67.5s (7/7) FINISHED
 => [internal] load build definition from test-docker.Dockerfile                                 0.0s
 => => transferring dockerfile: 348B                                                             0.0s
 => [internal] load .dockerignore                                                                0.0s
 => => transferring context: 2B                                                                  0.0s
 => [internal] load metadata for docker.io/library/debian:9.11                                   0.0s
 => [stage-01 1/2] FROM docker.io/library/debian:9.11                                            0.0s
 => CACHED [stage-01 2/2] RUN apt update &&     apt upgrade -y                                   0.0s
 => [stage-02 1/1] RUN apt install -y build-essential                                           64.7s
 => exporting to image                                                                           2.6s
 => => exporting layers                                                                          2.5s
 => => writing image sha256:ac36b95184b79b6cabeda3e4d7913768f6ed73527b76f025262d6e3b68c2a357     0.0s
 => => naming to docker.io/library/test                                                          0.0s
现在您有了名为
test
的映像,您可以生成一个容器来进行故障排除

docker run -ti --rm --name troubleshoot test /bin/bash
root@bbdb0d2188c0:/# ls

使用多个阶段有助于故障排除,但是它确实加快了构建过程,因为并行分支可以构建在不同的实例上。此外,构建文件的可读性也有了很大的提高。

您是否打算将Buffic ID存储在管道的中间,以调试或检查管道是否以错误结束?如果您的目标是能够选择使用commit命令创建的特定图像,那么我有一个主意,就是@JRichardsz。我想基本上使用一个成功构建的中间映像层来启动一个新容器并检查文件系统。在调试时,不要使用buildkit?这是一个极好的答案,Jordan!谢谢分享。我已经相应地标出了答案。