Cloud Native 19 min read

Managing Kubernetes Resources with the Fabric8 Java Client: Jobs, CronJobs, Namespaces, ServiceAccounts, Ingress, StatefulSets, and DaemonSets

This guide demonstrates how to use the Fabric8 Java client to create, retrieve, update, list, watch, and delete common Kubernetes resources such as Job, CronJob, Namespace, ServiceAccount, Ingress, StatefulSet, and DaemonSet, providing code snippets for each operation.

FunTester
FunTester
FunTester
Managing Kubernetes Resources with the Fabric8 Java Client: Jobs, CronJobs, Namespaces, ServiceAccounts, Ingress, StatefulSets, and DaemonSets

In the world of Kubernetes, mastering the management and operation of various resources is essential for developers and operators. Resources such as Job, CronJob, Namespace, ServiceAccount, and Ingress are indispensable parts of the Kubernetes ecosystem. Below are common operation examples for these resources using the Fabric8 Java client.

Job

Job is a controller for running one‑off tasks, ensuring they complete successfully and exit, suitable for batch or data‑processing jobs.

Job resources can be accessed via client.batch().jobs() . Common operations include:

Load Job from YAML file :

Job job = client.batch().jobs().load(new FileInputStream("sample-job.yml")).item();

Get Job from API server :

Job job = client.batch().jobs().inNamespace("FunTester").withName("pi").get();

Create Job :

final Job job = new JobBuilder()
    .withApiVersion("batch/v1")
    .withNewMetadata().withName("pi").withLabels(Collections.singletonMap("label1", "maximum-length-of-63-characters")).withAnnotations(Collections.singletonMap("annotation1", "some-very-long-annotation")).endMetadata()
    .withNewSpec()
      .withNewTemplate()
        .withNewSpec()
          .addNewContainer()
            .withName("pi")
            .withImage("perl")
            .withArgs("perl", "-Mbignum=bpi", "-wle", "print bpi(2000)")
          .endContainer()
          .withRestartPolicy("Never")
        .endSpec()
      .endTemplate()
    .endSpec()
    .build();
client.batch().jobs().inNamespace("FunTester").resource(job).create();

Apply Job to cluster (server‑side apply) :

Job job = client.batch().v1().jobs().inNamespace("FunTester").resource(job1).serverSideApply();

List Jobs in a specific namespace :

JobList jobList = client.batch().jobs().inNamespace("FunTester").list();

List Jobs in all namespaces :

JobList jobList = client.batch().jobs().inAnyNamespace().list();

List Jobs with a specific label :

JobList jobList = client.batch().jobs().inNamespace("FunTester").withLabel("foo", "bar").list();

Delete Job :

client.batch().jobs().inNamespace("FunTester").withName("pi").delete();

Watch Job :

client.batch().jobs().inNamespace("FunTester").watch(new Watcher<>() {
    @Override
    public void eventReceived(Action action, Job resource) {
        // handle event
    }
    @Override
    public void onClose(WatcherException cause) {}
});

CronJob

CronJob runs Jobs on a schedule (Cron‑like) for periodic tasks.

Access via client.batch().cronjobs() . Common operations:

Load CronJob from YAML :

CronJob cronJob = client.batch().cronjobs().load(new FileInputStream("cronjob.yml")).item();

Get CronJob from API server :

CronJob aCronJob = client.batch().cronjobs().inNamespace("FunTester").withName("some-cj").get();

Create CronJob :

CronJob cronJob1 = new CronJobBuilder()
    .withApiVersion("batch/v1beta1")
    .withNewMetadata().withName("hello").withLabels(Collections.singletonMap("foo", "bar")).endMetadata()
    .withNewSpec()
      .withSchedule("*/1 * * * *")
      .withNewJobTemplate()
        .withNewSpec()
          .withNewTemplate()
            .withNewSpec()
              .addNewContainer()
                .withName("hello")
                .withImage("busybox")
                .withArgs("/bin/sh", "-c", "date; echo Hello from Kubernetes")
              .endContainer()
              .withRestartPolicy("OnFailure")
            .endSpec()
          .endTemplate()
        .endSpec()
      .endJobTemplate()
    .endSpec()
    .build();
