docker - 在 CI 中运行时的 docker-compose 竞争条件
问题描述
我有一个在 CI 中运行的 docker-compose 烟雾测试....当同一项目的两个构建同时执行时,构建通常会失败。我确信构建是在具有共享 docker 套接字的同一台机器上同时执行的。似乎 docker-compose 试图从另一个实例重用/访问容器并最终处于某种竞争状态。
我尝试了各种标志来解决这个问题,但仍然失败。当前的标志是:--exit-code-from smoke --remove-orphans --force-recreate
using --exit-code-from implies --abort-on-container-exit
如何保持这两个构建容器实例相互隔离?
下面是一个失败的例子:
+ make smoke
ls: /var/lib/docker/volumes/0_3542251907521744511_default/_data: No such file or directory
ls: '/var/lib/docker/volumes/0_3542251907521744511_default/_data'/src/github.myco.com/viper-ace/psn-router/'}: No such file or directory
docker-compose version 1.23.2, build 1110ad0 docker-py version: 3.6.0 CPython version: 2.7.15 OpenSSL version: LibreSSL 2.7.4
docker-compose -f smoke-test/docker-compose.yaml up --exit-code-from smoke --remove-orphans --force-recreate
using --exit-code-from implies --abort-on-container-exit
Recreating mock-maker ...
Recreating mock-maker ... done
Recreating psn-router ...
Recreating psn-router-500 ...
Recreating psn-router-500 ... done
Recreating psn-router ... done
Recreating smoke ...
Attaching to mock-maker, psn-router-500, psn-router, smoke
mock-maker | > mock-maker@0.1.0 start /usr/src/app
psn-router-500 | 2019-04-11T16:36:21.411Z level=INFO, code=0000, src=psn-router/server.go:87, s=psn-router, hostname=psn-router-instance, c=UNKNOWN, site=UNKNOWN, m="Listen and Serve: http://127.0.0.1:8080"
mock-maker | > node mock-maker.js
psn-router | 2019-04-11T16:36:21.441Z level=INFO, code=0000, src=psn-router/server.go:87, hostname=psn-router-instance, c=UNKNOWN, site=UNKNOWN, s=psn-router, m="Listen and Serve: http://127.0.0.1:8080"
mock-maker | MockMaker app listening at http://:::80
Unexpected API error for psn-router (HTTP code 404)
Response body:
{"message":"No such container: 89460559a3e81a230f5647d52997c5b05bf94f3bdc8e268ca9654d3945ca675d"}
Recreating smoke ... done
Stopping psn-router-500 ...
Stopping mock-maker ...
Stopping psn-router-500 ... done
Stopping mock-maker ... done
No such container: 8dec60de6fb3657c0a70e9d53aa27e385b9bd50c24e6cb332d1a7cc373bb7afa
Aborting on container exit...
make: *** [Makefile:22: smoke] Error
这是 docker-compose 文件:
services:
mock-maker:
container_name: "mock-maker"
image: registry.myco/viper-ace/mock-maker:0.11.0
psn-router-500-endpoint:
container_name: "psn-router-500"
image: "${DOCKER_IMAGE}"
depends_on:
- mock-maker
environment:
- ENDPOINT= http://mock-maker/endpoint500
psn-router:
container_name: "psn-router"
image: "${DOCKER_IMAGE}"
depends_on:
- mock-maker
environment:
- ENDPOINT= http://mock-maker/endpoint200
smoke:
container_name: "smoke"
image: registry.myco/http-blackbox-test-tool:2.0.2
depends_on:
- psn-router
volumes:
- ${SMOKE_TEST_DIR}:/smoke-test
environment:
- TEST_DIR=/smoke-test
制定目标:
smoke:
@echo $(shell docker-compose version)
SMOKE_TEST_DIR=$(CODE_DIR)/smoke-test DOCKER_IMAGE=${DOCKER_IMAGE} docker-compose -f smoke-test/docker-compose.yaml up --exit-code-from smoke --remove-orphans --force-recreate
解决方案
您面临的问题是由于docker-compose
使用所谓的项目名称将容器“链接”到特定docker-compose
调用的事实。
以下是docker-compose
文档中有关项目名称的内容:
COMPOSE_PROJECT_NAME
设置项目名称。在启动时,该值会与服务名称一起添加到容器中。例如,如果您的项目名称是 myapp,并且它包含两个服务 db 和 web,那么 Compose 会分别启动名为 myapp_db_1 和 myapp_web_1 的容器。
设置这是可选的。如果您不设置此项,COMPOSE_PROJECT_NAME 默认为项目目录的基本名称。另请参见 -p 命令行选项。
因此,在您的情况下,如果您有两个docker-compose
命令尝试使用同一目录在同一台计算机上同时运行,则它们都将具有项目名称:smoke_test
.
这意味着如果两个调用make smoke
同时发生,它们都将看到带有smoke_test
前缀的容器并尝试管理/重新创建它们,因为它们认为它们属于它们,而实际上它们可能不属于它们。
解决方案:
对您来说最简单的解决方案是为每次make smoke
使用--project-name
标志的调用指定一个唯一的项目名称docker-compose
。
一种方法是:
docker-compose --project-name $(data +'%s') -f smoke-test/docker-compose.yaml up --exit-code-from smoke --remove-orphans --force-recreate
这样,每个 的 调用都docker-compose
将使其容器与 . 的其他同时调用隔离make smoke
。
顺便说一句,我认为生成唯一项目名称的首选方法是使用内部版本号之类的东西,而不是使用 unix 时间戳。
希望这会有所帮助。
推荐阅读
- arduino - Arduino NANO RP2040 Connect 串行直通不起作用
- android - 如何在活动或应用程序销毁后保持 OnCompleteListener 运行?
- python - matplotlib set_xdata 乱序绘图
- deep-learning - 用神经网络对多元函数进行近似,使用哪个激活函数?
- google-chrome - 截屏并用 JS 发送到服务器
- c# - 通过剪贴板和控制台应用程序更改任何文本框的内容
- c# - 如何在 .NET 5 中安装 Grpc.AspNetCore 的最新依赖项?
- spring-boot - SpringBoot 编辑用户角色列表
- r - 如何将自动导入文件的名称设置为它们在 R 中的文件名?
- rust - 是否有一个宏可以用来期待枚举的变体并提取其数据?