Architecture
High-level
Section titled “High-level”Dev (writes YAML) ┐ │ ▼ ┌────────────────┐ ┌──────────────────────┐ │ Kubernetes API │──────▶│ genkit-operator │ └────────────────┘ │ (controller-manager) │ └──────────┬───────────┘ │ SSA ▼ ┌────────────────────────────────┐ │ Deployment + Service + │ │ ConfigMaps (manifest, prompts, │ │ tools, config) + Secret mount │ └──────────┬─────────────────────┘ │ ▼ ┌────────────────────────────────┐ │ Runner Pod │ │ reads /genkit/* → POST /<flow> │ └────────────────────────────────┘You hand the API server a set of CRs:
PluginConfig(which provider + credentialsSecret)Model(which model + default config +pluginConfigRef)Prompts andToolsFlow(single endpoint) orFlowSet(many endpoints in one Pod)
The controller resolves references, renders the
runtime contract into
ConfigMaps, applies a Deployment and Service, and writes status
back.
Reconciliation flow
Section titled “Reconciliation flow”For each Flow / FlowSet:
- Resolve refs. Look up the
Model, everyPromptandTool, and thePluginConfig(plus itsSecret). Any missing ref blocks the reconciliation with a clearConditionsentry. - Render. Build the on-disk layout the runner expects:
config.json— resolved model + plugin configprompts/<name>.prompt— verbatim Dotprompttools/<name>.json—ai.ToolDefinition+ dispatch targetmanifest.json— only forFlowSet
- SHA-256 the content. This hash is written to:
Flow.status.contentHash/FlowSet.status.contentHash- The Pod template annotation
genkit.dev/content-hash
- Server-Side Apply all child resources with field manager
genkit-operatorand owner references back to the parent CR. - Update status.
Phase,Conditions(Ready,Reconciling),ObservedGeneration.
Why content hashing matters
Section titled “Why content hashing matters”Kubernetes will not restart Pods when a mounted ConfigMap’s data
changes. The annotation flip is the trigger:
- You edit a
Prompt. - The
Promptcontroller reconciles; nothing in theFlow’sDeploymentchanges yet. - The
Flowcontroller (which watchesPrompt) re-renders. - The new content hash differs → annotation changes → Deployment sees a new Pod template → rolling update.
No other mechanism in the operator forces a restart.
Single-Flow vs FlowSet
Section titled “Single-Flow vs FlowSet”| Aspect | Flow | FlowSet |
|---|---|---|
| HTTP routes / Pod | 1 (POST /<flow-name>) | N (one per flow) |
| ConfigMaps | 3 (prompts, tools, config) | 1 manifest + 3 per flow |
| Credentials | envFrom on the Pod | One file mount per flow under …/credentials/ |
| Use case | One model, one purpose | Multiple flows sharing a Pod, possibly different providers |
Ownership and GC
Section titled “Ownership and GC”Every child resource has an OwnerReference pointing at the parent
CR. Deleting the Flow / FlowSet triggers Kubernetes garbage
collection of all rendered resources.
What the operator does NOT do
Section titled “What the operator does NOT do”- It does not embed an LLM proxy. Calls go directly from the runner Pod to the provider.
- It does not manage
Secretcontents. You bring them; the operator references them. - It does not enforce network policies, mTLS, or auth on the flow’s
HTTP endpoint. Wrap the
Servicein your usual ingress / service mesh.