client.batch().cronjobs().inNamespace("FunTester").resource(cronJob1).create();

Apply CronJob (server‑side apply) :

CronJob cronJob = client.batch().v1().cronjobs().inNamespace("FunTester").resource(cronJob1).serverSideApply();

List CronJobs in a namespace :

CronJobList cronJobList = client.batch().cronjobs().inNamespace("FunTester").list();

List CronJobs in all namespaces :

CronJobList cronJobList = client.batch().cronjobs().inAnyNamespace().list();

List CronJobs with a label :

CronJobList cronJobList = client.batch().cronjobs().inNamespace("FunTester").withLabel("foo", "bar").list();

Edit/Update CronJob :

CronJob cronJob1 = client.batch().cronjobs().inNamespace("FunTester").withName(cronJob1.getMetadata().getName()).edit(cj -> new CronJobBuilder(cj).editSpec().withSchedule("*/1 * * * *").endSpec().build());

Delete CronJob :

client.batch().cronjobs().inNamespace("FunTester").withName("pi").delete();

Namespace

Namespaces can be accessed via client.namespaces() . Common operations:

Load Namespace from YAML :

Namespace namespace = client.namespaces().load(new FileInputStream("namespace-test.yml")).item();

Get Namespace from API server :

Namespace namespace = client.namespaces().withName("namespace1").get();

List Namespaces :

NamespaceList namespaceList = client.namespaces().list();

List Namespaces with a label :

NamespaceList namespaceList = client.namespaces().withLabel("key1", "value1").list();

Delete Namespace :

client.namespaces().withName("ns1").delete();

ServiceAccount

ServiceAccount provides identity for Pods and is usually bound to a Role or ClusterRole.

Access via client.serviceAccounts() . Common operations:

Load ServiceAccount from YAML :

ServiceAccount svcAccount = client.serviceAccounts().inNamespace("FunTester").load(new FileInputStream("sa.yml")).item();

Get ServiceAccount from API server :

ServiceAccount sa = client.serviceAccounts().inNamespace("FunTester").withName("sa-ribbon").get();

Create ServiceAccount :

ServiceAccount serviceAccount1 = new ServiceAccountBuilder()
    .withNewMetadata().withName("serviceaccount1").endMetadata()
    .withAutomountServiceAccountToken(false)
    .build();
client.serviceAccounts().inNamespace("FunTester").resource(serviceAccount1).create();

Apply ServiceAccount (server‑side apply) :

ServiceAccount serviceAccount = client.serviceAccounts().inNamespace("FunTester").resource(serviceAccount1).serverSideApply();

List ServiceAccounts in a namespace :

ServiceAccountList svcAccountList = client.serviceAccounts().inNamespace("FunTester").list();

List ServiceAccounts with a label :

ServiceAccountList saList = client.serviceAccounts().inNamespace("FunTester").withLabel("foo", "bar").list();

Update/Edit ServiceAccount :

ServiceAccount serviceAccount1 = client.serviceAccounts().inNamespace("FunTester").withName("serviceaccount1").edit(sa -> new ServiceAccountBuilder(sa)
    .addNewSecret().withName("default-token-uudp").endSecret()
    .addNewImagePullSecret().withName("myregistrykey").endImagePullSecret()
    .build());

Delete ServiceAccount :

client.serviceAccounts().inNamespace("FunTester").withName("serviceaccount1").delete();

Ingress

Ingress manages external HTTP/HTTPS access to Services inside the cluster.

Access via client.network().v1().ingress() . Common operations:

Load Ingress from YAML :

Ingress ingress = client.network().v1().ingress().load(new FileInputStream("ingress.yml")).item();

