How to create Job in Kubernetes using Java API

Am able to create a job in the Kubernetes cluster using CLI (https://kubernetesbyexample.com/jobs/)

Is there a way to create a job inside the cluster using Java API ?


Solution 1:

You can use Kubernetes Java Client to create any object such as Job. Referring from the example here

/*
 * Creates a simple run to complete job that computes π to 2000 places and prints it out.
 */
public class JobExample {
    private static final Logger logger = LoggerFactory.getLogger(JobExample.class);

    public static void main(String[] args) {
        final ConfigBuilder configBuilder = new ConfigBuilder();
        if (args.length > 0) {
          configBuilder.withMasterUrl(args[0]);
        }
        try (KubernetesClient client = new DefaultKubernetesClient(configBuilder.build())) {
          final String namespace = "default";
          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();

          logger.info("Creating job pi.");
          client.batch().jobs().inNamespace(namespace).createOrReplace(job);

          // Get All pods created by the job
          PodList podList = client.pods().inNamespace(namespace).withLabel("job-name", job.getMetadata().getName()).list();
          // Wait for pod to complete
          client.pods().inNamespace(namespace).withName(podList.getItems().get(0).getMetadata().getName())
            .waitUntilCondition(pod -> pod.getStatus().getPhase().equals("Succeeded"), 1, TimeUnit.MINUTES);

          // Print Job's log
          String joblog = client.batch().jobs().inNamespace(namespace).withName("pi").getLog();
          logger.info(joblog);

        } catch (KubernetesClientException e) {
            logger.error("Unable to create job", e);
        } catch (InterruptedException interruptedException) {
          logger.warn("Thread interrupted!");
          Thread.currentThread().interrupt();
        }
    }
}

Solution 2:

If you want to launch a job using a static manifest yaml from inside the cluster, it should be easy using the official library. This code worked for me.

ApiClient client = ClientBuilder.cluster().build(); //create in-cluster client
Configuration.setDefaultApiClient(client);
BatchV1Api api = new BatchV1Api(client);
    
V1Job job = new V1Job();
job = (V1Job) Yaml.load(new File("/tmp/template.yaml")); //load static yaml file
        
ApiResponse<V1Job> response = api.createNamespacedJobWithHttpInfo("default", job, "true", null, null);

You can also modify any kind of information of the job before launching it with the combination of getter and setter.

// set metadata-name
job.getMetadata().setName("newName");
    
// set spec-template-metadata-name
job.getSpec().getTemplate().getMetadata().setName("newName");