1

我有一个"india"依赖于 postgres 和 redis 的 Web 应用程序(例如)(例如,典型的 Rails 应用程序)。

我有一个docker-compose.yml组成容器的文件来启动这个应用程序。

version: '3'
services:

  redis-india:
    image: redis:5.0.6-alpine
    # .....

  postgres-india:
    image: postgres:11.5-alpine
    # ....

  india:
    depends_on:
      - postgres-india
      - redis-india
    image: india/india:local
    # ....

我想用 Kubernetes 运行这个应用程序部署。我试图弄清楚如何正确构建 k8s 资源对象,我正在权衡两个选项:

  1. 我可以在 k8s 中构建indiapostgres-indiaredis-india作为单独的部署(因此是单独的服务)

  2. 我可以构建india,postgres-indiaredis-india作为单个部署(因此单个pod/ service

#2 对我个人来说更有意义——这里的所有 3 项都包含应该作为单个服务 URL 公开的整个“应用程序服务”(即 Web 应用程序的前端)。

但是,如果我使用自动化工具kompose将我的docker-compose.yml文件转换为 k8s 资源,它会遵循方法 #1 并创建三个单独的 k8s 服务。

我应该遵循“正确的方法”或标准吗?

谢谢!

4

1 回答 1

4

独立组件

您的三个组件应该在 Kubernetes 上作为单独的部署运行。您希望这三个组件是:

  • 可独立升级和部署(例如,您部署了新版本的 Redis,但没有部署您的应用程序或数据库)
  • 独立可扩展 - 例如,您可能会获得许多用户并希望扩展到应用程序的多个实例(例如 5 个副本)。

状态

您的应用程序应设计为无状态的,并且可以部署为Deployment。但是 Redis 和 PostgreSQL 是有状态的组件,应该部署为StatefulSet

可用性

在生产环境中,您通常希望:

  • 升级任何应用程序或数据库时避免停机
  • 如果您或云提供商升级节点,请避免停机
  • 如果节点崩溃,例如由于硬件故障或内核崩溃,请避免停机。

使用部署为部署的无状态应用程序,这很容易解决 - 运行它的至少两个实例(副本) - 并确保它们部署在集群中的不同节点上。您可以使用Topology Spread Constraints来做到这一点。

对于有状态的组件,例如 Redis 或 PostgreSQL,这更加困难。您通常需要将其作为集群运行。参见例如Redis 集群。但是对于 PostgreSQL 来说更难,您可以考虑一个具有分布式设计的 PostgreSQL 兼容数据库,例如设计为在 Kubernetes 上运行的 CockroachDB 或者考虑CrunchyData PostgreSQL Operator

带有多个容器的 Pod

当您部署具有多个容器的 Pod 时,一个容器是“主”应用程序,而其他容器应该是“助手”/“实用程序”容器,以解决“主容器”的问题 - 例如,如果您的应用程序登录到两个不同的文件 - 您可以使用辅助容器来跟踪这些文件并将其输出到标准输出,就像Twelve-Factor App中推荐的日志输出一样。您通常只对并非设计为在 Kubernetes 上运行的应用程序使用“多个容器”,或者如果您想使用某些功能(例如服务网格)进行扩展。

于 2021-08-29T07:03:08.420 回答