Get Ingress from API server :

Ingress ingress = client.network().v1().ingress().inNamespace("FunTester").withName("ingress1").get();

Create Ingress :

Ingress ingress = new IngressBuilder()
    .withNewMetadata().withName("test-ingress").addToAnnotations("nginx.ingress.kubernetes.io/rewrite-target", "/").endMetadata()
    .withNewSpec()
      .addNewRule()
        .withNewHttp()
          .addNewPath()
            .withPath("/testPath")
            .withNewBackend().withServiceName("test").withServicePort(new IntOrString(80)).endBackend()
          .endPath()
        .endHttp()
      .endRule()
    .endSpec()
    .build();
client.network().v1().ingress().inNamespace("FunTester").resource(ingress).create();

Apply Ingress (server‑side apply) :

Ingress igx = client.network().v1().ingresses().inNamespace("FunTester").resource(ingress).serverSideApply();

List Ingresses in a namespace :

IngressList ingressList = client.network().v1().ingress().inNamespace("FunTester").list();

List Ingresses in all namespaces :

IngressList ingressList = client.network().v1().ingress().inAnyNamespace().list();

List Ingresses with a label :

IngressList ingressList = client.network().v1().ingress().inNamespace("FunTester").withLabel("foo", "bar").list();

Delete Ingress :

client.network().v1().ingress().inNamespace("FunTester").withName("ingress1").delete();

StatefulSet

StatefulSet manages stateful applications, ensuring each Pod has a stable network identity and persistent storage.

Access via client.apps().statefulsets() . Common operations:

Load StatefulSet from YAML :

StatefulSet aStatefulSet = client.apps().statefulSets().load(new FileInputStream("test-statefulset.yml")).item();

Get StatefulSet from API server :

StatefulSet ss1 = client.apps().statefulSets().inNamespace("FunTester").withName("ss1").get();

Create StatefulSet :

StatefulSet ss1 = new StatefulSetBuilder()
    .withNewMetadata().withName("ss1").endMetadata()
    .withNewSpec()
      .withReplicas(2)
      .withNewSelector().withMatchLabels(Collections.singletonMap("app", "nginx")).endSelector()
      .withNewTemplate()
        .withNewMetadata().addToLabels("app", "nginx").endMetadata()
        .withNewSpec()
          .addNewContainer()
            .withName("nginx")
            .withImage("nginx")
            .addNewPort().withContainerPort(80).withName("web").endPort()
            .addNewVolumeMount().withName("www").withMountPath("/usr/share/nginx/html").endVolumeMount()
          .endContainer()
        .endSpec()
      .endTemplate()
      .addNewVolumeClaimTemplate()
        .withNewMetadata().withName("www").endMetadata()
        .withNewSpec()
          .addToAccessModes("ReadWriteOnce")
          .withNewResources().withRequests(Collections.singletonMap("storage", new Quantity("1Gi"))).endResources()
        .endSpec()
      .endVolumeClaimTemplate()
    .endSpec()
    .build();
client.apps().statefulSets().inNamespace("FunTester").resource(ss1).create();

Apply StatefulSet (server‑side apply) :

StatefulSet ss = client.apps().statefulSets().inNamespace("FunTester").resource(ss1).serverSideApply();

List StatefulSets in a namespace :

StatefulSetList statefulSetList = client.apps().statefulSets().inNamespace("FunTester").list();

List StatefulSets in all namespaces :

StatefulSetList statefulSetList = client.apps().statefulSets().inAnyNamespace().list();

List StatefulSets with a label :

StatefulSetList statefulSetList = client.apps().statefulSets().inNamespace("FunTester").withLabel("foo", "bar").list();

Delete StatefulSet :

client.apps().statefulSets().inNamespace("FunTester").withName("ss1").delete();

Scale StatefulSet :

client.apps().statefulSets().inNamespace("FunTester").withName("ss1").scale(2);

