Parcheando recursos de Kubernetes desde Java con Fabric8 Kubernetes Client 7
Introducción
Cuando gestionas recursos de Kubernetes de forma programática, es posible que necesites actualizar partes de un recurso existente sin reemplazarlo por completo. Los controladores y operadores de Kubernetes a menudo utilizan el parcheo para actualizar recursos de una manera más eficiente y controlada. Con el Fabric8 Kubernetes Client 7, hay varias estrategias de parcheo disponibles que se mapean directamente a los mecanismos de parcheo nativos de Kubernetes.
En este artículo, te mostraré los tres métodos principales de parcheo: Strategic Merge Patch, JSON Patch y JSON Merge Patch, y ejemplos de código para cada uno.
¿Cuáles son los distintos métodos de parcheo en Kubernetes?
Kubernetes proporciona tres métodos principales de parcheo para actualizar recursos:
Strategic Merge Patch
El Strategic Merge Patch es un formato de parcheo específico de Kubernetes que te permite actualizar campos concretos en un recurso. Este método de parcheo está diseñado para ser más fácil de usar y menos propenso a errores que otros formatos de parcheo. Es particularmente útil para actualizar recursos que tienen un esquema bien definido, como los Custom Resource Definitions (CRDs).
JSON Patch (RFC 6902)
JSON Patch es un formato estándar definido en RFC 6902 que describe cómo aplicar una lista de operaciones a un documento JSON. Cada operación especifica un cambio que se aplicará al documento de destino.
El siguiente fragmento muestra una transacción HTTP que aplica un JSON Patch a un recurso HTTP:
PATCH /api/data/my-resource HTTP/1.1
Host: example.com
Content-Length: 152
Content-Type: application/json-patch+json
[
{ "op": "add", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "replace", "path": "/a/b/c", "value": "bar" }
]
JSON Merge Patch (RFC 7396)
JSON Merge Patch es un formato de parcheo más simple que funciona como una "actualización parcial" de un documento JSON según lo definido en RFC 7396.
Proporcionas un documento JSON con los campos a cambiar.
Establecer un campo a null
puede eliminarlo.
El Fabric8 Kubernetes Client proporciona soporte para todos estos tipos de parcheo, lo que lo convierte en una herramienta versátil para los desarrolladores de Java que trabajan con Kubernetes y OpenShift.
Parcheando recursos con Fabric8 Kubernetes Client 7
El Fabric8 Kubernetes Client 7 proporciona una forma sencilla de parchear recursos utilizando los tres métodos principales de parcheo en Kubernetes.
Strategic Merge Patch
Fabric8 proporciona un método sencillo que acepta una cadena JSON (o YAML) sin procesar para un strategic merge patch por defecto. Por ejemplo, supongamos que deseas actualizar la imagen del contenedor de un Deployment. Puedes escribir:
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
public class StrategicMergePatch {
public static void main(String[] args) {
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
String patch = "{"
+ " \"spec\": {"
+ " \"template\": {"
+ " \"spec\": {"
+ " \"containers\": ["
+ " {\"name\": \"my-container\", \"image\": \"nginx:latest\"}"
+ " ]"
+ " }"
+ " }"
+ " }"
+ "}";
client.apps().deployments().inNamespace("default").withName("my-deployment")
.patch(patch);
}
}
}
En este fragmento, la cadena de parcheo actualiza la imagen del contenedor en un Deployment.
Al usar el método patch(String)
de un sólo parámetro, Fabric8 utiliza el algoritmo de strategic merge patch por defecto.
JSON Patch
Si necesitas un control más granular, por ejemplo, cuando necesitas reemplazar un valor de campo utilizando una ruta precisa, puedes usar JSON Patch.
Con Fabric8, esto se logra especificando un PatchContext
con el tipo de parcheo JSON
.
Considera el siguiente ejemplo que actualiza una imagen de contenedor:
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
import io.fabric8.kubernetes.client.dsl.base.PatchType;
public class JsonPatch {
public static void main(String[] args) {
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
String patch = "["
+ "{\"op\": \"replace\", \"path\": \"/spec/template/spec/containers/0/image\", \"value\": \"nginx:latest\"}"
+ "]";
client.apps().deployments().inNamespace("default").withName("my-deployment")
.patch(PatchContext.of(PatchType.JSON), patch);
}
}
}
El fragmento anterior ilustra algunos puntos clave:
- El cliente Fabric8 proporciona un método
patch(PatchContext, String)
que acepta un objetoPatchContext
y una cadena JSON Patch. - El objeto
PatchContext
especifica el tipo de parcheo comoJSON
. PatchContext.of(PatchType)
es una forma conveniente de crear un objetoPatchContext
con el tipo de parcheo deseado.- Además, puedes establecer opciones como
force
,fieldManager
yfieldValidation
enPatchContext
utilizandoPatchContext.Builder
. - La cadena JSON Patch contiene la operación para reemplazar la imagen del contenedor en el Deployment según lo especificado en RFC 6902.
JSON Merge Patch
Para una operación de parcheo más sencilla, puedes usar el método JSON Merge Patch. Es útil cuando simplemente deseas actualizar o eliminar campos en un recurso.
El siguiente ejemplo muestra cómo eliminar una anotación de un recurso:
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
import io.fabric8.kubernetes.client.dsl.base.PatchType;
public class JsonMergePatch {
public static void main(String[] args) {
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
// In this patch, setting the "foo" annotation to null removes it.
String jsonMergePatch = "{"
+ "\"metadata\": {"
+ " \"annotations\": {"
+ " \"foo\": null"
+ " }"
+ "}"
+ "}";
PatchContext patchContext = PatchContext.of(PatchType.JSON_MERGE);
client.apps().deployments().inNamespace("default").withName("my-deployment")
.patch(patchContext, jsonMergePatch);
}
}
}
En este ejemplo, la cadena JSON Merge Patch elimina la anotación foo
del recurso estableciéndola a null
.
¿Cuándo usar cada método de parcheo?
Cada método de parcheo tiene sus propias ventajas y desventajas.
- Strategic Merge Patch: Utiliza este método cuando quieras actualizar campos específicos en un recurso estándar de Kubernetes. Fusiona listas y mapas de forma inteligente, sin afectar a otros campos.
- JSON Patch: Ideal para operaciones detalladas cuando necesitas un control preciso sobre qué añadir, eliminar o reemplazar. Funciona bien cuando estás cómodo especificando rutas a campos de un documento JSON.
- JSON Merge Patch: Un método más sencillo para actualizaciones parciales. Es útil cuando deseas actualizar o eliminar campos sin especificar la ruta exacta.
Nota
Recuerda que el parcheo tiene algunas dificultades. Por ejemplo, actualizar campos inmutables (como ciertos selectores) provocará errores.
Es importante que consultes siempre la documentación de la API de Kubernetes y pruebes a fondo tus operaciones de parcheo.
Conclusión
Parchear recursos de Kubernetes utilizando el Fabric8 Kubernetes Client 7 es una forma potente de gestionar actualizaciones de forma programática. Al aprovechar Strategic Merge Patch, JSON Merge Patch y JSON Patch, puedes gestionar distintos casos de uso con facilidad. Ya sea añadiendo anotaciones, actualizando imágenes de contenedor o modificando configuraciones, Fabric8 proporciona una API robusta para interactuar con tu clúster.
Puedes encontrar el código fuente completo de este artículo en GitHub.
¡Feliz parcheo!