Docker Swarm 中的数据库持续部署
Continuous deployment with databases in Docker Swarm
我正忙于为我的移动应用程序开发 API,我现在正在研究后端解决方案的部署。组件相当简单:nginx、.NET 核心应用程序和用于持久性的 postgresql。如果我需要快速扩展,我想首先在单个节点上使用 Docker Swarm。为 Postgresql 使用单独的数据卷似乎是可行的方法,但我找不到任何关于升级和数据库迁移的建议。当我需要升级 Postgresql 映像时(不需要 pg_upgrade 的小升级),这是否必须手动操作,或者我可以通过滚动升级来管理吗?要求是在发生这种情况时关闭所有应用程序实例。同样,我如何管理数据库迁移,例如静态数据/架构更改?我将需要所有应用程序实例退出、完成迁移然后重新启动。非常感谢任何想法。
因此,完成此操作后,我想 post 详细说明我的解决方案最终是什么样子的。首先,我使用了 GoCD,它是一个出色的开源持续交付服务器,可以自动化从测试到生产的整个交付过程。使用 Docker 应用单一职责原则很好,所以我创建了单独的 Docker Swarm 堆栈,如下所示:
- 数据:由数据库容器组成,在我的例子中是postgresql
- Data-admin:托管用于基于 cron 的数据库备份、文件备份的容器和处理应用程序数据库先决条件(例如创建数据库/用户)的容器
- 应用程序:C# 应用程序 API 的可扩展容器,以及使用 db-up
管理数据库迁移的容器
- Web:托管一个 Traefik 容器 - 一个反向代理服务器,配置为将流量路由到应用程序堆栈
- 监控:托管 logstash、logspout、kibana、grafana 和 portainer 的容器,应用程序记录到 elasticsearch 和 kibana / grafana 提供此数据的可视化。 Portainer 支持群的基本管理。
提交到 master 分支上的 BitBucket 存储库会触发通过 GoCD 对我的测试环境的更新,在 CentOS 上使用相当数量的 bash 脚本将这一切编织在一起。当测试看起来不错时,我可以 push-button 部署到生产环境中。 Docker 容器中的图像是 GoCD 构建工件,并作为构建过程的一部分进行了版本控制,因此很容易在必要时恢复并重新发现它们。
我消化的关于数据库升级的大部分信息都建议备份应用程序数据库并将它们恢复到新版本的容器实例。有关详细信息,请参阅 https://peter.grman.at/upgrade-postgres-9-container-to-10/。对于应用程序数据库迁移,我创建了一个特定于应用程序的 'devops' 用户,该用户有权进行架构更改。此用户被传递到应用程序的数据库迁移容器,并且不会在任何其他数据库上工作。应用程序容器本身仅提供给权限较低的应用程序用户。
可以说有很多复杂的问题需要克服,例如服务间依赖和启动,但通常的谷歌搜索和毅力带来了回报。现在效果很好!
注意:如果您只希望应用程序容器在保证数据库初始化时开始服务(即所有迁移 运行),那么需要注意的一种模式是提供一个端口,其他模式在该端口上服务可以检查服务健康状况。在我的例子中,我让数据库迁移容器监听一个端口,以便在所有迁移 运行 时提供响应。尝试从应用程序容器连接到数据库是不够的,因为它不知道架构是否为 up-to-date.
我正忙于为我的移动应用程序开发 API,我现在正在研究后端解决方案的部署。组件相当简单:nginx、.NET 核心应用程序和用于持久性的 postgresql。如果我需要快速扩展,我想首先在单个节点上使用 Docker Swarm。为 Postgresql 使用单独的数据卷似乎是可行的方法,但我找不到任何关于升级和数据库迁移的建议。当我需要升级 Postgresql 映像时(不需要 pg_upgrade 的小升级),这是否必须手动操作,或者我可以通过滚动升级来管理吗?要求是在发生这种情况时关闭所有应用程序实例。同样,我如何管理数据库迁移,例如静态数据/架构更改?我将需要所有应用程序实例退出、完成迁移然后重新启动。非常感谢任何想法。
因此,完成此操作后,我想 post 详细说明我的解决方案最终是什么样子的。首先,我使用了 GoCD,它是一个出色的开源持续交付服务器,可以自动化从测试到生产的整个交付过程。使用 Docker 应用单一职责原则很好,所以我创建了单独的 Docker Swarm 堆栈,如下所示:
- 数据:由数据库容器组成,在我的例子中是postgresql
- Data-admin:托管用于基于 cron 的数据库备份、文件备份的容器和处理应用程序数据库先决条件(例如创建数据库/用户)的容器
- 应用程序:C# 应用程序 API 的可扩展容器,以及使用 db-up 管理数据库迁移的容器
- Web:托管一个 Traefik 容器 - 一个反向代理服务器,配置为将流量路由到应用程序堆栈
- 监控:托管 logstash、logspout、kibana、grafana 和 portainer 的容器,应用程序记录到 elasticsearch 和 kibana / grafana 提供此数据的可视化。 Portainer 支持群的基本管理。
提交到 master 分支上的 BitBucket 存储库会触发通过 GoCD 对我的测试环境的更新,在 CentOS 上使用相当数量的 bash 脚本将这一切编织在一起。当测试看起来不错时,我可以 push-button 部署到生产环境中。 Docker 容器中的图像是 GoCD 构建工件,并作为构建过程的一部分进行了版本控制,因此很容易在必要时恢复并重新发现它们。
我消化的关于数据库升级的大部分信息都建议备份应用程序数据库并将它们恢复到新版本的容器实例。有关详细信息,请参阅 https://peter.grman.at/upgrade-postgres-9-container-to-10/。对于应用程序数据库迁移,我创建了一个特定于应用程序的 'devops' 用户,该用户有权进行架构更改。此用户被传递到应用程序的数据库迁移容器,并且不会在任何其他数据库上工作。应用程序容器本身仅提供给权限较低的应用程序用户。
可以说有很多复杂的问题需要克服,例如服务间依赖和启动,但通常的谷歌搜索和毅力带来了回报。现在效果很好!
注意:如果您只希望应用程序容器在保证数据库初始化时开始服务(即所有迁移 运行),那么需要注意的一种模式是提供一个端口,其他模式在该端口上服务可以检查服务健康状况。在我的例子中,我让数据库迁移容器监听一个端口,以便在所有迁移 运行 时提供响应。尝试从应用程序容器连接到数据库是不够的,因为它不知道架构是否为 up-to-date.