How to organize pods with non-replicatable containers in kubernetes?

2/11/2016

I'm trying to get my head around kubernetes.

I understand that pods are a great way to organize containers that are related. I understand that replication controllers are a great way to ensure they are up and running.

However, I do not get how to do it in real life.

Given a webapp with, say a rails app on unicorn, behind nginx with a postgres database.

The nginx and rails app can autoscale horizontally (if they are shared nothing), but postgres can't out of the box.

Does that mean I can't organize the postgres database within the same pod as nginx and rails, when I want to have two servers behind a loadbalancer? Does postgres need an own replication controller and is simply a service within the cluster?

The general question about that is: In common webscenarios, what kind of containers are going into one pod? I know that this can't be answered generally, so the ideas behind it are interesting.

-- shredding
kubernetes
postgresql

2 Answers

2/12/2016

The answer to this really depends on how far down the rabbithole you want to go. You are really describing 3 independent parts of your app - ngingx, rails, postgres. Each of those parts has different needs when it comes to monitoring, scaling, and updating.

You CAN put all 3 into a single pod. That replicates the experience of a VM, but with some advantages for manageability, deployment etc. But you're already calling out one of the major disadvantages - you want to scale (for example) the rails app but not the postgres instance. It's time to decompose.

What if you instead made 2 pods - one for rails+nginx and one for postgres. Now you can scale your frontend without messing up your database deployment. You might go even further and split your rails app and nginx into distinct pods, if that makes sense. Or split your rails app into 5 smaller apps.

This is the whole idea behind microservices (which is a very hyped word, I know). Decompose the problem into smaller and more manageable chunks. This is WHY kubernetes exists - to help you manage the resulting ocean of microservices.

To answer your last question - there is no single recipe. It's all about how your application is structured and what makes sense FOR YOU. Maybe you want to decompose along team boundaries, or along departments in your company, or along admin roles. The questions to ask yourself are things like "if I update or scale this pod, is there any part of it that I don't want updated/sclaed at the same time?"

In some sense it is a data normalization problem. A pod should be a model of one concept or owner or scope. I hope that helps a little.

-- Tim Hockin
Source: StackOverflow

2/11/2016

You should put containers into the same pod when you want to deploy and update them at the same time or if they need to share local state (disk, network, etc). In some edge cases, you may also want to co-locate them for performance reasons.

In your scenario, since nginx and the rails app can scale horizontally, they should be in their own pods so that you can provision the right number of replicas for each tier of your application (unless you would always scale them at the same time). The postgres database would be in a separate pod, accessed via a service.

This allows you to update to a newer version of nginx without changing anything else about your service. Same for the rails app. And they could each scale independently.

-- Robert Bailey
Source: StackOverflow