docker - 从 Docker buildkit 获取容器 ID 以进行交互式调试
问题描述
众所周知,您可以docker commit
针对失败的构建过程运行以获取容器的快照以进行调试。running in <ID>
容器 ID 是从文本中收集的。buildx
但是,在使用 Docker 的较新 BuildKit功能进行构建期间不会发出此文本。
我尝试--progress plain
在 Docker build 命令上使用,但这并没有显示容器 ID。另外,我无法从吐出的图像层 ID(SHA 哈希)运行新容器。
示例 BuildKit 输出
使用此命令:
#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
问题:如何在每个步骤中获取构建过程的容器 ID,特别是在使用 Docker BuildKit 时?
解决方案
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 您要在stage-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
使用多个阶段有助于故障排除,但它确实加快了构建过程,因为并行分支可以构建在不同的实例上。此外,构建文件的可读性显着提高。
推荐阅读
- selenium-webdriver - 如何验证是否在 Ruby 的 selenium webdriver 中打开了新选项卡?
- php - PHP数据库表格展示
- docker - Docker :: 为 Synology NAS 上的每个容器分配不同的 IP 地址
- docker - 如何将文件复制到docker中的容器
- python - 如何在 Pandas 的数据框中获取行号和列号?
- sql - 如何选择与表中项目相关的第一行和最后一行?
- javascript - let 变量的作用域
- ms-access - 图像未显示在网格表中
- python - 如何对字典中的项目进行排序并显示最大的键和值?
- java - 可以将 java DataSource 转换为另一种 DataSource 类型,如 HikariDataSource 吗?