Managed Kubernetes solved cluster installation and then quietly introduced two new costs: a monthly fee for the control plane and a node pool that has to be sized for the busiest hour of the week. This post follows a platform engineer at a twelve-service B2B SaaS we will call Meridian Ledger as they move from a hyperscaler's managed offering to the Kubernetes Cluster package on MassiveGRID PaaS, which is built on Virtuozzo Application Platform (formerly Jelastic). The interesting part is not that Kubernetes works, it is what the bill looks like when nodes are metered by the hour.

What the package installs, and what you do not have to

The Kubernetes Cluster package deploys an upstream, CNCF-conformant cluster with the pieces a team otherwise assembles by hand: Weave as the CNI plugin, CoreDNS, a Traefik ingress controller with TLS preconfigured (NGINX and HAProxy are options), an NFS volume provisioner backed by a shared storage container, the Kubernetes Dashboard, Helm, and a monitoring stack of metrics server, Prometheus and Grafana. Jaeger tracing is an optional tick box. K9s, kubectx, popeye and stern are on the control-plane node for anyone who prefers a terminal.

For Meridian that list replaced about two days of Terraform and Helm work per cluster, and the day of debugging that usually followed. The engineer installed the package with a multi-master option for a highly available control plane, picked the Frankfurt region, and had a cluster with a working ingress and a Grafana dashboard in the time it took to make coffee. The kubeconfig arrived by email.

Two layers of scaling instead of one

On the managed service, Meridian's node pool was six fixed-size instances chosen for Tuesday mornings, when every customer's finance team runs reconciliations. The cluster autoscaler could add instances, but each was a full VM that took minutes to join and was billed for the hour regardless of how much of it the pods used. On MassiveGRID PaaS the worker layer scales on two axes at once.

Vertical scaling happens inside each worker. A node is allocated cloudlets, each 128 MiB of RAM plus 400 MHz of CPU, up to a limit the engineer sets, and the platform adds or removes them as the pods on that worker consume more or less, with no restart. Meridian's workers run with a modest reserved allocation and a dynamic ceiling of 32 cloudlets (4 GiB of RAM). On Tuesday morning they grow; on Saturday they shrink. Kubernetes' own Vertical Pod Autoscaler can adjust pod requests inside that envelope.

Horizontal scaling adds workers. A trigger on the worker layer adds a node when average CPU across the layer exceeds 70% for five minutes and removes one when it falls below 30% for fifteen. New workers are placed on different physical hosts by the platform's anti-affinity rules and join the cluster automatically, and Kubernetes' Horizontal Pod Autoscaler spreads pods onto them. The two autoscalers, the platform's for nodes and Kubernetes' for pods, do what a cluster autoscaler does, but with node capacity that is elastic rather than fixed.

The bill, before and after

MassiveGRID publishes its cloudlet rate as $0.003372 per cloudlet-hour, which is $2.46 per cloudlet for a 730-hour month. Each node is charged per hour for the greater of its peak RAM and its average CPU, so a worker that is busy on CPU but light on memory does not pay for both. There is no charge for the control plane beyond the cloudlets its nodes consume, and internal traffic between nodes is free.

ComponentManaged Kubernetes (fixed)MassiveGRID PaaS (metered)
Control planeFlat monthly fee per clusterCloudlets consumed by master node(s), typically single digits each
Workers, quiet hours6 instances, full price3 workers at ~10 cloudlets each
Workers, Tuesday peak6 instances (or autoscaler adds a 7th for a full hour)5 workers at up to 32 cloudlets, for the hours it lasts
Ingress, monitoring, dashboardAdd-ons or self-managedIncluded in the package
Persistent volumesBlock storage per volumeNFS provisioner on a shared storage container, disk billed per GB

Meridian's quiet-hours footprint is about 45 cloudlets including the control plane, roughly $110 a month at the published rate before reserved-cloudlet and volume discounts. The Tuesday peak runs to about 180 cloudlets for four hours a week. Averaged across the month, the cluster costs a fraction of the previous fixed pool, and the difference is not a discount, it is the absence of capacity nobody was using between peaks.

Storage, ingress and the things that usually hurt

Persistent storage is where Kubernetes migrations get expensive, because every stateful workload needs a volume and cloud block storage bills per provisioned gigabyte per volume. The package's default StorageClass, jelastic-dynamic-volume, provisions NFS volumes automatically from a shared storage container in the same environment. For Meridian's Redis caches, its report-generation scratch space and its Grafana data, that is fast enough and it is billed as one pool of disk. For the PostgreSQL that backs the ledger service they chose the platform's own PostgreSQL cluster package in a separate environment, connected over the free internal network, because a replicated database with Pgpool-II failover is easier to operate outside the cluster than inside it.

Ingress arrived working. Traefik terminates TLS with the platform's built-in certificate for the environment domain, and the Let's Encrypt add-on issues certificates for the customer-facing domains on the public IP the engineer attached to the ingress node. The container firewall on every node denies inbound connections that no rule allows, and the engineer added one rule permitting the office VPN range to reach the Kubernetes API.

Operations after the move

Upgrades are the part of Kubernetes that managed services genuinely make easy, and the package keeps that: newer Kubernetes versions appear as in-place upgrades from the dashboard, following upstream releases. Velero is available for cluster backups. The platform's per-node statistics and load alerts sit alongside Prometheus, so the engineer gets an email when a worker approaches its cloudlet ceiling, which is the signal to raise the limit before the HPA runs out of room.

The team's one adjustment was mental. On the managed service they thought in instance types. On MassiveGRID PaaS they think in ceilings: how many cloudlets may a worker reach, how many workers may the layer reach. Those two numbers are the budget, and the platform stays inside them by construction. Meridian also keeps a stopped clone of the cluster's environment as a rehearsal target for upgrades, which costs disk only until it is started.

Frequently Asked Questions

Is this a certified, upstream Kubernetes?

Yes. The package installs upstream CNCF-conformant Kubernetes with standard components such as CoreDNS, Traefik or NGINX ingress and Helm. kubectl, Helm charts and operators work unchanged, and newer versions are offered as in-place upgrades.

How does node auto-scaling interact with the Horizontal Pod Autoscaler?

They operate on different objects. The platform's triggers add or remove worker nodes based on the layer's average CPU, memory, network or disk load, evaluated every minute. Kubernetes' HPA adds or removes pods based on their metrics. Together they behave like a cluster autoscaler, with the addition that each node also grows and shrinks vertically in cloudlets without restarting.

What does a stopped cluster cost?

Only its disk. Environments on MassiveGRID PaaS can be stopped from the dashboard, the CLI or on a schedule, and stopped nodes are not charged for CPU or RAM. A development cluster stopped outside working hours costs a small fraction of one that runs continuously.

A Kubernetes cluster billed by the hour

The Kubernetes Cluster package on MassiveGRID PaaS installs control plane, auto-scaling workers, ingress, dashboard, Prometheus and Grafana in one click. No control-plane fee, cloudlet billing, 100% uptime SLA, free 14-day trial.

Kubernetes on PaaS

Further Reading