In fact, a Java wrapper library that calls the Kubernetes API is officially prepared, and you can operate Kubernetes relatively easily from a Java application.
This time, let's create a REST API that starts Job with Spring Boot.
curl -s https://start.spring.io/starter.tgz \
-d baseDir=k8s-job-sample \
-d type=gradle-project \
-d javaVersion=1.8 \
-d dependencies=web,lombok | tar -xzvf -
Add dependency to build.gradle
compile('io.kubernetes:client-java:1.0.0-beta2')
src/main/resources/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(100)"]
restartPolicy: Never
backoffLimit: 4
DemoApplication.java
package com.example.demo;
import com.google.gson.Gson;
import io.kubernetes.client.ApiClient;
import io.kubernetes.client.apis.BatchV1Api;
import io.kubernetes.client.util.Config;
import java.io.IOException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public Gson gson() {
return new Gson();
}
@Bean
public Yaml yaml() {
return new Yaml(new SafeConstructor());
}
@Bean
public ApiClient apiClient() throws IOException {
return Config.fromConfig("/path/to/k8s-config.yaml");
}
@Bean
public BatchV1Api batchV1Api(ApiClient apiClient) {
return new BatchV1Api(apiClient);
}
}
Controller
JobController.java
package com.example.demo;
import com.google.gson.Gson;
import io.kubernetes.client.ApiException;
import io.kubernetes.client.apis.BatchV1Api;
import io.kubernetes.client.models.V1Job;
import io.kubernetes.client.models.V1ObjectMeta;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.yaml.snakeyaml.Yaml;
@RestController
@RequestMapping("jobs")
@RequiredArgsConstructor
public class JobController {
private final BatchV1Api batchApi;
private final ResourceLoader resourceLoader;
private final Gson gson;
private final Yaml yaml;
private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
@PostMapping
public V1Job executeJob(@RequestParam(required = false, defaultValue = "default") String nameSpace)
throws IOException, ApiException {
V1Job job = loadJobFromYaml("job.yaml");
V1ObjectMeta metaData = job.getMetadata();
metaData.setName(String.format("%s-%s", metaData.getName(), dateTimeFormatter.format(LocalDateTime.now())));
return batchApi.createNamespacedJob(nameSpace, job, null);
}
private V1Job loadJobFromYaml(String fileName) throws IOException {
Map jobManifest = (Map) yaml.load(
resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + fileName).getInputStream());
return gson.fromJson(gson.toJson(jobManifest), V1Job.class);
}
}
$ curl -X POST http://localhost:8080/jobs?nameSpace=develop
Recommended Posts