【发布时间】:2020-05-11 09:48:57
【问题描述】:
TL;DR:我的撰写文件中有两个几乎相同的服务,除了服务的名称和发布的端口。使用docker stack deploy... 部署时,为什么第一个服务失败并出现 no such image 错误,而使用相同图像的第二个服务运行正常?
完整:我有一个 docker-compose 文件,其中有两个 Apache Tomcat 服务从我的私有 git 存储库中提取相同的图像。我的docker-compose.yml 中的两个服务之间的唯一区别是服务的名称(*_dev 与*_prod)和发布的端口。我使用带有gitlab-ci.yml 的 Gitlab CI 在我的 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 无法正常工作,但这不是我目前的问题)。
现在奇怪的是,对于第一个服务,我收到一个No such image: 错误并且服务停止了,而对于第二个服务,一切似乎都运行得很好。两个服务都在同一个工作节点上。如果我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得到,发现*_prod和*_dev使用的IMAGE是一样的。
我的 docker-compose 中的 restart_policy 解释了为什么第一个服务在第二个服务启动三分钟后失败。这是我的 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"
为什么第一个服务失败并没有这样的图像错误?例如,是否不可能有两个使用相同图像的服务在同一个工作节点上工作?
(我不能简单地扩大一项服务,因为我需要将文件上传到 web 应用程序,这些文件对于生产和开发是不同的 - 例如 dev 与 prod 许可证 - 因此我需要两个不同的服务)
编辑:第二个服务有效,因为它是首先创建的:
$ docker stack deploy -c docker-compose.yml webapp1 --with-registry-auth
Creating service webapp1_tomcat_prod
Creating service webapp1_tomcat_dev
【问题讨论】:
-
如果你尝试在 docker-compose 之外运行一个新容器会发生什么?你能用随机名称创建 3 或 4 个实例吗?如果您正确映射端口并且理论上不使用相同的名称,您应该能够生成实例,直到内存不足。另外,当您从脚本运行 docker pull 时,您会遇到同样的错误吗?我好像 *_dev 不作为图像存在?
-
@Ludo21South 我之前有一个
docker exited (137)代码(=OOM),当我在这个特定的工作人员上只运行第一个规模=2 的服务时,这可能是相关的吗?如何检查第一个服务是否因 OOM 而停止?然后我应该检查worker1 node的可用内存吗?除了image is up to date for url/repo:tag消息外,我的 docker pull 命令没有任何特别之处。并且这两个服务都使用相同的图像,那么 *_dev 不作为图像存在是什么意思?感谢您的回复,非常感谢! -
会不会是第一个容器创建的时候docker pull还没有完成?与 docker compose 相比,Docker 堆栈不利于构建图像。例如,当您根据产品制作 tomcat_dev 时会发生什么?注意:我的 docker 知识非常基础(几乎不存在堆栈),所以我只是按照我认为的调试方式进行。还;忘记我的 docker pull 命令,我再次混淆了名称和图像名称。除非无法构建映像,否则 OOM 错误应该与它无关,在这种情况下,PROD 也应该失败。
-
不,
docker pull命令在启动docker stack deploy命令之前首先完成(我检查了我的 Gitlab CI 作业)。奇怪的是,第二个服务使用相同的图像工作得非常好。在我的本地计算机上的项目上下文中使用docker-compose up -d --build(在我的撰写文件中使用build: context: .而不是image: url/repo:tag)部署这两个服务也没有问题。 -
在那种情况下,我完全没有想法。希望其他人可以帮助您。
标签: docker docker-compose gitlab-ci docker-swarm