运行 Web 应用程序组件作为单个服务与 Kubernetes 中的多个服务

Running web application components as a single service versus multiple services in Kubernetes

我有一个网络应用程序(例如 "india")依赖于 postgres 和 redis(例如典型的 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. 我可以构建 indiapostgres-indiaredis-india 作为单个部署(因此单个 pod / service)

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

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

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

谢谢!

独立组件

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

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

您的应用应设计为 stateless, and can be deployed as a Deployment. But the Redis and PostgreSQL are stateful components and should be deployed as StatefulSet

可用性

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

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

无状态 应用程序部署为 Deployment, this is trivial to solve - run at least two instances (replicas) of it - and make sure they are deployed on different nodes in the cluster. You can do this using Topology Spread Constraints

使用 stateful 组件,例如Redis or PostgreSQL,这个比较难。您通常需要 运行 它作为一个集群。参见例如Redis Cluster. But it is more difficult for PostgreSQL, you could consider a PostgreSQL-compatible db that has a distributed design, e.g. CockroachDB that is designed to be run on Kubernetes or perhaps consider CrunchyData PostgreSQL Operator.

具有多个容器的 Pod

当您使用 multiple containers, one container is the "main" application and the other containers are supposed to be "helper" / "utility" containers to fix a problem for the "main container" - e.g. if your app logs to two different files - you could have helper containers to tail those files and output it to stdout, as is the recommended log output in Twelve-Factor App 部署 Pod 时。您通常只对未设计为在 Kubernetes 上 运行 的应用程序使用“多个容器”,或者如果您想要扩展某些功能,例如服务网格。