为什么“docker规模”和“docker抬高 – 规模 – 没有规模 – 不重build”有什么区别?

我正在使用Docker Compose来启动并连接11个Docker容器。 到目前为止,我还没有探索Kubernetes(等等),因为我怀疑这是一个我目前没有时间的大事业。 因此,当我的应用程序完成后,我计划与Compose一起生活。

因为我正在使用持续集成,所以我希望在应用程序正在使用的时候,我会频繁地部署新的容器,所以我希望能够透明地重新启动容器(所以旧容器被replace为一个新的容器,停机时间为零)。 为此,我使用Traefik作为前端代理,重置路由规则的dynamic文件configuration以及一些(PHP)脚本,以便对dockerdocker-compose二进制文件进行适当的调用。

理论是这样的:

  • 基于图像M1的容器C1正在运行
  • 图像M2被构build并通过CI
  • 运行映像M2的容器C2在Docker Compose中启动(使用缩放function)
  • Traefik被告知切换到新的容器C2而不是C1
  • 集装箱C1停止

诚然,这是一个“穷人的协调”,是的,我应该转向被广泛使用和testing的东西。 但是,我有这个工作,并希望至less在短期内坚持下去。

我正在使用这个版本的DC:

docker构成版本1.13.0,构build1719ceb

up命令问题

所以,这里是我遇到的问题 – 我如何创build一个在Docker Compose中定义的服务的新实例? 我的解决scheme是使用缩放,所以它会有点像这样。 要扩大后续missive-storage-backend ,我会这样做:

 docker-compose -p app -f docker-compose.yml up -d \ --no-recreate --no-deps --scale missive-storage-backend=2 

这会使现有的(旧)实例单独存在,并创build一个没有连接任何东西的(最新的)实例(即现在我们有两个实例)。 大! 所以,使用我的自定义脚本,我会重写Traefikconfiguration,应用程序将继续使用新组件。 最后,旧的容器可以停止。

这工作到目前为止。 但是,如果我现在想重新启动别的东西,事情就会出错。 比方说,我想升级missive-interface 。 很酷,所以我会这样做:

 docker-compose -p app -f docker-compose.yml up -d \ --no-recreate --no-deps --scale missive-interface=2 

这具有创buildInterface的新实例的效果,并重新启动之前升级的容器(Storage Backend)。 我想这是因为Docker Compose认识到missive-storage-backend的实例不是它开始的实例,所以它再次将scale = 1规则应用于它。

公平地说,不必要的重新启动不会随着旧容器的版本(它们都是最新版本)而变化。 不过,我的脚本并不期望两次重新启动,并且只为一个。 我可以解决这个问题,但坦率地说,我觉得我正在修补一个漏斗。

缩放命令解决scheme

所以,我正在尝试scale命令。 DC手册说,这是由docker-compose up --scale ,但它的行为有所不同。 这是第一个启动命令:

 docker-compose -p app -f docker-compose.yml \ scale missive-storage-backend=2 

这工作很好,根据最后一次。 现在开始第二个容器的新版本:

 docker-compose -p app -f docker-compose.yml \ scale missive-interface=2 

这正确地导致该容器的开始,这正是我想要的。 (然后我重新configurationTraefik来切换新的容器,然后调用docker stop old-container-hash来取消旧docker stop old-container-hash )。

那么,我是否误解了docker up --scale --no-deps --no-recreate的目的 – docker up --scale --no-deps --no-recreate ? 或者有我不寻常的扩展使用发现了一个错误? 这让我感到我应该能够在华盛顿特区扩展个人服务,而无需将所有服务YAML设置复制到单独的docker命令。

顺便说一下,我确实尝试了一个docker-compose create ,但没有得到任何地方 – 它没有创build我想要的服务的额外实例,并意外地杀死了其他人。 尽pipe如此,如果你认为这将是一条更好的路。

最后,我在up命令之后尝试了“整理”,通过重命名旧的/停止的容器,然后将新的命名重命名为默认情况下的_1string。 但是,那发现了一个Dockernetworking错误,所以我放弃了这个思路!

如果有所作为,Docker守护进程将在主机上运行,​​但是我通过映射卷的/var/run/docker.sock:/var/run/docker.sock来在“控制”容器内运行DC命令主办容器。