CF vs Kube: Is the difference who creates the container?
Cloud Foundry is an Application Runtime. Kubernetes is a Container Runtime. This much has (now) been made clear by the Cloud Foundry Foundation’s new marketing. I’ve heard some folks describe the fundamental difference between the Application Runtime (what most people think of as CF) and the new Container Runtime as “platform-created vs. user-provided containers”. It has the advantage of being easy to understand, but I’m gonna argue it’s wrong.
Cloud Foundry is an Application Runtime. What that really means is it’s a platform for running stateless apps. That’s — really — what we mean by “application”. (It’s kind of like Serverless is really a platform for running stateless functions).
In fact personally I think CF has much more to do with Serverless than with Kubernetes or other Container platforms. The abstractions are (stateless) functions, (stateless) apps and (stateful) services.
It happens to be the case that CF — because it’s an app platform and wants to let the user focus on their code — provides a way to convert code in to containers inside the platform without having to start messing around with Dockerfiles and the like. And this functionality even does some cool things for you like keeping your container OS automatically patched so you don’t have to build CI pipelines to monitor your base images and rebuild stuff.
But — and for me this is the reason I get up in the morning and work on CF: that’s not what Cloud Foundry is about. The magic of Cloud Foundry would still be magic (to me) if users had to ship their own containers to the platform and buildpacks were just a nice way to create them (along with Dockerfiles, Google Container Builder and so on). The magic of Cloud Foundry is: it optimises for stateless apps. And, because it’s optimised for stateless apps, it makes assumptions that save me time and complexity.
For example: it provides a service catalog so I have a cross-cloud way to deal with state rather than baking state management in to my app (friends don’t let friends push stateful services in the same bundle as their app).
For example: it means I don’t have to provide ReplicationControllers or DeploymentControllers or StatefulSets or PetSets or anything to scale my app. My app is a bit of stateless code that listens on a URL, so I scale it by just telling the platform to scale it.
It means I don’t have to think about how to deal with instances of my app crashing. The platform knows my app is stateless, so it can just spin up a new instance. And, for the same reason, when the platform needs to roll out upgrades it knows it can just create an extra instance of my app somewhere else — so I don’t need to plan for an outage, it all just works.
Most importantly: because I know every single app in a CF deployment is stateless and deployed in the same way, when stuff explodes — or just when I swap teams and work on another app — I know it works exactly the same as every other app in the system.
That’s why I love Cloud Foundry’s Application Runtime. Of course, because of these constraints — the constraints that are why I love it — the App Runtime can’t possibly work for complex stateful services: the whole point is for it not to. And that’s why it’s fantastic that there’s now a Container Runtime (which I wish we’d called a Stateful Services Runtime because that’s how I think of it).
But the difference isn’t who creates the containers: it’s how much I have to think about orchestrating them. Maybe someday CF will use a different scheduler, maybe we’ll make code-to-container creation a plugin for any orchestrator you like, maybe Dockerfiles will become standard enough that everyone uses them. I hope, though, we’ll keep what makes CF great: it’s a multi-tenant runtime for stateless apps.