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

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


Independent components

Your three components should run as separate deployments on Kubernetes. You want these three components to be:

  • Independently upgradable and deployable (e.g. you deploy a new version of Redis but not your app or database)
  • Independently scalable - e.g. you might get many users and want to scale up to multiple instances (e.g. 5 replicas) of your app.

State

Your app should be designed to be stateless, and can be deployed as a Deployment. But the Redis and PostgreSQL are stateful components and should be deployed as StatefulSet.

Availability

In a production environment, you typically want to:

  • Avoid downtime when upgrading any application or database
  • Avoid downtime if you or the cloud provider upgrade the node
  • Avoid downtime if the node crash, e.g. due to hardware failure or kernel crash.

With a stateless app deployed as a 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.

With a stateful component as e.g. Redis or PostgreSQL, this is more difficult. You typically need to run it as a cluster. See e.g. 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 with multiple containers

When you deploy a Pod with 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. You typically only use "multiple containers" for apps that are not designed to be run on Kubernetes, or if you want to extend with some functionality like e.g. a Service Mesh.