1 - Migrating from v1 to v2

Migrating from v1 to v2

Migrating from v1 to v2

Version 2 of the framework introduces improvements, features and breaking changes for the APIs both internal and user facing ones. The migration should be however trivial in most of the cases. For detailed overview of all major issues until the release of v2.0.0 see milestone on GitHub . For a summary and reasoning behind some naming changes see this issue

User Facing API Changes

The following items are renamed and slightly changed:

  • ResourceController interface is renamed to Reconciler . In addition, methods:
    • createOrUpdateResource renamed to reconcile
    • deleteResource renamed to cleanup
  • Events are removed from the Context of Reconciler methods . The rationale behind this, is that there is a consensus now on the pattern that the events should not be used to implement a reconciliation logic.
  • The init method is extracted from ResourceController / Reconciler to a separate interface called EventSourceInitializer that Reconciler should implement in order to register event sources. The method has been renamed to prepareEventSources and should now return a list of EventSource implementations that the Controller will automatically register. See also sample for usage.
  • EventSourceManager is now an internal class that users shouldn’t need to interact with.
  • @Controller annotation renamed to @ControllerConfiguration
  • The metrics use reconcile, cleanup and resource labels instead of createOrUpdate, delete and cr, respectively to match the new logic.

Event Sources

  • Addressing resources within event sources (and in the framework internally) is now changed from .metadata.uid to a pair of .metadata.name and optional .metadata.namespace of resource. Represented by ResourceID.

The Event API is simplified. Now if an event source produces an event it needs to just produce an instance of this class.

  • EventSource is refactored, but the changes are trivial.

2 - Migrating from v2 to v3

Migrating from v2 to v3

Migrating from v2 to v3

Version 3 introduces some breaking changes to APIs, however the migration to these changes should be trivial.


  • Reconciler can throw checked exception (not just runtime exception), and that also can be handled by ErrorStatusHandler.
  • cleanup method is extracted from the Reconciler interface to a separate Cleaner interface. Finalizers only makes sense that the Cleanup is implemented, from now finalizer is only added if the Reconciler implements this interface (or has managed dependent resources implementing Deleter interface, see dependent resource docs).
  • Context object of Reconciler now takes the Primary resource as parametrized type: Context<MyCustomResource>.
  • ErrorStatusHandler result changed, it functionally has been extended to now prevent Exception to be retried and handles checked exceptions as mentioned above.

Event Sources

  • Event Sources are now registered with a name. But utility method is available to make it easy to migrate to a default name.
  • InformerEventSource constructor changed to reflect additional functionality in a non backwards compatible way. All the configuration options from the constructor where moved to InformerConfiguration . See sample usage in WebPageReconciler .
  • PrimaryResourcesRetriever was renamed to SecondaryToPrimaryMapper
  • AssociatedSecondaryResourceIdentifier was renamed to PrimaryToSecondaryMapper
  • getAssociatedResource is now renamed to get getSecondaryResource in multiple places

3 - Migrating from v3 to v3.1

Migrating from v3 to v3.1

Migrating from v3 to v3.1

ReconciliationMaxInterval Annotation has been renamed to MaxReconciliationInterval

Associated methods on both the ControllerConfiguration class and annotation have also been renamed accordingly.

Workflows Impact on Managed Dependent Resources Behavior

Version 3.1 comes with a workflow engine that replaces the previous behavior of managed dependent resources. See Workflows documentation for further details. The primary impact after upgrade is a change of the order in which managed dependent resources are reconciled. They are now reconciled in parallel with optional ordering defined using the ‘depends_on’ relation to define order between resources if needed. In v3, managed dependent resources were implicitly reconciled in the order they were defined in.

Garbage Collected Kubernetes Dependent Resources

In version 3 all Kubernetes Dependent Resource implementing Deleter interface were meant to be also using owner references (thus garbage collected by Kubernetes). In 3.1 there is a dedicated GarbageCollected interface to distinguish between Kubernetes resources meant to be garbage collected or explicitly deleted. Please refer also to the GarbageCollected javadoc for more details on how this impacts how owner references are managed.

The supporting classes were also updated. Instead of CRUKubernetesDependentResource there are two:

Use the one according to your use case. We anticipate that most people would want to use CRUDKubernetesDependentResource whenever they have to work with Kubernetes dependent resources.

4 - Migrating from v4.2 to v4.3

Migrating from v4.2 to v4.3

Migrating from v4.2 to v4.3

Condition API Change

In Workflows the target of the condition was the managed resource itself, not the target dependent resource. This changed, now the API contains the dependent resource.

New API:

public interface Condition<R, P extends HasMetadata> {

    boolean isMet(DependentResource<R, P> dependentResource, P primary, Context<P> context);


Former API:

public interface Condition<R, P extends HasMetadata> {

