docker swarm模式下的数据库迁移

我有一个由简单的Node应用程序和Mongo数据库组成的应用程序。 我想知道,我怎么能在docker swarm模式下运行数据库迁移?

在没有swarm模式的情况下,我通过先停止旧版本的应用程序,运行一次性迁移命令和新版本的应用程序,然后启动新版本的应用程序来运行迁移:

# Setup is roughly the following $ docker network create appnet $ docker run -d --name db --net appnet db:1 $ docker run -d --name app --net appnet -p 80:80 app:1 # Update process $ docker stop app && docker rm app $ docker run --rm --net appnet app:2 npm run migrate $ docker run -d --name app --net appnet -p 80:80 app:2 

现在我正在Docker群模式下testing这个设置,这样我就可以轻松地缩放app 。 问题是,在群模式下,不能在群集networking中启动容器,因此我无法到达db来运行迁移:

 $ docker network ls NETWORK ID NAME DRIVER SCOPE 6jtmtihmrcjl appnet overlay swarm # Trying to replicate the manual migration process in swarm mode $ docker service scale app=0 $ docker run --rm --net appnet app:2 npm run migrate docker: Error response from daemon: swarm-scoped network (appnet) is not compatible with `docker create` or `docker run`. This network can only be used by a docker service. 

我不想在app启动过程中运行迁移命令,因为可能会启动多个实例,并可能会使数据库发生故障。 自动迁移是可怕的,所以我想不惜一切代价避免它们。

你有什么想法如何实施docker群模式下的手动迁移步骤?

编辑

我发现了一个肮脏的黑客,允许复制原来的工作stream程。 想法是用自定义命令创build一个新的服务,并在其任务完成后将其删除。 这远不是令人愉快的用法,更好的替代scheme比欢迎!

 $ docker service scale app=0 $ docker service create --name app-migrator --network appnet app:2 npm run migrate # Check when the first app-migrator task is finished and check its output $ docker service ps app-migrator $ docker logs <container id from app-migrator> $ docker service rm app-migrator # Ready to update the app $ docker service update --image app:2 --replicas 2 app 

我相信你可以解决这个问题,让你的覆盖networking,appnet,可以连接。 这可以通过以下命令来完成:

 docker network create --driver overlay --attachable appnet 

这应该修复swarm范围的networking错误,并允许您运行迁移

这确实是一个棘手的情况,但我认为在创业期间进行迁移可能是最后一块难题。

我现在做的方式(尽pipe不是很优雅,它的工作原理)是使用message queue (我使用的是redis ),在应用程序启动时,它会向queue发送一条消息,通知它migration任务需要运行。 在queue的另一端,我有一个listener app ,它将处理queue并运行migration任务。 迁移任务只能运行一次,因为只有一个listener实例依次运行它。 所以基本上我只是使用queuelistener app来确保migration任务只运行一次。