Watch StatefulSet :

client.apps().statefulSets().inNamespace("FunTester").withName("ss1").watch(new Watcher<>() {
    @Override
    public void eventReceived(Action action, StatefulSet resource) {}
    @Override
    public void onClose(WatcherException cause) {}
});

Update image of a container in StatefulSet :

client.apps().statefulSets().inNamespace("FunTester").withName("web").updateImage("nginx:1.19");

Rolling restart, pause, resume, and rollback :

StatefulSet ss = client.apps().statefulSets().inNamespace("FunTester").withName("web").rolling().restart();
client.apps().statefulSets().inNamespace("FunTester").withName("web").rolling().pause();
client.apps().statefulSets().inNamespace("FunTester").withName("web").rolling().resume();
client.apps().statefulSets().inNamespace("FunTester").withName("web").rolling().undo();

DaemonSet

DaemonSet ensures that a copy of a Pod runs on every node (or on nodes matching a label), useful for node‑level services such as log collectors.

Access via client.apps().daemonSets() . Common operations:

Load DaemonSet from YAML :

DaemonSet ds = client.apps().daemonSets().load(new FileInputStream("daemonset.yaml")).item();

Get DaemonSet from API server :

DaemonSet ds = client.apps().daemonSets().inNamespace("FunTester").withName("ds1").get();

Create DaemonSet :

DaemonSet ds = new DaemonSetBuilder()
    .withNewMetadata().withName("fluentd-elasticsearch").addToLabels("k8s-app", "fluentd-logging").endMetadata()
    .withNewSpec()
      .withNewSelector().addToMatchLabels("name", "fluentd-elasticsearch").endSelector()
      .withNewTemplate()
        .withNewSpec()
          .addNewToleration().withKey("node-role.kubernetes.io/master").withEffect("NoSchedule").endToleration()
          .addNewContainer()
            .withName("fluentd-elasticsearch")
            .withImage("quay.io/fluentd_elasticsearch/fluentd:v2.5.2")
            .withNewResources()
              .addToLimits(Collections.singletonMap("memory", new Quantity("200Mi")))
              .addToRequests(Collections.singletonMap("cpu", new Quantity("100m")))
            .endResources()
            .addNewVolumeMount().withName("varlog").withMountPath("/var/log").endVolumeMount()
          .endContainer()
          .withTerminationGracePeriodSeconds(30L)
          .addNewVolume().withName("varlog").withNewHostPath().withPath("/var/log").endHostPath().endVolume()
        .endSpec()
      .endTemplate()
    .endSpec()
    .build();
client.apps().daemonSets().inNamespace("FunTester").resource(ds).create();

Apply DaemonSet (server‑side apply) :

DaemonSet ds = client.apps().daemonSets().inNamespace("FunTester").resource(ds1).serverSideApply();

List DaemonSets in a namespace :

DaemonSetList dsList = client.apps().daemonSets().inNamespace("FunTester").list();

List DaemonSets in all namespaces :

DaemonSetList dsList = client.apps().daemonSets().inAnyNamespace().list();

List DaemonSets with a label :

DaemonSetList dsList = client.apps().daemonSets().inNamespace("FunTester").withLabel("foo", "bar").list();

Delete DaemonSet :

client.apps().daemonSets().inNamespace("FunTester").withName("ds1").delete();

Watch DaemonSet :

client.apps().daemonSets().inNamespace("FunTester").watch(new Watcher<>() {
    @Override
    public void eventReceived(Action action, DaemonSet resource) {}
    @Override
    public void onClose(WatcherException cause) {}
});

Through these examples, we can see that Kubernetes provides a rich API for managing various resources. Mastering operations on Job, CronJob, Namespace, ServiceAccount, Ingress, StatefulSet, and DaemonSet enables smooth navigation of the Kubernetes ecosystem.

Javacloud-nativeKubernetesresource managementDevOpsFabric8
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.