Hi Lorenzo, Thanks for writing this up. I like the direction. An operator is the right next step after the Helm chart, and the proposed shape is broadly reasonable.
I checked the FIP against the current code and I think a few points are worth discussing/considering: 1. Drain / scale-in The FIP says Path B needs a new drain primitive, while Path A only blocks scale-in if the target TabletServer still has replicas. I think we already have most of the low-level pieces: - ServerTag.PERMANENT_OFFLINE / TEMPORARY_OFFLINE - AddServerTagRequest / RemoveServerTagRequest - RebalanceRequest - ListRebalanceProgressRequest - RebalanceStatus >From the rebalance code, offline-tagged servers are not just excluded from new placements. ReplicaDistributionGoal moves replicas out of them, including followers, and the target replica count is effectively zero. So scale-in could be: AddServerTag(PERMANENT_OFFLINE) -> Rebalance -> wait for COMPLETED -> scale down StatefulSet TEMPORARY_OFFLINE may also be usable before rolling restart. Path A also needs server work as written. The operator needs to know whether a TabletServer still has replicas, but that count is internal in CoordinatorContext.replicasOnTabletServer() and is not exposed through Admin.getServerNodes(). So I do not think the choice is “Path A without server work” vs “Path B with server work”. Both need a small server/API decision. The important caveats are: - rebalance can fail if the remaining TabletServers cannot absorb the replicas; - I do not see min-ISR being considered by the rebalance executor, so decommission close to min-ISR may create write-availability windows; - tag + rebalance is currently multi-step, so the operator needs crash recovery if it dies between the two calls; - the operator would depend on @PublicEvolving Admin/rebalance APIs. Given that, I think a small wrapper may be cleaner: DecommissionServer(serverId) -> rebalanceId The server would own tag + rebalance as one operation. The operator would start it and poll progress. 2. Helm naming / adoption The FIP says operator naming matches the Helm chart to support in-place adoption. The current chart uses fixed names such as tablet-server, tablet-server-hs, coordinator-server and coordinator-server-hs. That means two Helm installs in one namespace collide. If the operator keeps these names, v1alpha1 is effectively one FlussCluster per namespace. I think the FIP should either state that constraint, or move both chart and operator resources to cluster-prefixed names. Otherwise adoption and multi-cluster UX are pulling in different directions. Smaller points - I would not use both status.phase and conditions. Conditions are enough and avoid forcing mutually-overlapping states into one enum. - TCP probes are too weak for operator readiness. Readiness should mean the server is actually usable from Fluss’ point of view: registered with the Coordinator, ZK connected, etc. - PVC retention should use StatefulSet persistentVolumeClaimRetentionPolicy. I would not add custom PVC finalizer logic unless we really need it. - Lake tiering is not mentioned. It is fine to keep it out of v1alpha1, but the FIP should say that explicitly. - Your "Configuration Updates" section asserts the registry is sourced from Fluss, but your Open Questions section correctly flags this as unresolved - I'd align the body with Open Questions. For v1alpha1 a small client-side allowlist mirrored from DynamicServerConfig.ALLOWED_CONFIG_KEYS is probably fine I reckon Overall, I like the proposal. The main thing I would clarify is the operator/server boundary: what the operator can safely orchestrate today, what needs a small server API, and what should be left out of v1alpha1. -- Anton чт, 7 мая 2026 г. в 09:57, Lorenzo Affetti via dev <[email protected]>: > > Hi Michael, > > Thanks for the careful read. > > *Framework*: Java Operator SDK, not plain fabric8. JOSDK is built on > fabric8 anyway, so we keep the option to drop down whether needed. > > *Minimum Kubernetes version*: not currently fixed in the FIP. My proposal > is 1.29 as the floor. > > Reasoning for framework: > > For a Fluss operator that has to coordinate rolling upgrades, scale-in > safety gates, dynamic vs restart-inducing config diffs, and a migration > state machine, JOSDK's dependent-resource and workflow primitives are > well-aligned. Fabric8 alone would push us toward reimplementing them > ourselves. > > The clearest signal is Strimzi. Strimzi predates JOSDK and was built > directly on fabric8—but their newer components (Access operator, Schema > Registry operator) use JOSDK. The most mature ASF distributed-system > operator effectively says: if we were starting today, we'd use JOSDK. > > For the version floor, the constraints are JOSDK 5.x (Java 17+) and the > Kubernetes APIs the operator uses — all GA well before 1.27: CRD v1 (1.16), > admission webhook v1 (1.16), PDB v1 (1.21), Lease v1 (1.14). > The useful-but-optional StatefulSet persistentVolumeClaimRetentionPolicy > was alpha in 1.23, beta in 1.27, GA in 1.32. > Kubernetes upstream currently patches 1.31–1.33. > > *1.29 keeps us within a defensible distance of upstream while leaving room > for users on enterprise distributions a release or two behind. 1.27 is more > permissive; 1.30+ stricter.*Open to community input on what Fluss users > actually run. > > I'll fold both into the FIP once we converge. > > Thank you! > > On Wed, May 6, 2026 at 3:51 PM Michael Koepf <[email protected]> > wrote: > > > Hi Lorenzo, > > > > Thanks for the FIP. I believe a dedicated Fluss Kubernetes Operator will > > further simplify deployment and operations in large-scale production > > environments. > > > > I skimmed over the FIP. > > > > > We propose introducing a Fluss Kubernetes Operator, implemented in Java > > [...] > > > > 1. The first question that comes to my mind; are there already detailed > > plans regarding implementation? Do you plan to use the Java Operator SDK > > framework (https://javaoperatorsdk.io/)? Or just the plain fabric8 Java > > Kubernetes client (https://github.com/fabric8io/kubernetes-client)? > > > > 2. What will be the minimum supported Kubernetes version? > > > > Looking forward to this. > > > > Thanks. > > -- > > Best, > > Michael > > > > On 2026/05/05 09:05:45 Lorenzo Affetti via dev wrote: > > > Hello community! > > > > > > I would like to start a discussion about FIP-41: Fluss Kubernetes > > Operator. > > > Here is the motivation: > > > > > > Fluss 0.8 introduced a Helm chart > > > <https://github.com/apache/fluss/issues/779> that simplifies the initial > > > deployment of a Fluss cluster on Kubernetes by packaging manifests, > > > configuration, and dependencies into a versioned release. While this is a > > > good foundation, a Helm chart is fundamentally a one-shot templating > > tool. > > > It has no awareness of Fluss's runtime state and cannot react to > > > operational events such as pod failures, rolling upgrades, or scale-in > > > operations that risk data loss. > > > > > > Running Fluss in production on Kubernetes today requires users to > > manually > > > coordinate: > > > > > > - Safe rolling restarts of TabletServers, ensuring tablet leadership > > is > > > migrated before each pod terminates (Fluss 0.8 introduced the graceful > > > shutdown > > > < > > https://fluss.apache.org/docs/maintenance/operations/graceful-shutdown/> > > > primitive > > > that makes this possible, but does not orchestrate it across pods) > > > - Version upgrades that must sequence CoordinatorServer and > > TabletServer > > > updates correctly > > > - Scale-in operations where a TabletServer must be drained of tablets > > > before its pod is terminated > > > - Recovery from partial failures (e.g., PVC reattachment, pod identity > > > preservation across restarts) > > > - Leveraging Fluss 0.8's dynamic configuration updates > > > < > > https://fluss.apache.org/docs/maintenance/operations/updating-configs/> > > for > > > keys that do not require restart, instead of triggering a rolling > > restart > > > for every config change > > > > > > This gap between deployment and operations is best addressed by a > > *Kubernetes > > > Operator* — a controller that continuously reconciles the desired state > > of > > > a FlussCluster resource against the actual state of the cluster, and > > > executes Fluss-aware transitions safely. > > > > > > The Flink and Spark ecosystems have established this pattern successfully > > > with the Apache Flink Kubernetes Operator > > > <https://github.com/apache/flink-kubernetes-operator> and the Apache > > Spark > > > Kubernetes Operator <https://github.com/apache/spark-kubernetes-operator > > >. > > > Fluss should follow suit. > > > > > > -- > > > Lorenzo Affetti > > > Team Leader of Stream Storage > > > [email protected] > > > www.ververica.com > > > ------------------------------ > > > > > > <https://www.ververica.com/> > > > Ververica GmbH | Herzogspitalstrasse 24 | 80331 München | Germany > > > > > > Follow us: > > > <https://www.linkedin.com/company/ververica/posts/?feedView=all> > > > <https://www.youtube.com/@ververica> > > > < > > https://open.spotify.com/show/2XME9h8iBOyr6YupqM99ir?si=87b064644add42a1 > > >Available > > > on: <https://aws.amazon.com/marketplace/pp/prodview-luvmqd6leha4i> > > > < > > https://marketplace.microsoft.com/en-us/product/saas/ververica.vvc_managed?tab=Overview > > > > > > > > > Pflichtangaben/Mandatory Information > > > <https://www.ververica.com/mandatory-information> > > > > > > > > -- > Lorenzo Affetti > Senior Software Engineer @ Flink Team > Ververica <http://www.ververica.com>
