我试图为我们的开发过程构建一个新的Docker映像,使用cpanm安装一堆Perl模块作为各种项目的基本映像。
在开发Dockerfile时,cpanm返回一个失败代码,因为一些模块没有干净地安装。
我很确定我需要准备安装更多的东西。
我在哪里可以找到/。在输出中引用Cpanm /work目录,以便检查日志?在一般情况下,我如何检查一个失败的docker构建命令的文件系统?
在运行一个发现后,我发现
/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm
这是可靠的吗,还是我最好构建一个“裸”容器并手动运行一些东西,直到我拥有所有我需要的东西?
目前最新的docker-desktop,没有办法选择退出
的新Buildkit,它还不支持调试(请参考
在这个GitHub线程上的最新更新:
https://github.com/moby/buildkit/issues/1472)。
找出Dockerfile中的哪一行出错了。
添加到Dockerfile的顶部:FROM xxx作为调试
添加一个额外的目标:FROM xxx作为下一个,就在失败命令的前一行(因为你不想构建那部分)。例子:
FROM xxx as debug
RUN echo "working command"
FROM xxx as next
RUN echoo "failing command"
运行docker build -f Dockerfile——target debug——tag debug。
然后你可以调试容器:docker运行- debug /bin/sh
您可以通过按CTRL P + CTRL Q退出shell
如果你想使用docker compose build而不是docker build,可以在docker-compose中添加target: debug。Yml正在建设中。
然后通过docker撰写运行xxxYourServiceNamexxx来启动容器,并使用其中之一:
上面的第二个答案是找出如何在容器中运行shell。
或者在FROM xxx之前添加ENTRYPOINT /bin/sh作为Dockerfile中的下一行。
如果您希望在命令失败之前立即检查状态,上面的答案是有效的。
但是,问题询问如何检查失败容器本身的状态。在我的情况下,失败的命令是一个需要几个小时的构建,所以在失败的命令之前倒回并再次运行它需要很长时间,而且没有太大帮助。
这里的解决方案是找到失败的容器:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6934ada98de6 42e0228751b3 "/bin/sh -c './utils/" 24 minutes ago Exited (1) About a minute ago sleepy_bell
将其提交到一个图像:
$ docker commit 6934ada98de6
sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83
然后运行映像[如果需要,运行bash]:
$ docker run -it 7015687976a4 [bash -il]
现在您实际上看到的是构建失败时的状态,而不是运行导致失败的命令之前的状态。
目前最新的docker-desktop,没有办法选择退出
的新Buildkit,它还不支持调试(请参考
在这个GitHub线程上的最新更新:
https://github.com/moby/buildkit/issues/1472)。
找出Dockerfile中的哪一行出错了。
添加到Dockerfile的顶部:FROM xxx作为调试
添加一个额外的目标:FROM xxx作为下一个,就在失败命令的前一行(因为你不想构建那部分)。例子:
FROM xxx as debug
RUN echo "working command"
FROM xxx as next
RUN echoo "failing command"
运行docker build -f Dockerfile——target debug——tag debug。
然后你可以调试容器:docker运行- debug /bin/sh
您可以通过按CTRL P + CTRL Q退出shell
如果你想使用docker compose build而不是docker build,可以在docker-compose中添加target: debug。Yml正在建设中。
然后通过docker撰写运行xxxYourServiceNamexxx来启动容器,并使用其中之一:
上面的第二个答案是找出如何在容器中运行shell。
或者在FROM xxx之前添加ENTRYPOINT /bin/sh作为Dockerfile中的下一行。
仍然使用BuildKit,正如Alexis Wilke的回答,您可以使用ktock/ building。
参见Kohei Tokunaga的“Dockerfile的交互式调试器”
build是一个基于BuildKit交互调试Dockerfile的工具。
源代码级检验
断点和步骤执行
交互式shell的一步与您自己的调试工具
基于BuildKit(需要未合并的补丁)
支持无根的
例子:
$ buildg.sh debug --image=ubuntu:22.04 /tmp/ctx
WARN[2022-05-09T01:40:21Z] using host network as the default
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.1s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 195B done
#2 DONE 0.1s
#3 [internal] load metadata for docker.io/library/busybox:latest
#3 DONE 3.0s
#4 [build1 1/2] FROM docker.io/library/busybox@sha256:d2b53584f580310186df7a2055ce3ff83cc0df6caacf1e3489bff8cf5d0af5d8
#4 resolve docker.io/library/busybox@sha256:d2b53584f580310186df7a2055ce3ff83cc0df6caacf1e3489bff8cf5d0af5d8 0.0s done
#4 sha256:50e8d59317eb665383b2ef4d9434aeaa394dcd6f54b96bb7810fdde583e9c2d1 772.81kB / 772.81kB 0.2s done
Filename: "Dockerfile"
2| RUN echo hello > /hello
3|
4| FROM busybox AS build2
=> 5| RUN echo hi > /hi
6|
7| FROM scratch
8| COPY --from=build1 /hello /
>>> break 2
>>> breakpoints
[0]: line 2
>>> continue
#4 extracting sha256:50e8d59317eb665383b2ef4d9434aeaa394dcd6f54b96bb7810fdde583e9c2d1 0.0s done
#4 DONE 0.3s
...
调试构建步骤失败确实非常烦人。
我发现的最好的解决方案是确保每一个真正工作的步骤都成功,并在那些失败的步骤之后添加检查。通过这种方式,您可以获得一个包含您可以检查的失败步骤的输出的已提交层。
一个Dockerfile,在# Run DB2静默安装行之后有一个示例:
#
# DB2 10.5 Client Dockerfile (Part 1)
#
# Requires
# - DB2 10.5 Client for 64bit Linux ibm_data_server_runtime_client_linuxx64_v10.5.tar.gz
# - Response file for DB2 10.5 Client for 64bit Linux db2rtcl_nr.rsp
#
#
# Using Ubuntu 14.04 base image as the starting point.
FROM ubuntu:14.04
MAINTAINER David Carew <carew@us.ibm.com>
# DB2 prereqs (also installing sharutils package as we use the utility uuencode to generate password - all others are required for the DB2 Client)
RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y sharutils binutils libstdc++6:i386 libpam0g:i386 && ln -s /lib/i386-linux-gnu/libpam.so.0 /lib/libpam.so.0
RUN apt-get install -y libxml2
# Create user db2clnt
# Generate strong random password and allow sudo to root w/o password
#
RUN \
adduser --quiet --disabled-password -shell /bin/bash -home /home/db2clnt --gecos "DB2 Client" db2clnt && \
echo db2clnt:`dd if=/dev/urandom bs=16 count=1 2>/dev/null | uuencode -| head -n 2 | grep -v begin | cut -b 2-10` | chgpasswd && \
adduser db2clnt sudo && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# Install DB2
RUN mkdir /install
# Copy DB2 tarball - ADD command will expand it automatically
ADD v10.5fp9_linuxx64_rtcl.tar.gz /install/
# Copy response file
COPY db2rtcl_nr.rsp /install/
# Run DB2 silent installer
RUN mkdir /logs
RUN (/install/rtcl/db2setup -t /logs/trace -l /logs/log -u /install/db2rtcl_nr.rsp && touch /install/done) || /bin/true
RUN test -f /install/done || (echo ERROR-------; echo install failed, see files in container /logs directory of the last container layer; echo run docker run '<last image id>' /bin/cat /logs/trace; echo ----------)
RUN test -f /install/done
# Clean up unwanted files
RUN rm -fr /install/rtcl
# Login as db2clnt user
CMD su - db2clnt
更新更新的docker版本20.10以上
Linux或macOS
DOCKER_BUILDKIT=0 docker build ...
窗户
# Command line
set DOCKER_BUILDKIT=0 docker build ...
# PowerShell
$env:DOCKER_BUILDKIT=0
使用
DOCKER_BUILDKIT=0 docker build…
从旧版本中获取中间容器哈希值。
在较新的版本上,Buildkit默认是激活的。建议仅将其用于调试目的。Build Kit可以使您的构建更快。
供参考:
Buildkit不支持中间容器哈希:https://github.com/moby/buildkit/issues/1053
感谢@David Callanan和@MegaCookie的投入。