Kubernetes Operators in Java

Quarkus + JOSDK on OpenShift

Quarkus Club Quarkus Java Kubernetes
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Who this is for

  • Quarkus developers — REST, CDI, extensions, quarkus:dev
  • Platform engineers curious about OLM and OperatorHub
  • Integration folks who want Camel on OpenShift without reinventing the wheel

If you can write a @ApplicationScoped bean, you can write a Reconciler.

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Agenda

Block Content
Theory Operators, JOSDK / QOSDK, CRD, reconcile, OLM bundle
Live demo · part 1 Joke 101 — Quarkus scaffold + operator-sdk on OpenShift Local
Live demo · part 2 OpenShift Integration Operator — ephemeral Quick Try

Same OLM path → anyone can publish to the community catalog (OperatorHub)

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Why Kubernetes Operators?

Problem: Stateful apps on K8s need human ops — install, upgrade, backup, failovers.

Solution: Encode ops knowledge in software that runs inside the cluster.

  • Extend the API with Custom Resources (CRs)
  • A controller watches CRs and drives real resources (Deployments, Services, …)
  • Declarative: users set spec; operator converges cluster to desired state
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Operator anatomy

1 User / CI apply CR (spec)
2 API Server + CRD stores the custom resource
3 Informer / Watch JOSDK receives the event
4 Reconcile(request) your Java CDI bean runs
5 Create / Update / Patch native K8s resources
6 Update CR .status phase · conditions · message

Key idea: idempotent reconcile — safe to run again and again · loop repeats

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

The open-source stack

Quarkus Quarkus Java QOSDK / JOSDK K8s Fabric8 Client OpenShift OLM Operator SDK CLI OperatorHub Quay.io OpenShift OpenShift
  • Quarkus — fast startup, CDI, native image option
  • QOSDK — Quarkus extension wrapping Java Operator SDK
  • Fabric8 — Kubernetes client (generated from CRDs)
  • OLM — install / upgrade operators via catalog
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

You don't need Go

Go (controller-runtime) Java (QOSDK)
Ecosystem default Yes Growing
Team skills Go required Java / Quarkus
Dev experience controller-gen code.quarkus.io, quarkus:dev
OLM bundles operator-sdk bundle-generator extension

Quarkus Club: same toolchain you already use for microservices

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Scaffold: code.quarkus.io + Quarkus CLI

  1. Go to code.quarkus.io → search qosdk or operator
  2. Select Quarkus Operator SDK extension
  3. Optionally add OLM Bundle Generator
  4. Generate & download — or:
quarkus create app org.acme:my-operator \
  --extension='quarkus-operator-sdk,quarkus-operator-sdk-bundle-generator'
cd my-operator
./mvnw quarkus:dev
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Define your Custom Resource

Java types in src/main/java/.../v1/ — JOSDK generates CRD YAML on build:

@Group("platform.io")
@Version("v1alpha1")
@Kind("IntegrationFlow")
public class IntegrationFlow extends CustomResource<
    IntegrationFlowSpec, IntegrationFlowStatus> {}
  • Spec — desired state (user-facing)
  • Status — observed state (operator-written)

Reference: Joke sample

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

The Reconciler — a CDI bean

@ControllerConfiguration(
    csvMetadata = @CSVMetadata(
        displayName = "Integration Operator",
        bundleName = "openshift-integration-operator"))
public class IntegrationFlowReconciler
    implements Reconciler<IntegrationFlow> {

  @Override
  public UpdateControl<IntegrationFlow> reconcile(
      IntegrationFlow resource, Context<IntegrationFlow> context) {
    // compare spec → create/update Deployments, Services…
    // update status phase: Pending → Running / Error
    return UpdateControl.patchStatus(resource);
  }
}
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Reconciliation loop · best practices

  1. Level-triggered, not edge-only — reconcile on timer + watch
  2. Idempotent — same spec → same outcome every time
  3. Owner references — child resources garbage-collected with CR
  4. Status conditions — Ready, Degraded, Progressing
  5. Don't put secrets in spec — reference Secret names

Ephemeral mode in our demo uses ownerReferences so deleting the CR cleans up worker Deployments

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

OLM bundle generation

Add extension: quarkus-operator-sdk-bundle-generator

mvn clean package \
  -Dquarkus.container-image.build=true \
  -Dquarkus.container-image.registry=quay.io \
  -Dquarkus.container-image.group=maximilianopizarro \
  -Dquarkus.operator-sdk.bundle.channels=alpha

Output: target/bundle/<name>/manifests/ + bundle.Dockerfile

Docs: Deploy with OLM

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Deploy to OpenShift · test path

# Validate bundle
operator-sdk bundle validate target/bundle/openshift-integration-operator \
  --select-optional name=operatorhub

