Console Login

Serverless Without the Handcuffs: Building Sovereign FaaS Architectures on KVM in Norway

Serverless Without the Handcuffs: Building Sovereign FaaS Architectures on KVM in Norway

Let's clear the air immediately: "Serverless" is the most expensive lie in the hosting industry. When Amazon or Google sells you serverless, they aren't selling you the absence of servers. They are selling you their servers, metered by the millisecond, with a hefty markup for the privilege of not managing the OS.

For a prototype, it's brilliant. For a high-throughput production workload in the Norwegian market? It's a financial and legal minefield.

I recently audited a fintech startup in Oslo. They were burning 40,000 NOK monthly on AWS Lambda invocations solely because of cold starts and inefficient memory allocation. Their latency to `us-east-1` was killing the user experience, and their legal team was having nightmares about Schrems II and the transfer of personal data outside the EEA.

The solution wasn't to abandon the Serverless architecture pattern. The pattern is sound. The solution was to repatriate the infrastructure. By moving to a self-hosted FaaS (Function as a Service) model on high-performance KVM instances, we cut costs by 65% and dropped latency from 120ms to 12ms.

The Architecture: Private FaaS on K3s

In 2022, you don't need a team of twenty Google engineers to run a FaaS platform. You need lightweight Kubernetes (K3s) and an agnostic function engine (OpenFaaS). This setup gives you the developer experience of Lambda with the raw I/O performance of a local VPS.

Why KVM? Containers share the kernel. If you are running multi-tenant workloads or strict compliance tasks, you want the hardware isolation of a Kernel-based Virtual Machine. At CoolVDS, we don't oversell CPU. When your function spikes, the cycles are there. Containers on shared hosting can't promise that.

Step 1: The Bare Metal Foundation

First, we need a cluster. We aren't using bloated `kubeadm` here. We use `k3s` because it strips out the legacy cloud provider bloat. On a CoolVDS instance running Ubuntu 20.04 LTS, initialization is instant.

Pro Tip: Always disable swap on your nodes before starting K8s, or the kubelet will fail.

sudo swapoff -a

Now, bootstrap the master node:

curl -sfL https://get.k3s.io | sh -
# Verify the node is ready (takes about 15 seconds on CoolVDS NVMe)
sudo kubectl get nodes

Step 2: Deploying the Function Engine

We use OpenFaaS. It’s container-centric, meaning you can write functions in Python, Go, or even Rust, packaged as Docker images. We'll use `arkade` (a Kubernetes marketplace installer) to get it running fast.

curl -sLS https://get.arkade.dev | sudo sh

Now, install OpenFaaS with basic auth enabled. Note that we are exposing the gateway strictly internally or via a secured ingress.

arkade install openfaas \
  --basic-auth=true \
  --set=faasIdler.dryRun=false

This command deploys the gateway, the queue worker (NATS), and Prometheus for metrics. If your underlying storage is slow (spinning rust), Prometheus will lag, causing auto-scaling to fail. This is why we insist on NVMe storage for the `/var/lib/rancher/k3s` directory.

Pattern 1: The Async Offload

The most common bottleneck I see is synchronous HTTP processing. A user uploads a document for KYC (Know Your Customer) verification. If you process that synchronously, the connection hangs. If the connection drops, the data is lost.

In a sovereign setup, we use the NATS streaming queue bundled with OpenFaaS. Here is the configuration for a Python function that processes data asynchronously.

The Stack YAML

version: 1.0
provider:
  name: openfaas
  gateway: http://127.0.0.1:8080
functions:
  doc-processor:
    lang: python3-http
    handler: ./doc-processor
    image: registry.coolvds-client.no/doc-processor:latest
    labels:
      com.openfaas.scale.min: 2
      com.openfaas.scale.max: 15
    annotations:
      topic: "kyc.documents.upload"
    environment:
      write_debug: true
      read_timeout: 10s
      write_timeout: 10s

By defining the `topic` annotation, OpenFaaS automatically wires this function to the NATS message bus. You publish to NATS, and the function executes when resources are available. No timeouts, no lost connections.

The Data Sovereignty Factor

This is where the