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.