Skip to content

Instantly share code, notes, and snippets.

@bentito
Last active September 26, 2023 14:28
Show Gist options
  • Save bentito/85942765284574ec966bfbf172490c6f to your computer and use it in GitHub Desktop.
Save bentito/85942765284574ec966bfbf172490c6f to your computer and use it in GitHub Desktop.
Creating Java-Based Kubernetes Operators: A Comparative Report with Code Examples

Comprehensive Analysis of Java-Based Kubernetes Operator Frameworks

Table of Contents

  1. Introduction
  2. Java Operator SDK
    1. Overview
    2. Detailed Analysis
    3. Top Contributors
  3. Quarkus Operator SDK
    1. Overview
    2. Detailed Analysis
    3. Top Contributors
  4. Fabric8 Kubernetes Client
    1. Overview
    2. Detailed Analysis
    3. Top Contributors
  5. Spring Cloud Kubernetes
    1. Overview
    2. Detailed Analysis
    3. Top Contributors
  6. Operator Framework Java Operator Plugins
    1. Overview
    2. Detailed Analysis
    3. Top Contributors
  7. Recommendations for Operator Framework Java Operator Plugin
  8. Java Library Dependency Graph
  9. Conclusion

Introduction

This report provides an analysis of various Java-based frameworks available for developing Kubernetes Operators, focusing on their features, use cases, and contributions. The aim is to offer insights and guidance to developers and decision-makers looking to adopt Java-based frameworks for their Kubernetes Operator development needs. Included are specific recommendations for the enhancement of the Operator Framework Java Operator Plugin to fill existing gaps in the ecosystem and how it might be changed to make sense in an evolved landspace of Java Operators.

A key finding of this report is that all the solutions for Java Operators depend on the Fabric8 framework, this includes solutions for Spring. And, Red Hat employees are main contributors on all Java Operator solutions. This descends from Red Hat's aquistions in this area over the past several years. Being so central to the development of all these projects represents a major opportunity for Red Hat to advance Java on Kubernetes and OpenShift. All the tools reviewed here advance Java as a best-in-class tool for creating controllers and operators. Fabric8 and Quarkus are crucial technologies that allow Java-based development teams to undertake new cloud development with Java and not worry that they should really be doing it all in Go. Since many large development teams in many organizations have many Java developers, this represents a major de-frictioning for all things cloud at these orgs. The Operator Pattern continues to attract development effort and resources because it represents an excellent methodology for managing providing solutions in the cloud. All the tools reviewed here enable development of powerful operators with sophisticated support and deployment strategies, easily, in Java.

One major reason this report was created was to help determine what can be improved or maintained in the Operator Framework Java Operator Plugins to justify perhaps pushing it from a technical preview to a generally available release. Operator Framework Java Plugin pulls together two things: an effective method of creating a new, small and efficient operator in Java by its dependence on the Quarkus Operator SDK, and building that operator to eas1ily fit in the OpenShift catalog and lifecycle management ecosystem. That need remains and becomes an important factor in a practical push to enable large Java development organizations to tackle operator development at scale.


Java Operator SDK

Overview

Java Operator SDK is a framework designed to facilitate the development of Kubernetes Operators using Java. It provides a simpler path for developers familiar with Java to create Operators, handling much of the Kubernetes API complexities. It’s particularly suitable for projects requiring robust and feature-rich frameworks for developing operators in Java.

Detailed Analysis

The Java Operator SDK (JOSDK) is focused on providing libraries that facilitate the development of Kubernetes Operators. The SDK incorporates a comprehensive set of features such as Custom Resource Definitions (CRD) and Controller implementations, making it a robust choice for developers. It uses annotations to define the operator’s custom resources and controller behaviors, streamlining the development process and reducing the learning curve for new users. The SDK’s focus on providing a clear and concise API makes it a suitable choice for projects that require a straightforward approach to operator development.

It's important to note that JOSDK sits on top of the Fabric8 library and is itself the basis for Quarkus Operator SDK.

JOSDK can be integrated with Quarkus or Spring.

Initial Configuration:

<!-- Sample from Java Operator SDK -->
<dependency>
    <groupId>io.javaoperatorsdk</groupId>
    <artifactId>operator-framework</artifactId>
    <version>${java.operator.sdk.version}</version>
</dependency>

Coding Examples:

public class SampleController extends ResourceController<SampleResource> {
    @Override
    public boolean deleteResource(SampleResource resource, Context<SampleResource> context) {
        // Handle deletion here
        return true;
    }