    boolean isMet(P primary, R secondary, Context<P> context);


Migration is trivial. Since the secondary resource can be accessed from the dependent resource. So to access the secondary resource just use dependentResource.getSecondaryResource(primary,context).

HTTP client choice

It is now possible to change the HTTP client used by the Fabric8 client to communicate with the Kubernetes API server. By default, the SDK uses the historical default HTTP client which relies on Okhttp and there shouldn’t be anything needed to keep using this implementation. The tomcat-operator sample has been migrated to use the Vert.X based implementation. You can see how to change the client by looking at that sample POM file:

  • You need to exclude the default implementation (in this case okhttp) from the operator-framework dependency
  • You need to add the appropriate implementation dependency, kubernetes-httpclient-vertx in this case, HTTP client implementations provided as part of the Fabric8 client all following the kubernetes-httpclient-<implementation name> pattern for their artifact identifier.

5 - Migrating from v4.3 to v4.4

Migrating from v4.3 to v4.4

Migrating from v4.3 to v4.4

API changes


We have simplified how to deal with the Kubernetes client. Previous versions provided direct access to underlying aspects of the client’s configuration or serialization mechanism. However, the link between these aspects wasn’t as explicit as it should have been. Moreover, the Fabric8 client framework has also revised their serialization architecture in the 6.7 version (see this fabric8 pull request for a discussion of that change), moving from statically configured serialization to a per-client configuration (though it’s still possible to share serialization mechanism between client instances). As a consequence, we made the following changes to the ConfigurationService API:

  • Replaced getClientConfiguration and getObjectMapper methods by a new getKubernetesClient method: instead of providing the configuration and mapper, you now provide a client instance configured according to your needs and the SDK will extract the needed information from it

If you had previously configured a custom configuration or ObjectMapper, it is now recommended that you do so when creating your client instance, as follows, usually using ConfigurationServiceOverrider.withKubernetesClient:

class Example {

  public static void main(String[] args) {
    Config config; // your configuration
    ObjectMapper mapper; // your mapper
    final var operator = new Operator(overrider -> overrider.withKubernetesClient(
            new KubernetesClientBuilder()
                    .withKubernetesSerialization(new KubernetesSerialization(mapper, true))

Consequently, it is now recommended to get the client instance from the ConfigurationService.


It is now recommended to configure your Operator instance by using a ConfigurationServiceOverrider when creating it. This allows you to change the default configuration values as needed. In particular, instead of passing a Kubernetes client instance explicitly to the Operator constructor, it is now recommended to provide that value using ConfigurationServiceOverrider.withKubernetesClient as shown above.

Using Server-Side Apply in Dependent Resources

From this version by default Dependent Resources use Server Side Apply (SSA) to create and update Kubernetes resources. A new default matching algorithm is provided for KubernetesDependentResource that is based on managedFields of SSA. For details see SSABasedGenericKubernetesResourceMatcher

Since those features are hard to completely test, we provided feature flags to revert to the legacy behavior if needed, see in ConfigurationService

Note that it is possible to override the related methods/behavior on class level when extending the KubernetesDependentResource.

The SSA based create/update can be combined with the legacy matcher, simply override the match method and use the GenericKubernetesResourceMatcher directly. See related sample.

Migration from plain Update/Create to SSA Based Patch

Migration to SSA might not be trivial based on the uses cases and the type of managed resources. In general this is not a solved problem is Kubernetes. The Java Operator SDK Team tries to follow the related issues, but in terms of implementation this is not something that the framework explicitly supports. Thus, no code is added that tries to mitigate related issues. Users should thoroughly test the migration, and even consider not to migrate in some cases (see feature flags above).

See some related issues in kubernetes or here. Please create related issue in JOSDK if any.

6 - Migrating from v4.4 to v4.5

Migrating from v4.4 to v4.5

Migrating from v4.4 to v4.5

Version 4.5 introduces improvements related to event handling for Dependent Resources, more precisely the caching and event handling features. As a result the Kubernetes resources managed using KubernetesDependentResource or its subclasses, will add an annotation recording the resource’s version whenever JOSDK updates or creates such resources. This can be turned off using a feature flag if causes some issues in your use case.

Using this feature, JOSDK now tracks versions of cached resources. It also uses, by default, that information to prevent unneeded reconciliations that could occur when, depending on the timing of operations, an outdated resource would happen to be in the cache. This relies on the fact that versions (as recorded by the metadata.resourceVersion field) are currently implemented as monotonically increasing integers (though they should be considered as opaque and their interpretation discouraged). Note that, while this helps preventing unneeded reconciliations, things would eventually reach consistency even in the absence of this feature. Also, if this interpreting of the resource versions causes issues, you can turn the feature off using the following feature flag.