Hosting a static blog on Kubernetes?

| 3 min read

Yes, this blog post, as of today, is served by a Kubernetes cluster. Yes, it's overkill, and no, I'm not sorry.

Kubernetes is a complex piece of technology that originated from the needs of a large organization. It shines at a large scale. The Kubernetes installation that serves this page is not large. Quite the opposite.

Why, then, would anyone choose to use Kubernetes to serve static HTML files?

Kubernetes for Application Developers

When I put on my application dev hat, Kubernetes very often is exactly how I want to deploy my application. It lets me control, exactly how my application gets run without having to deal with the boring logistics of actually getting my app to run that way.

I declaratively specify the file system image (and thus the system libraries) that the app gets deployed with, I specify the environment variables, what persistent storage is mounted where, which ports are exposed and under what URL the app should be reachable. Hell, with the amazing cert-manager, I even get to declare that I want TLS and i just happens.

When operations inevitably begs me to specify resource requests, limits and health checks, I sigh, go back to my app declaration and add these ten additional lines.

It's a good life. I don't have to fill out forms for other departments. I don't have to size and order VMs ahead of time. I don't have to fill operation manuals with boring, repetitive minutiae, like where to find log files, and most importantly: my instructions will be followed to the letter. I won't be called to fix deployment mistakes that arise from someone copy&pasting the wrong settings from a manual into the production system.

Kubernetes as a Platform

I already mentioned cert-manager as an optional add-on to a Kubernetes cluster. The fact that it is possible to implement something like cert-manager is, in my opinion, what catapulted Kubernetes to where it is today. Kubernetes is extensible. While some concepts are built in, anyone can build their own logic on top of Kubernetes fundamentals. All you need is a program that

  1. Can talk to the Kubernetes API server

  2. Can determine the difference between the real world and a specification retrieved from said API server

  3. Can make changes to the real world to shrink that difference

Keep that program running in a loop and your Kubernetes cluster has gained a new ability. Add to this that Kubernetes is relatively modular, which allows service providers to integrate it into their ecosystems and you get a system that helps you deliver software faster, more reliably and less directly dependent on big cloud providers.

Kubernetes as an Operator

Even the operations side benefits from Kubernetes, at least a little bit. Application developers need to take more ownership over how their app is deployed. If an environment variable is incorrect, that's their problem, not an operations problem. At the same time, you don't need to hunt down log files or mechanisms to start/stop/scale an application, which ports it uses. It's all specified in a standardized way.

But it all comes at a price and operations is who will be paying that price. Kubernetes is incredibly complex. Kubernetes is fundamentally distributed, with all of the challenges that brings. Kubernetes is also fast moving. You need to be ready to upgrade clusters regularly. Kubernetes is not something that you set up once and forget about it. Kubernetes require a standing army to be operated. And, to an extent, that's even true if you delegate the operation to a cloud provider.

Kubernetes is a lot of things, but it's not serverless.

But why host the blog Kubernetes

Well, if all you have is a hammer, everything looks like a nail. I run a small k3s single-node for-fun Kubernetes cluster. I use it to deploy apps that you can't easily throw on a random hosting service. I chose Kubernetes because I use Kubernetes at work. And finally, deploying my applications via YAML-soup means that my deployment is reproducible.

I can throw this cluster away and deploy the applications to a new machine. I don't want a lovingly hand raised server that will inevitably grow into unique snowflake of a machine. So unique that when it inevitably throws a tantrum that my limited sysadmin skills cannot control, I will not lose the ability to run my apps. The terraform-hcloud-kube-hetzner terraform module means that setting up a fresh cluster is reasonably easy.

And that's why this static HTML file gets packed into an NGINX docker container and deployed onto a Hetzner VM running k3s.

Temptations of bare metal

As a small addendum, I want to say that I am mightily tempted to buy/rent a small-ish bare metal server instead of the (much pricier) virtual server that runs the cluster now. The server would no longer be disposable, but I would get significantly more bang for my buck.