Docker compose,使用同一映像的两个服务:第一个服务失败,返回“0”;“没有这样的形象”;,第二次正常运行

Docker compose,使用同一映像的两个服务:第一个服务失败,返回“0”;“没有这样的形象”;,第二次正常运行,docker,docker-compose,gitlab-ci,docker-swarm,Docker,Docker Compose,Gitlab Ci,Docker Swarm,TL;DR:除了服务的名称和发布的端口之外,我的撰写文件中有两个几乎相同的服务。当使用docker stack deploy…部署时,为什么第一个服务会失败,并且没有这样的映像错误,而使用相同映像的第二个服务运行得非常好 Full:我有一个docker compose文件,其中有两个ApacheTomcat服务从我的私有git存储库中提取相同的映像。mydocker compose.yml中的两个服务之间的唯一区别是服务的名称(*\u dev与*\u prod)和发布的端口。我使用Gitlab

TL;DR:除了服务的名称和发布的端口之外,我的撰写文件中有两个几乎相同的服务。当使用
docker stack deploy…
部署时,为什么第一个服务会失败,并且没有这样的映像错误,而使用相同映像的第二个服务运行得非常好

Full:我有一个docker compose文件,其中有两个ApacheTomcat服务从我的私有git存储库中提取相同的映像。my
docker compose.yml
中的两个服务之间的唯一区别是服务的名称(
*\u dev
*\u prod
)和发布的端口。我使用Gitlab CI和
Gitlab CI.yml
在swarm上部署这个docker compose文件。为了在这个
gitlab ci.yml
中部署docker compose,我使用两个命令:

...
   script:
     - docker pull $REGISTRY:$TAG
     - docker stack deploy -c docker-commpose.yml webapp1 --with registry-auth
...
(我使用
docker pull[image]
命令将图像放在右侧节点上,因为我的
--with registry auth
工作不正常,但这目前不是我的问题)

现在奇怪的是,对于第一个服务,我得到一个
没有这样的图像:
错误,服务被停止,而对于第二个服务,一切似乎都运行得很好。两个服务都位于同一工作节点上。这是如果我
docker ps

:~$ docker service ps webapp1_tomcat_dev
ID          NAME                       IMAGE          NODE           DESIRED STATE       CURRENT STATE             ERROR                              PORTS
xxx1        webapp1_tomcat_dev.1       url/repo:tag   worker1 node   Shutdown            Rejected 10 minutes ago   "No such image: url/repo:tag@xxx…"
xxx2         \_ webapp1_tomcat_dev.1   url/repo:tag   worker1 node   Shutdown            Rejected 10 minutes ago   "No such image: url/repo:tag@xxx…"
:~$ docker service ps webapp1_tomcat_prod
ID          NAME                    IMAGE          NODE           DESIRED STATE       CURRENT STATE            ERROR               PORTS
xxx3        webapp1_tomcat_prod.1   url/repo:tag   worker1 node   Running             Running 13 minutes ago
我使用了
--no trunc
acquire来查看
*\u prod
*\u dev
使用的
图像是否相同

my docker compose中的
重新启动\u策略
解释了为什么第一个服务在第二个服务启动三分钟后失败。这是我的docker compose:

version: '3.2'

services:
  tomcat_dev:
    image: url/repo:tag
    deploy:
      restart_policy:
        condition: on-failure
        delay: 60s
        window: 120s
        max_attempts: 1
    ports:
      - "8282:8080"

  tomcat_prod:
    image: url/repo:tag
    deploy:
      restart_policy:
        condition: on-failure
        delay: 60s
        window: 120s
        max_attempts: 1
    ports:
      - "8283:8080"
为什么第一个服务失败时没有这样的映像错误?例如,是否不可能有两个使用相同映像的服务在同一工作节点上工作

(我不能简单地扩展一项服务,因为我需要将不同于生产和开发的文件上传到webapp,例如
dev
vs
prod
许可证,因此我需要两种不同的服务)

