我想知道如何通过执行中间构建层并在该层外运行调试容器来监视其中的内容来调试Docker构建。
因为在任何地方都找不到答案,所以我创建了自定义解决方案,效果很好(见下文)。
答案 0 :(得分:0)
解决方案
我在管道中添加了debug-failed-build
作业,该作业将该层作为docker映像上传到Gitlabs Docker注册表:
.gitlab-registry-login: &local-registry-login
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
build:
stage: build
script:
- *local-registry-login
- docker build --pull -t "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}" . | tee docker-build-debug.out
- docker push "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}"
artifacts:
paths:
- docker-build-debug.out
when: on_failure
expire_in: 30 mins
debug-failed-build:
stage: debug
script:
- *local-registry-login
- DEBUG_LAYER=$(grep '\-\-\-> [0-9a-z]' docker-build-debug.out |tail -1| cut -b 7-)
- docker tag "$DEBUG_LAYER" "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}-failed"
- docker push "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}-failed"
when: on_failure
dependencies:
- build
工作方式
Docker构建的输出存储在一个文件中,该文件在发生故障的情况下作为工件传递给debug-failed-build
作业。这是一个示例,Docker构建的输出看起来像(只是片段):
Step 16/19 : VOLUME ["/sys/fs/cgroup"]
---> Using cache
---> a63a68682fcb
Step 17/19 : COPY --from=ansibleci-base /ansibleci-base /ansibleci-base
---> Using cache
---> 98fa646b73fb
Step 18/19 : RUN ln -s /ansibleci-base/scripts/run-tests.sh /usr/local/bin/run-tests && ln -s /ansibleci-base/ansible-plugins/human_log.py /usr/local/lib/python3.6/dist-packages/ansible/plugins/callback/human_log.py
---> Running in 83116392053c
ln: failed to create symbolic link '/usr/local/lib/python3.6/dist-packages/ansible/plugins/callback/human_log.py': No such file or directory
DEBUG_LAYER=...
脚本命令后面的表达式将从Docker构建输出(98fa646b73fb
)中提取最后一个层ID。下一条命令将为该层提供一个准备好要上载到注册表的图像名称,最后一条命令将上载该图像。
作为上传图像的替代方法,您还可以将图层另存为文件(使用docker save
),并将保存的图像存储为压缩的tar存档。然后,将这个档案定义为Gitlab CI Artifact,您可以将其下载到计算机上并docker load
在那里。