Migration Guide

3 min read

You have a working Kubernetes operator. The question is not whether controller-runtime works — it does. The question is what it costs.

Informers, workqueues, worker pools, leader election, status, finalizers, events, metrics, health endpoints, panic recovery — written from scratch for every CRD. The behaviour is always small. The machinery is always the same.

Orkestra removes the machinery. This guide shows the same WebApp operator expressed five ways so you can see what you are choosing between, and when to pick each.


The pack

ork init --pack from-controller-runtime

Each directory is a self-contained, runnable step. Work through them in order or jump to the option you need.


What you will learn

  • What controller-runtime costs in practice, measured against a real operator
  • How to go declarative — zero Go, no binary — when it fits
  • How the hybrid pattern (90% declarative, 10% Go hook) works and when to use it
  • How to drop all declarations and let a Go hook own every resource
  • How to lift an existing Reconcile method into Orkestra with a one-line signature change
  • How pkg/resources simplifies the Get / Create / Patch pattern
  • How ork migrate automates the constructor path for an existing operator file

The options

StepDirectoryGo requiredWhat you own
Baseline00-controller-runtime-baselineYes — fullEverything: informers, manager, scheme, main.go
Declarative01-declarativeNoNothing — pure YAML
Hybrid02-hybridYes — hook onlyThe 10% templates can’t express
Hooks only03-hooks-onlyYes — all resourcesAll child resource specs in Go
Constructor — lift04-constructor-migrationYes — full reconcilerReconcile logic; manager removed
Constructor — resources05-constructor-orkestra-resourcesYes — full reconcilerReconcile logic; resource ops simplified
ork migrate06-ork-migrateAutomated constructor path from an existing file

Contents

PageWhat it covers
The BaselineWhat controller-runtime costs — line by line
DeclarativeZero Go, zero binary — pure Katalog
Hybrid90/10: declare everything Orkestra handles, write Go for the rest
Hooks onlyWhen type-safe control over every resource matters more than YAML
Constructor — liftOne signature change, every resource op untouched
Constructor — resourcespkg/resources: Get / Create / Patch → one Update call
ork migrateAutomate the constructor path for an existing operator file

Before you begin

The pack uses a WebApp CRD. When a CR is applied, the operator creates a Deployment and a Service, then writes status. The behaviour is intentionally small so the migration story is about the machinery, not the domain.

You do not need to understand all five options. Pick the first one that fits your situation and stop there.

No cluster needed for simulate. Every option has a simulate.yaml that runs in-memory — no cluster, no binary. Simulate before you deploy.


Try it

ork init --pack from-controller-runtime
cd from-controller-runtime/01-declarative
ork simulate
ork run --dev

For typed operators (options 02–06), build first:

cd from-controller-runtime/02-hybrid
make registry && make build
./ork simulate
./ork run --dev

To try the automated path with your own operator:

cd from-controller-runtime/06-ork-migrate
# Follow the README
ork migrate ../00-controller-runtime-baseline/controller/webapp_controller.go -o ./output