    @Override
    public UpdateControl<SampleResource> createOrUpdateResource(
      SampleResource resource, Context<SampleResource> context) {
        // Handle creation or update here
        return UpdateControl.updateResource(resource);
    }
}

Explanation

The Java Operator SDK allows developers to write operators for Kubernetes in Java. The SDK offers a higher level abstraction for the K8s resource management by providing a ResourceController interface which the developers can implement. This example demonstrates a simple operator that handles the creation, update, and deletion of SampleResource. The deleteResource method is invoked when the resource is deleted, and the createOrUpdateResource method is called when the resource is created or updated.

Top Human Contributors to JOSDK

  1. csviri: 968 contributions (Organizations: None) 🔴 Red Hat 🔴
  2. metacosm: 537 contributions (Organizations: apache, gatein, snowdrop, quarkiverse) 🔴 Red Hat 🔴
  3. adam-sandor: 178 contributions (Organizations: clusteringsolutionsshowdown, java-operator-sdk)

Analysis of Quarkus Operator SDK

Overview

Quarkus Operator SDK extends the capabilities of the Java Operator SDK by leveraging Quarkus, known for its native compile and compile-time boot capabilities. This SDK is ideal for projects looking to combine the power of Quarkus with the comprehensive features of the Java Operator SDK, benefiting from optimized memory footprint and start-up speed provided by Quarkus.

Detailed Analysis

The Quarkus Operator SDK, as an extension of the Java Operator SDK, inherits its features and capabilities but adds the benefits of Quarkus’ compile-time boot and extension ecosystem. This synergy allows developers to create operators that are not only feature-rich but also optimized in terms of memory footprint and start-up speed. The integration with Quarkus’ ecosystem makes it a versatile choice, especially for projects that prioritize performance and resource efficiency.

Initial Configuration

The Quarkus Operator SDK provides a streamlined approach to configuring the pom.xml file. The SDK leverages Quarkus extensions to simplify the configuration and optimize the operator's runtime characteristics. Developers typically need to include the Quarkus Operator SDK extension along with the necessary dependencies to ensure proper functionality. Here’s a simplistic representation of how a pom.xml might be configured with the Quarkus Operator SDK:

<dependencies>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-operator-sdk</artifactId>
        <version>${quarkus.version}</version>
    </dependency>
    <!-- Other dependencies -->
</dependencies>

Coding Examples

Quarkus Operator SDK allows developers to define Kubernetes operators concisely using Java. The operators are reactive and imperative, employing the standard Kubernetes API. Below is an elementary example demonstrating how developers might structure their Java class to define a custom resource:

@Controller
public class ExampleController {

    @Inject
    Client client;

    void onAdd(@Observes AddedEvent<Example> event) {
        // Handle when a new custom resource is added
    }

    void onUpdate(@Observes UpdatedEvent<Example> event) {
        // Handle when a custom resource is updated
    }

    void onDelete(@Observes DeletedEvent<Example> event) {
        // Handle when a custom resource is deleted
    }
}

Explanation:

In the above example, @Controller is a CDI stereotype that designates the class as a controller, allowing it to manage custom resources. The @Observes annotation marks the method to be notified when a specified event occurs. The AddedEvent, UpdatedEvent, and DeletedEvent represent different types of events that a controller can handle.

The Quarkus Operator SDK provides a robust set of features, including the ability to create, update, delete, and watch custom resources, enabling developers to manage Kubernetes resources effectively. Its integration with Quarkus brings the benefits of Quarkus’s container-first philosophy, developer joy, and the extensive Quarkus ecosystem, making it a versatile choice for developing Kubernetes operators.