编辑:第二个服务工作,因为它是第一个创建的:

$ docker stack deploy -c docker-compose.yml webapp1 --with-registry-auth
Creating service webapp1_tomcat_prod
Creating service webapp1_tomcat_dev

我找到了一个解决办法,将我的服务分为两个不同的docker compose文件(
docker-compose-prod.yml
docker-compose-dev.yml
),并在我的
gitlab ci.yml
中执行
docker stack deploy
命令两次:

...
   script:
     - docker pull $REGISTRY:$TAG
     - docker stack deploy -c docker-commpose-prod.yml webapp1 --with registry-auth
     - docker pull $REGISTRY:$TAG
     - docker stack deploy -c docker-commpose-dev.yml webapp1 --with registry-auth

...

我的直觉告诉我,我的docker compose中的
restart_策略
也太严格了(有
max_尝试次数:1
),可能是由于这个原因,图像无法及时/在一次重启内使用(如@Ludo21South所建议的)。因此,我允许更多的尝试,但由于我已经将服务分为两个文件(已经工作了),我没有检查这一假设是否正确。

我通过将我的服务分为两个不同的docker compose文件(
docker-compose-prod.yml
docker-compose-dev.yml
)找到了解决方法并在my
gitlab ci.yml
中执行两次
docker stack deploy
命令:

...
   script:
     - docker pull $REGISTRY:$TAG
     - docker stack deploy -c docker-commpose-prod.yml webapp1 --with registry-auth
     - docker pull $REGISTRY:$TAG
     - docker stack deploy -c docker-commpose-dev.yml webapp1 --with registry-auth

...

我的直觉告诉我,我的docker compose中的
restart_策略
也太严格了(有
max_尝试次数:1
),可能是由于这个原因,图像无法及时/在一次重启内使用(如@Ludo21South所建议的)。因此,我允许更多的尝试,但由于我已经将服务分为两个文件(已经工作),我没有检查这个假设是否正确。

如果您尝试在docker compose之外运行一个新容器,会发生什么?你能用随机名称创建3或4个实例吗?如果正确映射端口,并且理论上不使用相同的名称,则应该能够生成实例,直到内存耗尽。另外,当您从脚本中运行docker pull时,是否会遇到相同的错误?我似乎觉得*\u dev不作为映像存在?@Ludo21South我以前有一个
docker退出过(137)
code(=OOM),例如,当我在这个特定的worker上只运行了第一个scale=2的服务时,这有关系吗?如何检查第一次服务是否因OOM而停止?然后我是否应该检查
worker1节点的可用内存?我的docker pull命令声明,除了url/repo:tag
消息的
图像是最新的之外,没有什么特别的。这两个服务都使用相同的映像,所以您认为*\u dev不作为映像存在到底是什么意思?谢谢你的回复,非常感谢!是否在创建第一个容器时docker拉动尚未完成?与Docker compose不同,Docker堆栈不便于构建图像。例如,当您根据prod生成tomcat_dev时会发生什么?注意:我的docker知识非常基础(堆栈实际上是不存在的),所以我只想用我认为是调试方法的任何东西。也;忘记我的docker pull命令,我又把名称和图像名称搞混了。除非无法生成映像,否则OOM错误与此无关,在这种情况下,产品也应该失败。不,在启动
docker stack deploy
命令之前,
docker pull
命令首先完成(我检查了我的Gitlab CI作业)。奇怪的是,第二个服务在使用相同的图像时工作得非常好。使用
docker compose up-d--build
在本地机器上的项目上下文中(使用
build:context:。
而不是我的compose文件中的
image:url/repo:tag
),部署这两个服务也没有问题。在这种情况下,我完全没有主意了。希望其他人能帮助您。如果您尝试在docker compose之外运行新容器,会发生什么?你能用随机名称创建3或4个实例吗?如果正确映射端口,并且理论上不使用相同的名称,则应