I'm currently at Craft Conf, where the vast majority of the topics seem to focus around either Kubernetes or server-less architecture. As a result, a discussion broke out around which is better. And I am willing to bet that you read the title of this post expecting a brutal showdown. A list of stats, metrics, justifications as to why I prefer one over the other. Wrong, because:
They are the same
OK, well obviously they're not the same. But if you stick with me for a minute I would like to explain why in many ways I believe they're fundamentally trying to achieve the same goal of abstracting us from virtual infrastructure, or in other words, abstracting us from our cloud providers.
So keeping that in mind; lets reword the quote slightly:
They can be used to achieve some of the same goals, for example virtual infrastructure abstraction
That's looking a little less provocative so lets go with that for a while and see where we get.
Goal: Virtual Infrastructure Abstraction
So lets consider that goal. In order to consider it - I think it is important to take a step back for a minute and understand the evolutionary steps that have brought us here.
It's a journey of minimising low value work, work that doesn't deliver any real value when looking at the goals of the product we're working on, you know the sort of work I'm talking about.. that 20% of your time you spend on your project writing ansible and terraform scripts to manage your application servers, thinking about deployment strategies, vulnerability patching etc. That same 20% you spend on pretty much every project. We just want to focus on the high value bits, you know - the stuff your stakeholders
From here on out, you must excuse the terrible drawing skils...
From left to right folks, this is what happened:
- We're building physical servers, and deploying our apps to those servers.
- We're really tired of how long it takes to build physical servers, so instead we build a whole cluster of physical servers and run virtual servers on top of those. Yay, we get our apps running faster.
- We're really tired of having to buy and replace hardware, plus running our data centre just costs a fortune. So we pay a cloud provider to do that bit for us. Yay, we have more predictable costs and less work, so we can be faster.
- We're really tired of having to think about how to patch, monitor, scale or virtual machines. Plus we are really tired of paying for virtual machines which aren't really taking any load. So lets just get rid of the servers all together, right? Yay, even less work, lets be even faster!
- There is no 5 on my diagram.... I do wish I could predict the future!
It's plain to see that the only consistency across this whole picture is that valuable part - the application, we're slowly chipping away at the rest in different ways.
So lets briefly take a look at the two opponents in the ring today. And lets face them off with the challenge of building and deploying a single page web chat application, which serves up some static content, and some dynamic content from a database.
FaaS (Functions as a Service)
Fancy title; it's a vendor agnostic way of saying Lambda or App Engine. But we all know what I'm talking about - so lets use Amazon as an example. Your typical server-less architecture for the above problem ends up looking something like this:
The premise is simple really, create your application code as a Lambda function (or even a whole nodejs app), front the Lambda function with an API gateway, provision your DynamoDB as your message store and serve your static content from S3.
Amazon handles the scheduling and running of these bits across a multi-tenant server environment. There is also no such thing as server-less in the literal sense, there are always servers, it's just about who you're paying to look after them, and how good of a job they do.
Server-less is in the eye of the beholder
- Totally scalable, no infrastructure concerns at all
- Only paying for exactly what you use
- Server-less naturally leans itself towards a micro-services style architecture, so you have clearly defined components and responsibilities
- Lends itself extremely nicely to Event Driven Architectures
- You're having to think about Continuous Integration and Continuous delivery across four different AWS services, and then the composition and orchestration between those components
- There is currently no industry standard 'abstraction' for server-less technologies, so the tendency is to build server-less architectures which are vendor locked
- You are limited to the technologies and versions that the server-less provider supports
- You therefore have a higher dependency on that provider, they become a bigger BAU stakeholder. For example; if they decide to retire a version of node, or worse, an entire service.
- Having a representative development environmental locally is not possible (so offline development is harder)
I have to give credit where credit is due, Amazon are thinking about the 'standards' problem with Serverless Application Model. It's just early days (by their own admission too).
So lets take a look at the same problem being solved on a kubernetes cluster.
The application stack here would be marginally smaller, we would have three well-known technologies as images, our nodejs app, mariadb and nginx, and then we would deploy those images to Kubernetes.
Kubernetes would then schedule the running images (pods) to one of the minion nodes, it'd handle the load balancing and scaling too.
You still have Virtual Machines and a Kubernetes cluster to look after
Screams the person wearing the AWS Lambda T-shirt and the S3 hat
Wowzer, they're right - and we're talking about abstracting ourselves from virtual infrastructure here so it would only be fair to compare to a PaaS offering of Kubernetes. The forerunner in this space at the moment is Google Container Engine however with Microsofts recent acquisition of Deis as well as Kubernetes dominance in the container orchestration space, I think we will see more of these cloud based platform offerings coming.
With a PaaS offering, Kubernetes is built and managed for you, including patching of the underlying machines. You never go onto the underlying machine, literally ever.
- The ability to support almost any tech stack, in any configuration (double edged sword)
- Vendor agnostic, Kubernetes acts as an abstraction between you and the cloud provider (or even your local machine)
- Kubernetes is totally open source too, and has great community support
- An easier migration path for non-greenfield applications (ie you can bundle up an existing application in a container faster than you can break it down into functions for FaaS)
- The ability to run on entirely your own hardware; should the problem require such a setup
- You still have to manage your docker containers, for example - vulnerabilities inside them
- Kubernetes can scale both the pods, and the underlying machines - but not as quickly as a FaaS function can deal with load
- Despite auto scaling, you always have some running costs, as there is a minimal amount of 24/7 machine time in order to run Kubernetes itself
At a very, very high level - this is where I feel we're sat at the moment. In this diagram, the more faded the part, the less we want to care about it.
I do believe what we're seeing are multiple ways of doing virtual infrastructure abstraction. Just like we saw multiple ways of doing private cloud abstraction, and we saw multiple ways of doing physical infrastructure abstraction.
From a consulting perspective, I find the concept of virtual infrastructure abstraction extremely exciting. We've all come across situations where clients are interested in moving to the public cloud, but is a political process that will take a long time to resolve. Well, what if we could pragmatically do that, starting by abstracting them from their own private cloud first with a layer like SAM or Kubernetes, and then the migration path to a public cloud provider is much less daunting.
And finally, as Dan North put it recently at Craft Conf, there are trade offs in any decision we make. There are multiple ways to solve any problem, and there are pros and cons to each - each of those decisions need to be made for each problem you're trying to solve.
For those who haven't seen Dan's talk by the way, you should check it out here.