All Options

2 min read

All five migration patterns running in a single Orkestra runtime. One binary, one Komposer, five CRD kinds.

ork init --pack from-controller-runtime
cd from-controller-runtime/08-all-options
make registry KOMPOSER=komposer-local.yaml && make build
ork simulate
ork run -f komposer-local.yaml

What is here

Each option lives in options/ as a self-contained sub-directory. They share one go.mod and compile into one binary.

OptionCRD KindPattern
declarativeDeclarativeAppPure YAML, zero Go
hybridHybridAppDeclarative + Go service hook
hooksHooksAppGo hook, no declared templates
constructorConstructorAppGo reconcile loop (direct migration)
ork-resourcesOrkAppGo reconcile loop (Orkestra resources)

All five produce the same result: a Deployment and a Service for each CR. The difference is how much Go is involved in producing them.


How the Komposer composes them

komposer-local.yaml imports each option’s katalog.yaml from options/. Each katalog declares its own unique group and kind, so all five coexist in the same runtime without conflict.

The Komposer adds two things at composition level:

Dependency ordering. hybridApp and hooksApp wait for declarativeApp to start before their reconcilers activate:

spec:
  crds:
    hybridApp:
      dependsOn:
        declarativeApp:
          condition: started
    hooksApp:
      dependsOn:
        declarativeApp:
          condition: started

Worker tuning. The Komposer overrides workers for specific CRDs where the katalog’s defaults are too conservative for the combined load.

That is all a Komposer adds here — the katalogs are self-contained. The same approach scales to production: import from OCI references instead of local files, tune at the Komposer level, keep the katalogs untouched.


Observing side-by-side

With all five running:

kubectl get deployments
kubectl get services
kubectl get declarativeapps,hybridapps,hooksapps,constructorapps,orkapps

Open the Control Center to watch each reconciler’s queue depth, worker utilisation, and health state independently:

ork control

declarativeApp activates first. hybridApp and hooksApp become active once it is started. ConstructorApp and OrkApp run independently from the start.


OCI distribution

Once each option validates locally, publish it so others can pull the Komposer without cloning the repo:

# Repeat for each option you want to distribute
ork push -f options/<name>/katalog.yaml

Update komposer.yaml with your registry org and tags, then:

ork pull -f komposer.yaml
make registry && make build
ork run

The OCI imports replace the local file imports — same runtime, distributed katalogs.


When to use this

Use this as a template for real multi-operator runtimes — one Komposer, multiple katalogs from different teams. The per-katalog isolation means each team owns their CRD entry; the Komposer owner controls load balancing, dependency order, and distribution.