Top Human Contributors

  1. [metacosm](https://github.com/gsmet](https://github.com/metacosm): 551 contributions (Organizations: apache, gatein, snowdrop, quarkiverse) 🔴 Red Hat 🔴
  2. csviri: 17 contributions (Organizations: None) 🔴 Red Hat 🔴
  3. Sgitario: 14 contributions (Organizations: None) 🔴 Red Hat 🔴

Fabric8 Kubernetes Client

Overview

Fabric8 Kubernetes Client is a versatile and comprehensive client for interacting with Kubernetes clusters using Java. It supports a wide range of Kubernetes resources and provides an extensive set of features for interacting with Kubernetes, making it a one-stop solution for Java developers working with Kubernetes.

Detailed Analysis

The Fabric8 Kubernetes Client offers extensive capabilities and comprehensive support for Kubernetes resources. Its focus on providing a unified and feature-rich interface for interacting with Kubernetes APIs makes it an ideal choice for projects requiring comprehensive interactions with a variety of Kubernetes resources. The client’s support for a wide range of Kubernetes resources and its adaptability make it a suitable choice for diverse use cases.

Fabric8 Kubernetes Client - Detailed Analysis

Initial Configuration

The Fabric8 Kubernetes Client necessitates a straightforward configuration within the pom.xml file. Developers generally need to integrate the Fabric8 Kubernetes Client dependency to ensure the correct functioning. Below is a basic representation of how a pom.xml might be configured when using the Fabric8 Kubernetes Client:

<dependencies>
    <dependency>
        <groupId>io.fabric8</groupId>
        <artifactId>kubernetes-client</artifactId>
        <version>${fabric8.version}</version>
    </dependency>
    <!-- Other dependencies -->
</dependencies>

Fabric8 Kubernetes Client

Initial Setup: pom.xml Configuration

<!-- Adding Fabric8 Kubernetes Client Dependency -->
<dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>${fabric8.version}</version>
</dependency>

Configuration Examples

// Creating Kubernetes Client Configuration
Config config = new ConfigBuilder()
    .withMasterUrl("https://<k8s-master-url>")
    .withOauthToken("<token>")
    .build();

KubernetesClient client = new DefaultKubernetesClient(config);

Coding Examples

// Listing Pods in a Namespace
PodList podList = client.pods().inNamespace("default").list();
for (Pod pod : podList.getItems()) {
    System.out.println(pod.getMetadata().getName());
}

// Creating a Namespace
Namespace ns = new NamespaceBuilder()
    .withNewMetadata().withName("new-namespace").endMetadata()
    .build();

client.namespaces().create(ns);

// Deleting a Namespace
client.namespaces().withName("new-namespace").delete();

Explanation:

The Fabric8 Kubernetes Client provides a fluent API to interact with a Kubernetes cluster. Developers can use the provided ConfigBuilder to configure the connection to the Kubernetes cluster and then create a KubernetesClient to perform operations on the cluster. The examples above demonstrate how to list pods in a namespace, create a new namespace, and delete a namespace using the client. The client supports various other operations, providing developers with the flexibility to manage the Kubernetes resources effectively.

Detailed Analysis

Upon a detailed examination of the Fabric8 Kubernetes Client project, it is evident that the project emphasizes providing a comprehensive and fluent API for developers to interact with Kubernetes clusters. The project's structure is well-organized, with clear distinctions between different Kubernetes resources, allowing for easy navigation and understanding.

The project offers extensive documentation and examples, guiding developers through the process of integrating the client into their projects and illustrating the usage of various features. The community around the project is active, with numerous contributors continually enhancing the client's capabilities and ensuring its alignment with the evolving Kubernetes ecosystem.

The Fabric8 Kubernetes Client stands out for its extensive feature set, supporting a wide range of Kubernetes resources and operations, making it a suitable choice for projects requiring comprehensive interactions with Kubernetes clusters. However, projects looking for a lightweight client may find it to be extensive, necessitating a consideration of the project’s specific needs and preferences.

Top Human Contributors

  1. manusa: 648 contributions (Organizations: eclipse, fabric8io, marcnuri-demo, cekit, jkubeio) 🔴 Red Hat 🔴
  2. iocanel: 637 contributions (Organizations: jclouds, ops4j, fusesource, snowdrop, jboss-fuse, fabric8io, funktionio, shellib, dekorateio) 🔴 Red Hat 🔴
  3. rohanKanojia: 526 contributions (Organizations: eclipse, fabric8io, jkubeio) 🔴 Red Hat 🔴
  4. shawkins: 516 contributions (Organizations: None) 🔴 Red Hat 🔴

Spring Cloud Kubernetes

Overview

Spring Cloud Kubernetes provides an interaction model between Spring Cloud and Kubernetes, allowing Spring Boot applications to work seamlessly on Kubernetes. It offers a set of primitives for building cloud-native applications and services on Kubernetes, making it a suitable choice for developers familiar with the Spring ecosystem.

Detailed Analysis

The Spring Cloud Kubernetes project aims to provide a seamless integration between Kubernetes and Spring Cloud, focusing on enabling developers to utilize Kubernetes-native services within their Spring applications. The project’s structure is modular, allowing developers to integrate specific components based on their requirements, and it offers extensive documentation and examples, facilitating the adoption of the framework.

The project emphasizes providing a simplified and Spring-idiomatic experience, allowing developers to leverage Kubernetes resources effectively while utilizing familiar Spring concepts and annotations. The active community around the project continually contributes to its development, ensuring its alignment with the evolving ecosystems of both Kubernetes and Spring Cloud.

Spring Cloud Kubernetes

Initial Configuration

<!-- Adding Spring Cloud Kubernetes Dependency -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes</artifactId>
    <version>${spring-cloud.version}</version>
</dependency>

Configuration Examples

// Configuring Application Properties
spring:
  cloud:
    kubernetes:
      config:
        name: application-name
        namespace: default

Coding Examples

// Injecting Kubernetes Client
@Autowired
private KubernetesClient kubernetesClient;

// Listing Pods in a Namespace
public List<String> listPods() {
    return kubernetesClient.pods().inNamespace("default").list().getItems()
            .stream()
            .map(pod -> pod.getMetadata().getName())
            .collect(Collectors.toList());
}

// Retrieving ConfigMap
public Map<String, String> getConfigMap(String configMapName) {
    return kubernetesClient.configMaps().inNamespace("default").withName(configMapName).get().getData();
}

Explanation:

Spring Cloud Kubernetes integrates the Kubernetes ecosystem with Spring Cloud, allowing developers to leverage Kubernetes-native services within Spring applications. The framework enables developers to utilize Kubernetes ConfigMaps and Secrets for externalized configuration, ensuring seamless transitions across different environments.

Developers can inject the KubernetesClient to interact with the Kubernetes cluster and perform various operations, such as listing pods in a namespace or retrieving a ConfigMap. The framework's integration with the Spring environment allows developers to manage Kubernetes resources effectively, utilizing familiar Spring concepts and annotations.

Spring Cloud Kubernetes stands out for its seamless integration with the Spring ecosystem, making it a suitable choice for projects based on Spring Cloud. However, projects not utilizing Spring may find it less applicable and should consider other frameworks that align better with their technological stack and preferences.

Top Human Contributors

  1. ryanjbaxter: 419 contributions (Organizations: OpenSocial) 🔵 VMWare 🔵
  2. wind57: 290 contributions (Organizations: None)
  3. spencergibb: 140 contributions (Organizations: spring-projects, spring-cloud, rsocket-broker) 🔵 VMWare 🔵
  4. iocanel: 100 contributions (Organizations: jclouds, ops4j, fusesource, snowdrop, jboss-fuse, fabric8io, funktionio, shellib, dekorateio) 🔴 Red Hat 🔴

Operator Framework Java Operator Plugins

Overview

Operator Framework Java Operator Plugins is a project under the Operator Framework initiative, focusing on providing plugins to facilitate the development of operators using Java. It’s an evolving project aiming to provide essential tools and libraries for developing Java-based operators.

Detailed Analysis

The Operator Framework Java Operator Plugins project is in its early stages, focusing on providing essential libraries and plugins for developing operators in Java. The project aims to fill the gaps in the Java-based operator development ecosystem by offering tools and libraries that streamline the development process and enhance productivity. The project’s focus on the Java ecosystem makes it a suitable choice for developers looking for Java-centric solutions for operator development.

Initial Configuration

<!-- Adding Plugin Dependency -->
<dependency>
    <groupId>io.javaoperatorsdk</groupId>
    <artifactId>operator-framework-spring-boot-starter</artifactId>
    <version>${operator-framework.version}</version>
</dependency>

Configuration Examples

// Application Properties Configuration
quarkus.operator-sdk.clients.default.namespace=default

Coding Examples

// Creating a Controller
@Controller
public class SampleController implements ResourceController<SampleResource> {

    @Override
    public DeleteControl deleteResource(SampleResource resource, Context<SampleResource> context) {
        // Handle delete resource
        return DeleteControl.DEFAULT_DELETE;
    }
    
    @Override
    public UpdateControl<SampleResource> createOrUpdateResource(
      SampleResource resource, Context<SampleResource> context) {
        // Handle create or update resource
        return UpdateControl.updateCustomResource(resource);
    }
}

Explanation:

The Operator Framework Java Operator Plugin provides a foundation for developing Kubernetes operators using Java. It offers a set of APIs and tools to create, deploy, and manage operators efficiently. The developers can leverage the provided ResourceController interface to define the behaviors for handling resources, ensuring a structured approach to implementing operator logic.

This framework provides a clear and concise way to define controllers, allowing developers to focus on implementing the business logic without delving deep into the Kubernetes internals. It integrates well with the Quarkus and Spring Boot, offering flexibility to developers familiar with these ecosystems.

Top Contributors

  1. jmrodri: 40 contributions (Organizations: operator-framework) 🔴 Former Red Hat 🔴
  2. laxmikantbpandhare: 29 contributions (Organizations: kubernetes, nguyensjsu, kubernetes-sigs, operator-framework, team19hackathon2021) 🔴 Former Red Hat 🔴
  3. metacosm: 27 contributions (Organizations: apache, gatein, snowdrop, quarkiverse) 🔴 Red Hat 🔴
  4. theishshah: 3 contributions (Organizations: acm-uiuc, openshift, gnulug, Confbase, operator-framework) 🔴 Red Hat 🔴
  5. sujil02: 3 contributions (Organizations: containers)

Recommendations for Operator Framework Java Operator Plugin

Based on our detailed analysis of various Java-based Kubernetes Operator frameworks, we recommend the following enhancements for the Operator Framework Java Operator Plugin to fill existing gaps in the ecosystem and provide competitive advantages:

  1. Custom Resource Definitions (CRD) Enhancement: Adopting OpenAPI v3 specifications for CRD validation and providing support for multiple versions of CRD will enhance flexibility and usability, This would make it easier for developers to create CRDs that are compatible with a wider range of Kubernetes clusters and versions. It would also make it easier to evolve CRDs over time without breaking existing deployments.

  2. Enhanced Documentation and Examples: Developing comprehensive documentation, including tutorials, guides, and a variety of examples covering different use cases, can facilitate better adoption. It will lower the entry barrier and learning curve for new users and developers, fostering a more inclusive and diverse user community.

  3. Integration with Other Frameworks: Creating guides and tools for integrating with popular frameworks like Spring Boot and Quarkus will expand the plugin’s reach and applicability. It will attract developers from different backgrounds and preferences, increasing the user base and community contributions.

  4. Improve Testability: Offering frameworks or tools that facilitate the testing of operators will enhance development productivity and operator reliability, promoting the development of high-quality operators, increasing the trust and reliability of operators developed using the plugin.


Gaps in the Java-based Operator Development Ecosystem that the Operator Framework Java Operator Plugin Could Fill

The Java-based operator development ecosystem is still evolving, and there are a number of gaps that the Operator Framework Java Operator Plugin aims to fill. Some specific examples of these gaps include:

  • Lack of a common foundation: There are a number of different Java-based operator development frameworks available, but none of them have emerged as the clear leader. This can make it difficult for developers to choose the right framework for their needs, and can also lead to fragmentation of the Java-based operator ecosystem.
  • Complexity: Developing operators can be a complex task, even for experienced Java developers. This is because operators need to interact with a variety of Kubernetes APIs and resources. The Operator Framework Java Operator Plugin aims to simplify the development process by providing a common foundation and a set of APIs and tools that make it easier to develop and manage operators.
  • Lack of documentation and examples: Many of the existing Java-based operator development frameworks lack comprehensive documentation and examples. This can make it difficult for developers to learn how to use the frameworks and to develop their own operators.
  • Lack of integration with other frameworks: Many of the existing Java-based operator development frameworks do not integrate well with other popular Java frameworks, such as Spring Boot and Quarkus. This can make it difficult for developers to use these frameworks to develop operators for their existing Java applications.

In addition to the above, here are some other specific examples of the gaps in the Java-based operator development ecosystem that the Operator Framework Java Operator Plugin aims to fill:

  • Lack of support for multiple Kubernetes versions: Many of the existing Java-based operator development frameworks only support a single version of Kubernetes. This can make it difficult for developers to develop operators that can be deployed to different Kubernetes clusters.
  • Lack of support for custom resource definitions (CRDs): CRDs are a powerful way to extend Kubernetes with new custom resources. However, many of the existing Java-based operator development frameworks do not provide good support for CRDs.
  • Lack of support for testing: Testing operators can be a difficult task. Many of the existing Java-based operator development frameworks do not provide good support for testing operators.

The Operator Framework Java Operator Plugin aims to address all of these gaps by providing a common foundation, simplifying the development process, improving documentation and examples, and providing integration with other popular Java frameworks. By filling these gaps, the Operator Framework Java Operator Plugin can help to make Java a more attractive platform for developing Kubernetes operators.

Java Library Dependency Graph

java_kubernetes_libraries_dependencies

Conclusion

The ecosystem for developing Java-based Kubernetes operators is diverse, with each framework and library catering to different needs and preferences. Choosing the right framework or library involves balancing factors such as features, complexity, community support, and integration capabilities. For the Operator Framework Java Operator Plugin to gain a competitive edge, focusing on strategic developments like enhanced CRD capabilities, improved documentation, and integration with other popular frameworks is crucial. Identifying and addressing the gaps in the existing solutions will position the Operator Framework Java Operator Plugin as a go-to solution for developing Java-based operators.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment