Ejecutar Kubernetes CronJob manualmente desde Java usando YAKC
Introducción
En este post, te mostraré cómo realizar el equivalente a kubectl --from=cronjob/<cronjob-name> <job-name>
(ejecución manual) desde Java usando YAKC- Yet Another Kubernetes Client.
Esto realiza algo similar a lo que hace la acción de activación de CronJob del Dashboard oficial de Kubernetes.

Ejecución manual de CronJob
Una vez que has desplegado un CronJob en tu cluster, en la mayoría de los casos tiene sentido activar una ejecución de prueba. Probablemente, necesites verificar que todo funciona correctamente sin tener que esperar a la hora programada.
A partir de la versión 1.10, Kubernetes ofrece una forma de crear un Job desde un CronJob usando kubectl
.
Esto básicamente se traduce en ejecutar manualmente el CronJob.
A continuación te muestro la implementación del código en Kubectl:
func (o *CreateJobOptions) createJobFromCronJob(cronJob *batchv1beta1.CronJob) *batchv1.Job {
annotations := make(map[string]string)
annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range cronJob.Spec.JobTemplate.Annotations {
annotations[k] = v
}
job := &batchv1.Job{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Annotations: annotations,
Labels: cronJob.Spec.JobTemplate.Labels,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: batchv1beta1.SchemeGroupVersion.String(),
Kind: cronJob.Kind,
Name: cronJob.GetName(),
UID: cronJob.GetUID(),
},
},
},
Spec: cronJob.Spec.JobTemplate.Spec,
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}
En el fragmento de código anterior, vemos cómo kubectl
crea un nuevo Job
usando el JobTemplate
del CronJob y propaga las etiquetas.
Ejecutar CronJob desde Java
Ahora que hemos visto cómo kubectl
crea un Job
desde un CronJob
, veamos cómo podemos lograr esto con YAKC.
final CronJob cronJob = kc.create(BatchV1beta1Api.class).readNamespacedCronJob(name, applicableNamespace).get();
final String jobName = String.format("%s-manual-%s",
name.length() > 38 ? name.substring(0, 38) : name,
new Random().nextInt(999999)
);
kc.create(BatchV1Api.class).createNamespacedJob(applicableNamespace, Job.builder()
.metadata(ObjectMeta.builder()
.name(jobName).namespace(applicableNamespace)
.labels(new HashMap<>(Optional.ofNullable(cronJob.getMetadata().getLabels()).orElse(Collections.emptyMap())))
.putInAnnotations("cronjob.kubernetes.io/instantiate", "manual")
.addToOwnerReferences(OwnerReference.builder()
.kind(cronJob.getKind())
.apiVersion(cronJob.getApiVersion())
.controller(false)
.name(cronJob.getMetadata().getName())
.uid(cronJob.getMetadata().getUid())
.build())
.build())
.spec(cronJob.getSpec().getJobTemplate().getSpec())
El fragmento de código anterior es parte del quickstart de CronJobs jbang.
El primer paso es recuperar el CronJob
actual del cluster. A continuación, generamos un nombre aleatorio para el job activado manualmente usando el nombre del CronJob como prefijo.
Finalmente, creamos un nuevo Job
usando el JobTemplateSpec
del CronJob recuperado y propagamos sus etiquetas. También agregamos una referencia de propietario al Job creado para que pueda ser asociado y listado al consultar el CronJob
.
Dado que este ejemplo está alojado como un script de jbang, puedes probarlo directamente ejecutando el siguiente comando:
jbang https://github.com/manusa/yakc/blob/master/quickstarts/jbang/CronJobs.java trigger $cronJobName
A continuación puedes verificar el resultado de la operación en la interfaz de YAKC – Kubernetes Dashboard (puedes leer más sobre este proyecto aquí):

Conclusión
En este post, te he mostrado cómo activar manualmente CronJobs desde Java usando YAKC.
He extraído el código para este post de la sección de quickstarts jbang de YAKC. Puedes aprender más visitando el sitio del proyecto YAKC en GitHub. También puedes ver el código relacionado aquí.