# Install from published bundle (community)
operator-sdk run bundle \
  quay.io/maximilianopizarro/openshift-integration-operator-bundle:v0.8.2 \
  --namespace openshift-integration \
  --install-mode AllNamespaces \
  --timeout 10m

Or: OperatorHub in OpenShift Console → Install

Same bundle path → PR to community-operators → catalog

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

From skeleton to product

After Joke 101 — a real operator already on OperatorHub

OpenShift Integration Operator — QOSDK · Apache 2.0 · community catalog

Today (part 2): ephemeral Quick Try only — GitOps is in the repo, not live today

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo environment · try it at home

Path: Podman Desktop + OpenShift Local · free Red Hat Developer account

  1. Joke 101 — internal registry + operator-sdk run bundletutorial Getting Started
  2. Next — Integration Operator from OperatorHub (ephemeral)

Prefer pure OSS? kind works for Joke / operator runtime — no OpenShift Console plugin UX.

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Live demo · part 1

Joke 101 on OpenShift Local

Scaffold · internal registry · operator-sdk run bundle · JokeRequest

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Joke 101 · operator-sdk

# From joke-operator/ — images → OpenShift Local registry
mvn clean package -Dquarkus.container-image.build=true \
  -Dquarkus.container-image.registry=default-route-openshift-image-registry.apps-crc.testing \
  -Dquarkus.container-image.group=openshift-operators

operator-sdk run bundle \
  default-route-openshift-image-registry.apps-crc.testing/openshift-operators/joke-operator-bundle:1.0.0-SNAPSHOT \
  --namespace openshift-operators --timeout 10m

kubectl apply -f k8s/jokerequest-sample.yaml

Full steps: tutorial repo · docs

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Live demo · part 2

OpenShift Integration Operator

Community catalog · Console plugin · Kaoto · Ephemeral Quick Try

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Install from OperatorHub

Operators → OperatorHub → "OpenShift Integration Operator" → Install

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Console plugin

Integration Platform in the OpenShift Console navigation

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Create ephemeral IntegrationFlow

apiVersion: platform.io/v1alpha1
kind: IntegrationFlow
metadata:
  name: ephemeral-camel-demo
  namespace: openshift-integration
spec:
  deploymentMode: EPHEMERAL
  integrationType: CAMEL_ROUTE
  ephemeral:
    ttlSeconds: 3600
  kaotoDesign: |
    - route:
        from:
          uri: "timer:hello?period=5000"
          steps:
            - log: { message: "Hello from Quarkus Club!" }

Apply: oc apply -f k8s/examples/09-ephemeral-demo.yaml

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Kaoto visual designer

