docker在CI中运行时编写竞态条件

docker在CI中运行时编写竞态条件,docker,docker-compose,Docker,Docker Compose,我在CI中运行docker compose smoke测试……当同一项目的两个构建同时执行时,构建通常会失败。我确信构建是在同一台机器上通过共享docker套接字并发执行的。docker compose似乎试图从另一个实例重用/访问容器,并最终陷入某种竞争状态 我尝试了各种标志来解决这个问题,但仍然失败。当前标志为:--从烟雾中退出代码--删除孤立项--强制重新创建 使用--exit code from意味着--abort on container exit 如何使构建容器的这两个实例彼此隔离

我在CI中运行docker compose smoke测试……当同一项目的两个构建同时执行时,构建通常会失败。我确信构建是在同一台机器上通过共享docker套接字并发执行的。docker compose似乎试图从另一个实例重用/访问容器,并最终陷入某种竞争状态

我尝试了各种标志来解决这个问题,但仍然失败。当前标志为:
--从烟雾中退出代码--删除孤立项--强制重新创建
使用--exit code from意味着--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
文档说明:

撰写项目名称

设置项目名称。该值在启动时与服务名称一起添加到容器中。例如,如果您的项目名为myapp,它包含两个服务db和web,那么Compose将分别启动名为myapp_db_1和myapp_web_1的容器

此设置是可选的。如果未设置此选项,则COMPOSE_PROJECT_名称默认为项目目录的basename。另请参见-p命令行选项

因此,在您的情况下,如果有两个
docker compose
命令试图使用相同的目录在同一台机器上同时运行,那么它们都将投影名称:
smoke\u test

这意味着如果两次调用
使冒烟
同时发生,它们都会看到带有
冒烟测试
前缀的容器,并尝试管理/重新创建它们,因为它们认为它们属于它们,而实际上它们可能不属于它们

解决方案:

最简单的解决方案是使用
docker compose
--project name
标志为每次调用
make smoke
指定一个唯一的项目名称

一种方法是:

docker-compose--project name$(数据+'%s')-f冒烟测试/docker-compose.yaml-up--从冒烟中退出代码--删除孤立项--强制重新创建

这样,每次调用
docker compose
都会将其容器与其他同时调用
make smoke
的容器隔离开来

另一方面,我认为生成唯一项目名称的首选方法是使用构建号,而不是unix时间戳


希望这会有所帮助。

您能提供您的Makefile,并用make目标更新问题吗