eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – Summer Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

Course – Summer Sale 2026 – NPI (cat=Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

1. Introduction

In this tutorial, we’ll cover CRUD operations on Kubernetes resources using its official Java API.

We’ve already covered the basics of this API usage in previous articles, including basic project setup and various ways in which we can use it to get information about a running cluster.

In general, Kubernetes deployments are mostly static. We create some artifacts (e.g. YAML files) describing what we want to create and submit them to a DevOps pipeline. The pieces of our system then remain the same until we add a new component or upgrade an existing one.

However, there are cases where we need to add resources on the fly. A common one is running Jobs in response to a user-initiated request. In response, the application would launch a background job to process the report and make it available for later retrieval.

The key point here is that, by using those APIs, we can make better use of the available infrastructure, as we can consume resources only when they’re needed, releasing them afterward.

2. Creating a New Resource

In this example, we’ll create a Job resource in a Kubernetes cluster. A Job is a kind of Kubernetes workload that, differently from other kinds, runs to completion. That is, once the programs running in its pod terminate, the job itself terminates. Its YAML representation is not unlike other resources:

apiVersion: batch/v1
kind: Job
metadata:
  namespace: jobs
  name: report-job
  labels:
    app: reports
spec:
  template:
    metadata:
      name: payroll-report
    spec:
      containers:
      - name: main
        image: report-runner
        command:
        - payroll
        args:
        - --date
        - 2021-05-01
      restartPolicy: Never

The Kubernetes API offers two ways to create the equivalent Java object:

  • Creating POJOS with new and populating all required properties via setters
  • Using a fluent API to build the Java resource representation

Which approach to use is mostly a personal preference. Here, we’ll use the fluent approach to create the V1Job object, as the building process looks very similar to its YAML counterpart:

ApiClient client  = Config.defaultClient();
BatchV1Api api = new BatchV1Api(client);
V1Job body = new V1JobBuilder()
  .withNewMetadata()
    .withNamespace("report-jobs")
    .withName("payroll-report-job")
    .endMetadata()
  .withNewSpec()
    .withNewTemplate()
      .withNewMetadata()
        .addToLabels("name", "payroll-report")
        .endMetadata()
      .editOrNewSpec()
        .addNewContainer()
          .withName("main")
          .withImage("report-runner")
          .addNewCommand("payroll")
          .addNewArg("--date")
          .addNewArg("2021-05-01")
          .endContainer()
        .withRestartPolicy("Never")
        .endSpec()
      .endTemplate()
    .endSpec()
  .build(); 
V1Job createdJob = api.createNamespacedJob("report-jobs", body, null, null, null);

We start by creating the ApiClient and then API stub instance. Job resources are part of the Batch API, so we create a BatchV1Api instance, which we’ll use to invoke the cluster’s API server.

Next, we instantiate a V1JobBuilder instance, which kind of leads us through the process of filling all the properties.  Notice the use of nested builders: to “close” a nested builder, we must call its endXXX() method, which brings us back to its parent builder.

Alternatively, it’s also possible to use a withXXX method to inject a nested object directly. This is useful when we want to reuse a common set of properties, such as metadata, labels, and annotations.

The final step is just a call to the API stub. This will serialize our resource object and POST the request to the server. As expected, there are synchronous (used above) and asynchronous versions of the API.

The returned object will contain metadata and status fields related to the created job. In the case of a Job, we can use its status field to check when it is finished. We can also one of the techniques presented in our article about monitoring resources to receive this notification.

3. Updating an Existing Resource

Updating an existing resource consists of sending a PATCH request to the Kubernetes API server, containing which fields we want to modify. As of Kubernetes version 1.16, there are four ways to specify those fields:

  • JSON Patch (RFC 6092)
  • JSON Merge Patch (RFC 7396)
  • Strategic Merge Patch
  • Apply YAML

Of those, the last one is the easiest one to use as it leaves all merging and conflict resolution to the server: all we have to do is send a YAML document with the fields we want to modify.

Unfortunately, the Java API offers no easy way to build this partial YAML document. Instead, we must resort to the PatchUtil helper class to send a raw YAML or JSON  string. However, we can use the built-in JSON serializer available through the ApiClient object to get it:

V1Job patchedJob = new V1JobBuilder(createdJob)
  .withNewMetadata()
    .withName(createdJob.getMetadata().getName())
    .withNamespace(createdJob.getMetadata().getNamespace())
    .endMetadata()
  .editSpec()
    .withParallelism(2)
  .endSpec()
  .build();

String patchedJobJSON = client.getJSON().serialize(patchedJob);

PatchUtils.patch(
  V1Job.class, 
  () -> api.patchNamespacedJobCall(
    createdJob.getMetadata().getName(), 
    createdJob.getMetadata().getNamespace(), 
    new V1Patch(patchedJobJSON), 
    null, 
    null, 
    "baeldung", 
    true, 
    null),
  V1Patch.PATCH_FORMAT_APPLY_YAML,
  api.getApiClient());

Here, we use the object returned from createNamespacedJob() as a template from which we’ll construct the patched version. In this case, we’re just increasing the parallelism value from one to two, leaving all other fields unchanged. An important point here is that as we build the modified resource, we must use the withNewMetadata().  This ensures that we don’t build an object containing managed fields, which are present in the returned object we got after creating the resource. For a full description of managed fields and how they’re used in Kubernetes, please refer to the documentation.

Once we’ve built an object with the modified fields, we then convert it to its JSON representation using the serialize method. We then use this serialized version to construct a V1Patch object used as the payload for the PATCH call. The patch method also takes an additional argument where we inform the kind of data present in the request. In our case, this is PATCH_FORMAT_APPLY_YAML, which the library uses as the Content-Type header included in the HTTP request.

The “baeldung” value passed to the fieldManager parameter defines the actor name who is manipulating the resource’s fields. Kubernetes uses this value internally to resolve an eventual conflict when two or more clients try to modify the same resource. We also pass true in the force parameter, meaning that we’ll take ownership of any modified field.

4. Deleting a Resource

Compared to the previous operations, deleting a resource is quite straightforward:

V1Status response = api.deleteNamespacedJob(
  createdJob.getMetadata().getName(), 
  createdJob.getMetadata().getNamespace(), 
  null, 
  null, 
  null, 
  null, 
  null, 
  null ) ;

Here, we’re just using the deleteNamespacedJob method to remove the job using default options for this specific kind of resource. If required, we can use the last parameter to control the details of the deletion process. This takes the form of a V1DeleteOptions  object, which we can use to specify a grace period and cascading behavior for any dependent resources.

5. Conclusion

In this article, we’ve covered how to manipulate Kubernetes resources using the Java Kubernetes API library.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – Summer Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

Course – Summer Sale 2026 – NPI (All)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

eBook Jackson – NPI EA – 3 (cat = Jackson)