Drag-and-drop Camel routes · embedded in the console plugin

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Ephemeral architecture (today's path)

OpenShift Console (Plugin + Kaoto)
        │
        ▼
 IntegrationFlow CR  (deploymentMode: EPHEMERAL)
        │
        ▼
 Operator Reconciler ──► EphemeralWorkerImageResolver
        │                      │
        ▼                      ▼
 Worker Deployment      precompiled Camel Quarkus image (Quay)
        │
        ▼
 Logs / OTel / SSE ──► Console (Flow Logs, status)

GitOps (Gitea · Tekton · Argo CD) — in repo, not live today

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Visual diagram & status

Reconciler wrote status · diagram reflects route structure

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Watch reconciliation

oc get integrationflow -n openshift-integration -w

oc get pods -n openshift-integration -l integrationflow=ephemeral-camel-demo

oc logs -f deploy/iflow-ephemeral-camel-demo-worker -n openshift-integration

Expect: phase Running · pod 2/2 or 1/1 Ready · logs every 5s

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Flow logs in console

Live pod log streaming · container selector · follow mode

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · Platform status

Health: Operator · Kaoto · OTel · (GitOps services when enabled)

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Demo · TTL & lifecycle

ttlSeconds · extend from console · optional promote-to-gitops (not live)

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Try it yourself

  1. Joke 101tutorial Getting Started · OpenShift Local · internal registry · operator-sdk
  2. Next — OperatorHub → OpenShift Integration Operator · ephemeral YAML
  3. Publish — PR to community-operators when ready

Also fine: ROSA / ARO / on-prem · or kind + operator-sdk (no Console plugin)

Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

What you learned

  1. Operators extend K8s with CRDs + reconcile loops
  2. QOSDK scaffolds from code.quarkus.io — Java, not Go
  3. Joke 101 — bundle + operator-sdk on OpenShift Local (internal registry)
  4. Community catalog — same path → PR to OperatorHub; anyone can contribute
  5. Next level: Integration Operator · ephemeral Quick Try
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

Thank you

Quarkus Club

Build operators in Java · Open source

Quarkus Club
Quarkus Club · Kubernetes Operators in Java · maximilianoPizarro

speakerNote: | EN Welcome to Quarkus Club. I'm Maximiliano Pizarro. Most Kubernetes operators are written in Go — but they don't have to be. We'll cover theory with Quarkus and the Java Operator SDK, then two live demos on OpenShift Local: first a Joke 101 operator via operator-sdk — the path anyone can reproduce from our tutorial repo — then the OpenShift Integration Operator from the community catalog. Same Java skills you already use for Quarkus apps — CDI, Maven, dev mode — applied to the control plane. And yes: anyone can contribute to that community catalog. — ES Bienvenidos a Quarkus Club. Soy Maximiliano Pizarro. La mayoría de los operadores de Kubernetes están escritos en Go, pero no tienen por qué estarlo. Cubriremos teoría con Quarkus y el Java Operator SDK, y después dos demos en vivo en OpenShift Local: primero un operador Joke 101 con operator-sdk — el path que cualquiera puede reproducir desde nuestro repo tutorial — y después el OpenShift Integration Operator del catálogo comunitario. Las mismas habilidades Java que ya usás con Quarkus — CDI, Maven, dev mode — aplicadas al plano de control. Y sí: cualquiera puede contribuir a ese catálogo comunitario.

speakerNote: | EN This session is for Quarkus Club — Java developers first. You don't need Go. If you've shipped a Quarkus service, you already understand dependency injection, configuration, and hot reload. An operator is the same pattern at a different layer. Today: Joke 101 with operator-sdk on OpenShift Local, then a richer community operator — Integration Operator — ephemeral Quick Try only, not the full GitOps stack. Platform engineers will care that the same OLM bundle path is how you publish to the community catalog. — ES Esta sesión es para Quarkus Club — desarrolladores Java primero. No necesitás Go. Si ya desplegaste un servicio Quarkus, entendés inyección de dependencias, configuración y hot reload. Un operador es el mismo patrón en otra capa. Hoy: Joke 101 con operator-sdk en OpenShift Local, y después un operador comunitario más rico — Integration Operator — solo Quick Try efímero, no el stack GitOps completo. Los platform engineers van a interesarse en que el mismo path de bundle OLM es cómo se publica al catálogo comunitario.

speakerNote: | EN Roadmap: theory first — operators, Quarkus Operator SDK, OLM bundles. Then two live demos on OpenShift Local. Part one: the Joke 101 path — scaffold or use the workshop joke-operator, build to the local registry, operator-sdk run bundle. Part two: the OpenShift Integration Operator from OperatorHub — ephemeral flow only. Key message throughout: anyone can contribute to the community catalog — you don't need to be a vendor. Questions anytime. — ES Roadmap: primero teoría — operadores, Quarkus Operator SDK, bundles OLM. Después dos demos en vivo en OpenShift Local. Parte uno: path Joke 101 — scaffold o el joke-operator del workshop, build al registry local, operator-sdk run bundle. Parte dos: OpenShift Integration Operator desde OperatorHub — solo flow efímero. Mensaje clave: cualquiera puede contribuir al catálogo comunitario — no hace falta ser vendor. Preguntas cuando quieran.

speakerNote: | EN Kubernetes gives you Deployments and Services, but complex software — databases, messaging, integration platforms — needs operational knowledge: how to install, upgrade, scale, recover. Operators package that knowledge. You define a Custom Resource — your domain object — and a controller loop that watches it and creates or updates native Kubernetes objects until reality matches spec. Users declare what they want; the operator makes it happen. That's the Operator pattern from CoreOS, now standard across the ecosystem. — ES Kubernetes te da Deployments y Services, pero software complejo — bases de datos, mensajería, plataformas de integración — necesita conocimiento operativo: instalar, actualizar, escalar, recuperar. Los operadores empaquetan ese conocimiento. Definís un Custom Resource — tu objeto de dominio — y un loop de control que lo observa y crea o actualiza objetos nativos de Kubernetes hasta que la realidad coincida con el spec. Los usuarios declaran lo que quieren; el operador lo hace realidad. Ese es el patrón Operator de CoreOS, hoy estándar en el ecosistema.

speakerNote: | EN Walk through the diagram. Someone applies a YAML with spec. The API server stores it because a CRD registered that type. The operator's informer receives an event. Your Reconciler method runs — this is where your Java code lives. You compare desired spec with what's in the cluster, create or patch Deployments, Secrets, whatever you need, then write back status so users see phase, messages, conditions. Reconcile must be idempotent: if it crashes mid-way, the next run fixes it. Same mental model as a Quarkus scheduled job or event handler — but the event source is the Kubernetes API. — ES Recorramos el diagrama. Alguien aplica un YAML con spec. El API server lo guarda porque un CRD registró ese tipo. El informer del operador recibe un evento. Corre tu método Reconciler — ahí vive tu código Java. Comparás el spec deseado con lo que hay en el cluster, creás o parcheás Deployments, Secrets, lo que necesites, y escribís status para que el usuario vea phase, mensajes, conditions. Reconcile debe ser idempotente: si crashea a mitad, la próxima ejecución lo arregla. Mismo modelo mental que un job programado o event handler en Quarkus — pero la fuente del evento es la API de Kubernetes.

speakerNote: | EN Here's the stack we'll use — all open source. Quarkus for the operator runtime: you get CDI, configuration, logging, container image builds. QOSDK — Quarkus Operator SDK — integrates Java Operator SDK so reconcilers are CDI beans. Fabric8 kubernetes-client talks to the API. OLM — Operator Lifecycle Manager — is how OpenShift installs operators from a catalog. operator-sdk CLI validates bundles and can run a bundle locally. Images land on Quay; OperatorHub is the community catalog. OpenShift adds Console integration — we'll see a dynamic plugin in the demo. — ES Este es el stack que usamos — todo open source. Quarkus para el runtime del operador: CDI, configuración, logging, builds de imagen. QOSDK — Quarkus Operator SDK — integra Java Operator SDK para que los reconcilers sean beans CDI. Fabric8 kubernetes-client habla con la API. OLM — Operator Lifecycle Manager — es cómo OpenShift instala operadores desde un catálogo. operator-sdk CLI valida bundles y puede correr un bundle localmente. Las imágenes van a Quay; OperatorHub es el catálogo comunitario. OpenShift suma integración en Console — vamos a ver un dynamic plugin en la demo.

speakerNote: | EN Go is the default in kubebuilder and controller-runtime — nothing wrong with that. But if your organization is Java-first, QOSDK lets you stay in one language. code.quarkus.io can scaffold an operator project like any other Quarkus app. quarkus:dev gives you fast iteration — though for operators you often test against a real cluster or kind. The bundle-generator extension produces OLM manifests on mvn package — parallel to what operator-sdk does for Go. For Quarkus Club, the message is: operators aren't a separate religion; they're Quarkus apps with a reconcile loop. — ES Go es el default en kubebuilder y controller-runtime — nada malo con eso. Pero si tu organización es Java-first, QOSDK te deja quedarte en un solo lenguaje. code.quarkus.io puede scaffoldar un proyecto operador como cualquier app Quarkus. quarkus:dev te da iteración rápida — aunque para operadores often probás contra un cluster real o kind. La extensión bundle-generator produce manifiestos OLM en mvn package — paralelo a lo que operator-sdk hace en Go. Para Quarkus Club, el mensaje es: los operadores no son una religión aparte; son apps Quarkus con un loop de reconcile.

speakerNote: | EN Step one in any operator journey: scaffold. On code.quarkus.io, search qosdk — you'll get the Quarkus Operator SDK extension which pulls JOSDK with aligned BOM versions. Add the bundle-generator if you plan to publish to OperatorHub — we'll cover that in a few slides. The CLI equivalent is quarkus create with both extensions. After generate, you have a Maven project with sample CRD stubs and a reconciler skeleton. mvn quarkus:dev starts the operator locally — useful for debugging REST endpoints if your operator exposes any; for reconciliation you typically deploy to a cluster with olm or run locally with kubeconfig. — ES Paso uno en cualquier journey de operador: scaffold. En code.quarkus.io, buscá qosdk — obtenés la extensión Quarkus Operator SDK que trae JOSDK con versiones alineadas del BOM. Agregá bundle-generator si planeás publicar en OperatorHub — lo vemos en unos slides. El equivalente CLI es quarkus create con ambas extensiones. Después del generate, tenés un proyecto Maven con stubs de CRD y un esqueleto de reconciler. mvn quarkus:dev arranca el operador localmente — útil para debuggear REST si tu operador expone alguno; para reconciliation typically desplegás en cluster con olm o corrés local con kubeconfig.

speakerNote: | EN Custom resources are plain Java classes extending CustomResource with Spec and Status types. Annotations Group, Version, Kind map to apiVersion and kind in YAML. During build, QOSDK generates the CRD manifest you apply to the cluster. Spec holds what the user wants — deployment mode, image, routes. Status holds phase, messages, conditions — only the operator should write status. The Joke sample in quarkus-operator-sdk repo is the hello-world: a Joke CR that fetches a joke and stores it in status. Our demo product uses IntegrationFlow — same pattern, production scale. — ES Los custom resources son clases Java que extienden CustomResource con tipos Spec y Status. Las anotaciones Group, Version, Kind mapean a apiVersion y kind en YAML. En el build, QOSDK genera el manifiesto CRD que aplicás al cluster. Spec tiene lo que el usuario quiere — deployment mode, imagen, routes. Status tiene phase, mensajes, conditions — solo el operador debe escribir status. El sample Joke en el repo quarkus-operator-sdk es el hello-world: un CR Joke que trae un chiste y lo guarda en status. Nuestro producto demo usa IntegrationFlow — mismo patrón, escala producción.

speakerNote: | EN The reconciler implements Reconciler of your CR type. It's a CDI bean — inject services, use @ApplicationScoped helpers, same as any Quarkus app. reconcile gets the current resource and context with retry info. You read spec, fetch existing Deployments, diff, apply changes via Fabric8 client, set status fields, return UpdateControl — patchStatus, patchResource, or noUpdate. CSVMetadata on ControllerConfiguration feeds the OLM ClusterServiceVersion — display name, icon, owned CRDs. That's how your operator shows up nicely in OperatorHub. Error handling: set status phase Error with a message; don't throw unless you want a retry storm. — ES El reconciler implementa Reconciler de tu tipo CR. Es un bean CDI — inyectás servicios, usás helpers @ApplicationScoped, igual que cualquier app Quarkus. reconcile recibe el resource actual y context con info de retry. Leés spec, buscás Deployments existentes, diffs, aplicás cambios vía Fabric8 client, seteás campos de status, devolvés UpdateControl — patchStatus, patchResource, o noUpdate. CSVMetadata en ControllerConfiguration alimenta el ClusterServiceVersion OLM — display name, ícono, CRDs owned. Así tu operador se ve bien en OperatorHub. Manejo de errores: seteá status phase Error con mensaje; no tires excepción unless querés retry storm.

speakerNote: | EN Production reconcilers follow these rules. Level-triggered means you reconcile whenever spec or related objects change, and periodically — not only on create. Idempotent: running reconcile twice shouldn't create duplicate Deployments — use server-side apply or patch with resourceVersion. Owner references link child Deployments to the IntegrationFlow CR so when the user deletes the CR, Kubernetes GC removes workers — critical for ephemeral Quick Try. Status conditions integrate with kubectl wait and UI. Our community operator's ephemeral path deploys a precompiled Camel worker with ownerReference — you'll see that in the demo when we delete or TTL-expire a flow. — ES Reconcilers de producción siguen estas reglas. Level-triggered significa reconciliar cuando cambia spec u objetos relacionados, y periódicamente — no solo en create. Idempotente: correr reconcile dos veces no debe crear Deployments duplicados — usá server-side apply o patch con resourceVersion. Owner references vinculan Deployments hijos al CR IntegrationFlow así cuando el usuario borra el CR, Kubernetes GC remueve workers — crítico para Quick Try efímero. Status conditions integran con kubectl wait y UI. El path efímero de nuestro operador comunitario despliega un worker Camel precompilado con ownerReference — lo van a ver en la demo al borrar o expirar TTL un flow.

speakerNote: | EN To install on OpenShift via OperatorHub or operator-sdk run bundle, you need an OLM bundle image. The bundle-generator extension runs during mvn package and emits CSV, CRD copies, RBAC, and annotations under target/bundle. In Joke 101 we push images to the OpenShift Local internal registry — no Quay required. For a published product you push to Quay and submit a PR to community-operators — that is how anyone gets onto OperatorHub. Our Integration Operator automates this in CI; the same path is open to every Quarkus Club member. — ES Para instalar en OpenShift vía OperatorHub u operator-sdk run bundle, necesitás una imagen bundle OLM. La extensión bundle-generator corre en mvn package y emite CSV, copias de CRD, RBAC y annotations bajo target/bundle. En Joke 101 pusheamos al registry interno de OpenShift Local — sin Quay. Para un producto publicado, Quay + PR a community-operators — así cualquiera llega a OperatorHub. Nuestro Integration Operator automatiza esto en CI; el mismo path está abierto a cualquier miembro de Quarkus Club.

speakerNote: | EN Two paths on cluster: operator-sdk run bundle for workshops and local testing — Joke 101 uses the CRC internal registry; published operators use Quay. Or OperatorHub in the console for anything already in the community catalog. After install, verify the operator pod and CRD. Important for the club: contributing is a PR to community-operators / OperatorHub — anyone can do it, not only vendors. Part one of the demo uses run bundle; part two uses OperatorHub for Integration Operator. — ES Dos caminos en cluster: operator-sdk run bundle para workshops y test local — Joke 101 usa el registry interno de CRC; operadores publicados usan Quay. O OperatorHub en consola para lo que ya está en el catálogo comunitario. Después del install, verificá pod y CRD. Importante para el club: contribuir es un PR a community-operators / OperatorHub — cualquiera puede, no solo vendors. Parte uno de la demo usa run bundle; parte dos usa OperatorHub para Integration Operator.

speakerNote: | EN Joke 101 proves the circuit: scaffold, CRD, reconciler, bundle, operator-sdk on Local. The OpenShift Integration Operator is what that path looks like when published — OperatorHub, Quay, console plugin, Camel. One CR drives integrations: paste kaotoDesign, EPHEMERAL mode, worker in minutes. GitOps mode exists in the repo; we won't demo it live. Bridge message: after your first operator, the community catalog is open — PR to community-operators. Part two starts next. — ES Joke 101 prueba el circuito: scaffold, CRD, reconciler, bundle, operator-sdk en Local. El OpenShift Integration Operator es cómo se ve ese path publicado — OperatorHub, Quay, console plugin, Camel. Un CR maneja integraciones: pegás kaotoDesign, modo EPHEMERAL, worker en minutos. El modo GitOps está en el repo; no lo demo en vivo. Mensaje puente: después del primer operador, el catálogo comunitario está abierto — PR a community-operators. Arranca la parte dos.

speakerNote: | EN Logistics before we go live. OpenShift Local via Podman Desktop — free Red Hat Developer account. Part one follows the tutorial: trust the CRC CA, build Joke images into the cluster internal registry, operator-sdk deploy — no Quay account needed for 101. Part two installs Integration Operator from OperatorHub. kind is fine for Joke if you skip the console plugin. Links in chat. Switch to the cluster for Joke 101. — ES Logística antes de ir en vivo. OpenShift Local vía Podman Desktop — cuenta free Red Hat Developer. Parte uno sigue el tutorial: confiar la CA de CRC, build de Joke al registry interno, operator-sdk — sin cuenta Quay para el 101. Parte dos instala Integration Operator desde OperatorHub. kind sirve para Joke si omitís el plugin de consola. Links en el chat. Cambio al cluster para Joke 101.

speakerNote: | EN Part one — Joke 101. OpenShift Local on this machine. We'll use the joke-operator from the Quarkus Club tutorial repo: build operator and bundle images to default-route-openshift-image-registry, then operator-sdk run bundle. Create a JokeRequest CR and watch reconciliation. This is the circuit every Java developer can finish in a workshop. After that, part two: a published community operator. — ES Parte uno — Joke 101. OpenShift Local en esta máquina. Usamos joke-operator del repo tutorial de Quarkus Club: build de imágenes operator y bundle al default-route-openshift-image-registry, después operator-sdk run bundle. Creamos un CR JokeRequest y vemos reconciliation. Es el circuito que cualquier Java developer puede completar en un workshop. Después, parte dos: un operador comunitario ya publicado.

speakerNote: | EN Walk the commands live. Trust CRC CA first if HTTPS to the registry fails. Maven builds push operator and bundle to the internal registry. operator-sdk run bundle installs via OLM. Apply JokeRequest — status should show a joke. Same pattern as Quay later: change registry and group, then you can PR to community-operators. When Joke works, we move to Integration Operator. — ES Recorrer los comandos en vivo. Confiar la CA de CRC si falla HTTPS al registry. Maven pushea operator y bundle al registry interno. operator-sdk run bundle instala vía OLM. Aplicar JokeRequest — el status debería mostrar un joke. Mismo patrón que Quay después: cambiás registry y group, y podés PR a community-operators. Cuando Joke funciona, pasamos a Integration Operator.

speakerNote: | EN Part two — Integration Operator. Already on the community catalog: OperatorHub install, console plugin, ephemeral IntegrationFlow. This is what a published Java operator looks like after the 101 circuit. Reminder: anyone in this room can contribute an operator the same way — PR to community-operators. No vendor required. Let's install and create a flow. — ES Parte dos — Integration Operator. Ya está en el catálogo comunitario: install desde OperatorHub, console plugin, IntegrationFlow efímero. Así se ve un operador Java publicado después del circuito 101. Recordatorio: cualquiera en la sala puede contribuir un operador igual — PR a community-operators. No hace falta ser vendor. Instalamos y creamos un flow.

speakerNote: | EN Part two — OpenShift Console. OperatorHub, search OpenShift Integration Operator. Community source, CRD IntegrationFlow. Install, wait for CSV Succeeded. Same path any Quarkus Club member can follow on OpenShift Local — and the same catalog your own operator can join via community-operators PR. — ES Parte dos — Consola OpenShift. OperatorHub, buscar OpenShift Integration Operator. Source community, CRD IntegrationFlow. Install, esperar CSV Succeeded. Mismo camino que cualquier miembro de Quarkus Club en OpenShift Local — y el mismo catálogo al que tu operador puede sumarse vía PR a community-operators.

speakerNote: | EN After install, the Helm chart or bundle deploys a ConsolePlugin CR. Refresh the console — you get Integration Platform in the nav. This is a PatternFly React dynamic plugin, same extension model Red Hat uses. List IntegrationFlows with search, filters, links to pods. This UX layer is optional for operators but shows how Java + frontend OSS integrates natively on OpenShift. Click into our demo flow once we create it. — ES Después del install, el chart Helm o bundle despliega un ConsolePlugin CR. Refrescá la consola — aparece Integration Platform en la nav. Es un dynamic plugin React PatternFly, mismo modelo de extensión que usa Red Hat. Listá IntegrationFlows con búsqueda, filtros, links a pods. Esta capa UX es opcional para operadores pero muestra cómo Java + frontend OSS se integra nativo en OpenShift. Entrá al flow demo una vez que lo creemos.

speakerNote: | EN Ephemeral mode: no Git repo, no pipeline. Set deploymentMode EPHEMERAL, paste kaotoDesign — Camel YAML from Kaoto or hand-written. Operator picks a precompiled worker image on Quay based on components — timer and log use the slim core image. TTL defaults configurable; extend from console later. Apply the example from the repo or use the console create form with Browse templates — two hundred plus public API flows. Watch oc get integrationflow -w — phase goes Pending, then Running when worker Deployment is ready. — ES Modo efímero: sin repo Git, sin pipeline. Set deploymentMode EPHEMERAL, pegá kaotoDesign — YAML Camel de Kaoto o a mano. El operador elige imagen worker precompilada en Quay según componentes — timer y log usan imagen core slim. TTL configurable por defecto; extend desde consola después. Aplicá el ejemplo del repo o usá el form create de consola con Browse templates — más de doscientos flows de APIs públicas. Mirá oc get integrationflow -w — phase va Pending, luego Running cuando el Deployment worker está listo.

speakerNote: | EN Open the flow in the console, Kaoto tab. Kaoto is open source low-code for Camel — palette of components, property editor, syncs to kaotoDesign in spec. You don't need IDE for workshop demos. Edit visually, save spec, reconciler rolls the worker if needed. For Quarkus Club: the worker runtime is Camel Quarkus — same stack as integration microservices, packaged as a Deployment the operator owns. — ES Abrí el flow en consola, tab Kaoto. Kaoto es low-code open source para Camel — paleta de componentes, editor de propiedades, sincroniza a kaotoDesign en spec. No necesitás IDE para demos workshop. Editás visual, guardás spec, reconciler actualiza worker si hace falta. Para Quarkus Club: el runtime worker es Camel Quarkus — mismo stack que microservicios de integración, empaquetado como Deployment que el operador owns.

speakerNote: | EN This is the path we're demoing. User interacts with console or kubectl. CR hits reconciler; ephemeral service resolves worker image tier — core, http, messaging, full — from URI schemes in the route. Deployment created with ownerReference. Logs stream in plugin; optional OTel colors nodes on diagram. GitOps path scaffolds Git repos and Tekton — mention only: promote-to-gitops API exists for when you're ready. Keeps the story honest for a one-hour slot. — ES Este es el path que demostramos. Usuario interactúa con consola o kubectl. CR llega al reconciler; servicio ephemeral resuelve tier de imagen worker — core, http, messaging, full — desde esquemas URI en la ruta. Deployment creado con ownerReference. Logs stream en plugin; OTel opcional colorea nodos en diagrama. Path GitOps scaffolda repos Git y Tekton — solo mencionar: existe API promote-to-gitops para cuando estés listo. Mantiene la historia honesta para un slot de una hora.

speakerNote: | EN The plugin renders SVG diagram from kaotoDesign — branches, splits, error handlers. Click nodes to jump to YAML. Status panel shows phase, deployment mode EPHEMERAL, resilience settings. This connects back to theory: reconciler updates status; UI reads it — same contract as any operator. For simpler demo route you'll see a linear timer → log path; saga screenshot shows what complex flows look like. — ES El plugin renderiza diagrama SVG desde kaotoDesign — branches, splits, error handlers. Click en nodos salta a YAML. Panel status muestra phase, deployment mode EPHEMERAL, settings de resiliencia. Conecta con la teoría: reconciler actualiza status; UI lo lee — mismo contrato que cualquier operador. Para ruta demo simple verás path lineal timer → log; screenshot saga muestra cómo se ven flows complejos.

speakerNote: | EN Terminal alongside console. Watch IntegrationFlow phase. Describe the CR — events show reconciler progress. Pods labeled by flow name. Logs prove Camel route executing — Hello from Quarkus Club every five seconds. If phase Error, describe CR status.message — common issues: missing RBAC, image pull, invalid kaotoDesign. This is your debug loop as operator author too — status messages you write in Java appear here. — ES Terminal junto a consola. Watch phase IntegrationFlow. Describe del CR — events muestran progreso del reconciler. Pods labeled por nombre de flow. Logs prueban ruta Camel ejecutando — Hello from Quarkus Club cada cinco segundos. Si phase Error, describe status.message del CR — issues comunes: RBAC faltante, image pull, kaotoDesign inválido. Este es tu loop de debug como autor del operador — mensajes de status que escribís en Java aparecen acá.

speakerNote: | EN Flow Logs tab — no oc needed for workshop attendees watching screen. Select worker container, tail lines, follow. Same logs as kubectl. For stream reliability I keep this tab open during demo. Points to operator REST API backing the plugin — Quarkus JAX-RS, another Quarkus advantage for operators that expose admin APIs. — ES Tab Flow Logs — no hace falta oc para quienes miran pantalla en workshop. Seleccioná container worker, tail lines, follow. Mismos logs que kubectl. Para confiabilidad del stream mantengo esta tab abierta en demo. Apunta al REST API del operador detrás del plugin — Quarkus JAX-RS, otra ventaja Quarkus para operadores que exponen APIs admin.

speakerNote: | EN Platform Status dashboard — operator pod health, Kaoto backend, telemetry stack. In ephemeral-only install GitOps rows may show absent or N/A — that's fine. Operator and plugin healthy is what we need. Real-time enough for demo; production teams wire OTel to their backends. Mention MCP/AI bridge exists in repo for LangChain flows — out of scope today. — ES Dashboard Platform Status — salud pod operador, backend Kaoto, stack telemetry. En install solo efímero filas GitOps pueden mostrar absent o N/A — está bien. Operador y plugin healthy es lo que necesitamos. Suficientemente real-time para demo; equipos producción conectan OTel a sus backends. Mencionar que existe bridge MCP/AI en repo para flows LangChain — fuera de scope hoy.

speakerNote: | EN Ephemeral flows auto-expire — TTL in spec. Extend from UI or POST to operator API. Pause, resume, stop — lifecycle on the same CR. Promote-to-gitops scaffolds repo and switches mode — I won't run it live; say it exists for evaluators who outgrow Quick Try. Deleting CR cleans workers via ownerReferences — show delete if time permits. — ES Flows efímeros expiran solos — TTL en spec. Extend desde UI o POST al API del operador. Pause, resume, stop — lifecycle en el mismo CR. Promote-to-gitops scaffolda repo y cambia modo — no lo corro en vivo; decir que existe para evaluadores que superan Quick Try. Borrar CR limpia workers vía ownerReferences — mostrar delete si da el tiempo.

speakerNote: | EN Three steps for the audience tonight: finish Joke 101 from the tutorial repo on OpenShift Local; try Integration Operator from OperatorHub; when your own operator is ready, open a PR to community-operators — anyone can contribute. kind works for Joke without Red Hat login. Star repos, open issues. — ES Tres pasos para la audiencia esta noche: completar Joke 101 del repo tutorial en OpenShift Local; probar Integration Operator desde OperatorHub; cuando tengan su operador, PR a community-operators — cualquiera puede contribuir. kind sirve para Joke sin login Red Hat. Star a los repos, abrí issues.

speakerNote: | EN Recap for Quarkus Club. Same Quarkus toolchain as microservices. Scaffold, CR, reconcile, bundle — Joke 101 on Local proved it without Quay. Same OLM path publishes to the community catalog — you don't need to be a vendor. Integration Operator showed a real OperatorHub product: console plugin, ephemeral Camel. Clone the tutorial repo tonight; PR to community-operators when you're ready. — ES Recap para Quarkus Club. Mismo toolchain Quarkus que microservicios. Scaffold, CR, reconcile, bundle — Joke 101 en Local lo probó sin Quay. El mismo path OLM publica al catálogo comunitario — no hace falta ser vendor. Integration Operator mostró un producto real en OperatorHub: console plugin, Camel efímero. Clonen el repo tutorial esta noche; PR a community-operators cuando estén listos.

speakerNote: | EN Start with Getting Started — Podman, OpenShift Local, Joke 101. Then Integration Operator on OperatorHub. If you want your own operator in the catalog, community-operators is the PR target — anyone can contribute. LinkedIn and GitHub are on the thank-you slide. — ES Empiecen por Getting Started — Podman, OpenShift Local, Joke 101. Después Integration Operator en OperatorHub. Si quieren su propio operador en el catálogo, community-operators es el destino del PR — cualquiera puede contribuir. LinkedIn y GitHub están en el slide de thank you.

speakerNote: | EN Thanks for joining Quarkus Club. Start with Joke 101 from the tutorial, then Integration Operator. If you want to collaborate — or publish your own operator to the community catalog — LinkedIn and GitHub are here. Drop a connection request or open an issue. Go build an operator this week. — ES Gracias por sumarte a Quarkus Club. Empiecen con Joke 101 del tutorial, después Integration Operator. Si quieren colaborar — o publicar su propio operador al catálogo comunitario — LinkedIn y GitHub están acá. Conecten o abran un issue. Construyan un operador esta semana.