Josh Siviour 8e11908dfb fix: make the EKS control plane's disk latency observable, and give it room to run (#1009)
* fix: report CPU and memory pressure in the EKS control-plane health diagnostic

An unhealthy control plane reported readyz, etcd reachability and etcd-disk
free space. When etcd goes unreachable with disk:ok and no OOM kill, that set
cannot distinguish a starved guest from a genuine etcd fault, so add the
loadavg and MemAvailable that separate them.

An empty /readyz body also rendered as readyz:[none], which reads as "no
subcheck failed" when it means the probe never answered. Report that as
unreachable instead.

* fix: sample the node's load, not just the runner host's

Every runner agent runs on one host while their nodes sit on several, so the
existing sample measured the runner's host and was labelled as the hypervisor.
It happens to coincide when the node is on that same host and misleads
otherwise. Relabel it and add a node-side sample, which is where the guests are
actually scheduled and so where a starved guest shows up.

* feat: build the mkosi EKS image in CI and give its control plane telemetry

The Ubuntu/systemd EKS image is what customers run, and nothing built it: the
composition existed in mkosi-build.sh's image_profiles table but had no caller,
so a change that broke it was found by hand or not at all. Cell-25 builds the
Alpine image, which leaves the published one with no gate. Add a Makefile target
beside the Alpine one and a job in the existing path-filtered image workflow.

The guest also collected nothing. k3s has served embedded-etcd metrics on
127.0.0.1:2381 since the daemon started setting etcd-expose-metrics, and no
collector ever read them, so an etcd stall was only ever visible as
"etcd:unreachable" in the state report — which cannot separate a slow disk from
a dead one. Ship otelcol-contrib pinned to the version the cluster hosts already
run, scraping etcd and guest host metrics.

The unit is gated on ConditionPathExists for its endpoint file rather than
started unconditionally: whether the control-plane guest can reach the sink from
the isolated CP VPC is unverified, and a collector with nowhere to export is a
restart loop, not telemetry.

* fix: report etcd fsync latency in the control-plane health diagnostic

disk:ok measures free space, which says nothing about how long a write takes.
etcd stalls on fsync latency long before it runs out of room, and this guest's
disk is an EBS volume served by viperblock, so a fsync is a network round trip.
An unhealthy control plane reporting healthy memory and disk was uninterpretable
without it.

Derived from the histogram's sum and count rather than a bucket percentile: two
greps against an interpolation this script has no business doing, and the
difference between a healthy single-digit reading and a stalled one is an order
of magnitude, not a tail. Rides the state report's existing gateway path, so it
needs no route the CP VPC does not already grant, and lands on both images
because the script is shared.

The scrape's failure is guarded explicitly. Under set -e a bare assignment from
a curl against a port nothing answers aborts the whole diagnosis, dropping the
reason field exactly when it is wanted.

* feat: publish etcd fsync on every control-plane report, not only failing ones

A figure that appears only once the apiserver is already unhealthy has no
baseline to be read against, which is the same gap a passing cell that uploads
no journal leaves: the number is unanchored when it finally arrives. Move the
scrape into its own helper, emit it on healthy reports too, and carry it as a
typed field rather than only inside the reason string.

Slowness is logged, never gated. observe() decides cluster health, and a working
cluster on a slow disk is working — returning an issue there would fail
customers' clusters on a latency threshold. The warning is latched on the
transition instead, because the control plane republishes on its own timer and a
line every interval is how a real signal gets tuned out.

An absent sample is not a fast one. Too few fsyncs to average, an etcd serving
no metrics and an older AMI all arrive as nil, and the field is omitted rather
than defaulted so none of them can be read as healthy. The minimum sample count
is the same lesson as the slow-shard floor: a mean over three fsyncs on a
just-started etcd is a number with no meaning.

* fix: log an etcd fsync baseline and name the two no-sample cases apart

A healthy cluster logs no health lines, so the fsync figure reached the
daemon on every report and was never surfaced — a passing cell left nothing
for a later slow reading to be compared against. Log the first known sample.

Split the "unknown" sentinel into nometrics (etcd served none) and warmup
(too few fsyncs to average): different faults, different fixes. The payload
guard now tests for a number rather than the sentinel word, so a future
sentinel cannot leak into the JSON as a bare value.

* feat: measure fdatasync latency in the diskperf gate

The two pinned profiles are buffered-bypassing throughput jobs at queue
depth 32. Neither measures the cost of making a write durable, which is what
a consensus datastore pays per raft entry and stalls on long before it runs
short of bandwidth. A 5ms barrier on bare metal went unseen as a result.

syncwrite-4k is the etcd-shaped profile: sequential 4k, queue depth 1,
fdatasync every write, buffered psync so the sync has a page cache to flush.
fio reports the sync distribution apart from the write stream, so the parser
reads it separately — gating on write clat would score the time to reach the
cache and call it durability.

No figures captured on this hardware yet, so the baseline entry is zero and
the job records without gating.

* fix: use the real otelcol checksums asset name in the EKS server image

The checksums file is named for the release repo and the distribution and
carries no version, unlike the tarball beside it. The guessed name 404'd and
took the image build with it.

* fix: extract otelcol as root in the EKS server image

The upstream tarball records its build uid (runner/docker, 1001:118), which
does not exist in the image. tar running as root tries to restore it and
fails outright rather than degrading, taking the build with it.

---------

Co-authored-by: Ben Duncan <5178243+benduncan@users.noreply.github.com>
2026-09-07 21:53:41 +10:00
2026-08-25 11:15:32 +10:00
2026-09-07 15:17:13 +10:00

Spinifex: the open, AWS-compatible cloud you run yourself. EC2, EBS, S3, VPC, and IAM on your infrastructure, at the edge, or on a Neocloud.

Go License mulgadc.com

What is Spinifex? · Platform · Deploy · AWS Compatibility · Live Demo · Components · Architecture · Installation · Docs


Spinifex: the open, AWS-compatible cloud you run yourself

Spinifex, built by Mulga, recreates the AWS services your software already uses (EC2, EBS, S3, VPC, IAM) on infrastructure you control. Move workloads off the hyperscalers, run AI at a fraction of the cost, or take the cloud to the edge, without rewriting a line. The exact build you ship to AWS, Spinifex serves on your own hardware: same APIs, same Terraform, same SDKs.

What is Spinifex?

Spinifex is an open-source infrastructure platform that recreates the AWS service surface (EC2, EBS, S3, VPC, IAM) on bare-metal, edge, and on-premises environments. Run cloud-native software without a hyperscaler.

Built for teams that need:

  • The AWS tooling you already use (AWS CLI, SDKs, Terraform), with nothing to rewrite
  • Full control of the stack: your hardware, your network, your data, your keys
  • A cloud that keeps running offline, through disconnection, with no external control plane
  • An open core (AGPL-3.0), auditable and yours to keep, with no lock-in

You change where your software runs, not what it is.

The Platform

The Spinifex stack: your apps and AWS tooling on top, the Spinifex AWS-compatible service layer, running on standard Linux on CPU and GPU hardware, deployable to Neocloud, on-premise, or the edge.

From commodity hardware up to unmodified AWS tooling, every layer is replaceable and yours to own.

Three Ways To Deploy

The same AWS-compatible platform runs in three shapes. Pick the one that matches your hardware.

Neocloud

Lift and shift onto a partner Neocloud without rewriting workloads. GPU capacity (H100 / H200 / B200), cheaper, available now. Change an endpoint, keep the software.

On-premise

Host Spinifex on your own hardware in your own data centre. You get a multi-node HA cluster integrated with your storage and networking, so the stack, the data, and the jurisdiction stay yours.

Edge

Cloud where the cloud can't reach. Air-gapped sites, vehicles, vessels, factories, and clinics. Compute next to the data, running through disconnection, on hardware you own. The same AWS APIs your software already uses.

AWS Compatibility

Spinifex speaks the AWS API surface. The AWS SDKs, AWS CLI, and Terraform all work unchanged, whether you deploy at the edge, on-premise, or on a partner Neocloud.

Service What it is Status
EC2 Compute Available
EBS Block Storage Available
S3 Object Storage Available
VPC Networking Available
IAM Identity & Auth Available
ALB / NLB Load Balancers Available
EKS Kubernetes Available
ECR Container Registry Available
ECS Container Service Available
RDS Databases Available
Bedrock AI Deployment Q3 2026

Roadmap items ship under the same AWS API surface. Code written for AWS today keeps working the moment they land. Track what's shipped in the release notes.

Live Demo

Create a live sandbox in under a minute. The fastest way to experience the stack. Try Spinifex against one of your own workloads on infrastructure we run for you.

  • Live in under a minute. No card, no install.
  • Yours for 72 hours to test and experiment.
  • Real AWS-compatible endpoint, access keys and console.
  • EC2, EBS, S3, VPC, IAM, EKS and RDS, ready to call.
  • Point your existing AWS CLI or Terraform straight at it.

Sign up at https://mulgadc.com/signup

Core Components

Spinifex (Compute and Platform Services – EC2, EKS, ECS, RDS)

Spinifex is a minimal VM orchestration layer built on top of QEMU, exposing an EC2 compatible API. It manages lifecycle operations like start, stop, and terminate through QEMU's QMP interface. Designed to be straightforward and scriptable, Spinifex lets you launch VMs with the AWS CLI, SDKs, or Terraform, without Kubernetes or a heavyweight orchestrator.

The managed services build on that same instance layer. An EKS node group, an ECS container instance, and an RDS database are Spinifex VMs on your own hardware, each driven through its own AWS API.

  • EC2 – VM lifecycle on bare metal, cloud-init and IMDS metadata, key pairs, tags, spot instances, capacity reservations, and GPU passthrough
  • EKS – Managed Kubernetes on k3s, with HA control planes, managed node groups, cluster add-ons, an OIDC provider, and IAM access entries
  • ECS – Task and service scheduling across container instances, with awsvpc ENIs, capacity providers, rolling deployments, and GPU-aware placement
  • ECR – Private container registry backed by Predastore, with content-addressed blobs deduplicated per account and lifecycle policies
  • RDS – Managed PostgreSQL and MariaDB, with parameter groups, automated backups, and DNS endpoints served by Northstar
  • ALB / NLB – Layer 7 load balancing on HAProxy and layer 4 on nginx stream, with health checks and ACM-issued listener certificates
  • VPC and IAM – OVN-backed networking and security groups, with roles, policies, and SigV4 auth applied across every service

Viperblock (Block Storage – EBS Alternative)

Viperblock is a high-performance, WAL-backed block storage service that replicates volumes across multiple nodes. It's built for reliability and speed, with support for snapshots, recovery, and direct connection to QEMU instances using NBD or virtio-blk.

  • Fast, durable virtual disks
  • Replication for resilience
  • Exposed over NBD or embedded in VMs
  • High performance WAL logs on local NVMe drives, reducing IO traffic to S3
  • In-memory read/write block cache

Predastore (Object Storage – S3-Compatible)

Predastore is a fully S3-compatible object storage system. It supports the AWS S3 API, including Signature V4 authentication, multipart uploads, and Terraform provisioning. Predastore chunks data and distributes it across nodes using Reed-Solomon erasure coding, so it survives node loss and suits large-scale or low-bandwidth sites.

  • S3-compatible API and auth
  • Multipart uploads, streaming reads/writes
  • Data redundancy with Reed-Solomon encoding

Northstar (Authoritative DNS)

Northstar is a lightweight authoritative DNS server that handles both internal service discovery and public-facing DNS for a Spinifex cluster. Zones are human-readable TOML files, served from the local filesystem or synced from Predastore, keeping DNS configuration in the same object storage as the rest of your infrastructure.

  • Authoritative DNS over UDP, TCP, and DNS-over-TLS
  • Service discovery for cluster components via SRV records
  • Zone files stored locally or in S3-compatible storage

Architecture at a Glance

Spinifex message-driven architecture: standard AWS clients call the AWS Gateway over HTTPS with SigV4, which publishes to a NATS bus answered by stateless ec2/ebs/s3/vpc/iam daemons over local backends.

Every AWS API call is authenticated at the gateway, published to a NATS subject, and answered by whichever daemon claims it. Daemons are stateless: scale horizontally by starting more. No etcd, no Kubernetes, no external control plane. Just systemd units, a NATS cluster, and your hardware. Deep dive: docs/DESIGN.md.

Self-hosted Installation

Installation requires an Ubuntu 26.04 or Debian 13 system. See the detailed documentation at docs.mulgadc.com for installing Spinifex.

Bare Metal ISO

The recommended installation is a bootable x86 installer for bare-metal hardware.

curl -fLO https://iso.mulgadc.com/spinifex.iso

Follow the USB install guide to write the ISO to USB and install on your hardware.

Single Node Install

Prerequisite: Spinifex requires a Linux bridge configured on the host for VM networking. See the single-node install guide for setup details.

curl -fsSL https://install.mulgadc.com | bash

sudo /usr/local/share/spinifex/setup-ovn.sh --management

sudo spx admin init --node node1 --nodes 1

sudo systemctl start spinifex.target

export AWS_PROFILE=spinifex

aws ec2 describe-instance-types

Development Setup

For a complete development environment see the Source Install documentation.

Spinifex UI

Spinifex ships with a built-in web console, an optional alternative to the AWS CLI, SDKs, and Terraform. If you know the AWS Management Console, the Spinifex UI fills the same role: a browser-based view of your instances, volumes, buckets, VPCs, and IAM resources, without leaving your own network.

Spinifex web console dashboard

Each node serves the console on port 3000 over TLS, and it comes up with spinifex.target:

  • Same API, different surface. The UI issues the same AWS SigV4 calls the CLI does, so RBAC, audit trails, and IAM policies apply the same way.
  • Single sign-on against your AWS credentials. Log in with the access keys from ~/.aws/credentials on the node where Spinifex is installed. There is no separate user database.
  • Self-hosted, works offline. The Spinifex binary embeds the UI and each node serves it directly, with no external CDN or analytics calls.

For the full walkthrough, covering first-time TLS certificate trust, login, and a feature tour, see Launching the Web UI in the cluster setup guide.

Development Philosophy

Built by Engineers, For Engineers

Spinifex is developed by experienced infrastructure engineers with deep AWS expertise, including former AWS team members who understand the intricacies of building production-grade cloud services. Our team brings decades of combined experience from AWS, enterprise infrastructure, and edge computing environments.

AI-Assisted Development

Spinifex is architected and implemented by experienced engineers, with Claude Code accelerating certain development tasks. The split keeps the quality and reliability standards that production infrastructure demands:

How We Use Claude Code:

  • Code Generation: Boilerplate AWS API structures and handlers
  • Documentation: Comprehensive development guides and API documentation
  • Testing: Test case generation and validation scenarios
  • Refactoring: Large-scale code restructuring and optimization

What Remains Human-Driven:

  • Architecture Decisions: Core system design and scalability choices
  • Security Implementation: Authentication, encryption, and threat modeling
  • Performance Optimization: Real-world performance tuning and benchmarking
  • Production Operations: Deployment strategies and operational procedures

Trademarks

"AWS", "Amazon Web Services", and all related service names (EC2, EBS, S3, VPC, IAM, and others) are trademarks of Amazon.com, Inc. or its affiliates. Mulga Defense Corporation and Spinifex are independent and not affiliated with, endorsed by, or sponsored by Amazon.com, Inc. or Amazon Web Services, Inc. References to AWS services describe interoperability and compatibility only.

License

Spinifex is open source under the GNU Affero General Public License v3.0, with a commercial license available. You're free to use, modify, and deploy it anywhere you need reliable infrastructure without depending on centralized cloud platforms.

S
Description
Spinifex – Open source AWS-compatible platform for secure edge deployments. Run EC2, VPC, S3, and EBS-like services on bare metal with full control. Built for environments where running in the cloud isn’t an option. Whether you’re deploying to edge sites, private data-centers, or operating in low-connectivity or highly contested environments.
Readme AGPL-3.0 121 MiB
Languages
Go 85.7%
TypeScript 9.2%
Shell 4.6%
Python 0.2%
HCL 0.1%