Accede al API de Kubernetes desde un Pod con Java


Introducción

En este ejemplo os mostraré cómo podéis acceder a la API REST de vuestro Kubernetes cluster desde un Pod utilizando YAKC (Yet Another Kubernetes Client), Eclipse JKube y Spring Boot.

En la primera parte os enseñaré  cómo crear una aplicación muy sencilla basada en Spring Boot con la dependencia a YAKC Kubernetes Client (ver introducción a YAKC).

En la segunda parte describo cómo desplegar la aplicación en un cluster de Kubernetes y cómo hacer peticiones a los endpoints REST expuestos en el Servicio del Pod para obtener información del Cluster.

Aplicación de ejemplo

Lo primero que haremos será crear una aplicación Spring Boot the ejemplo. Este es el fichero pom.xml que utilizaremos. Además de las dependencias estándar para Spring Boot, también debemos de incluir las dependencias de YAKC Kubernetes Client (y su api):

Ahora podemos declarar un Bean de KubernetesClient en la main class de nuestra aplicación (AccessClusterFromPodApplication):

Este Bean nos permitirá inyectar (autowire) la instancia compartida (singleton) de KubernetesClient al resto de componentes de la aplicación.

Cluster Service

Primero definiremos los distintos métodos que vamos a necesitar en la interfaz ClusterService. A continuación definiremos su implementación en la clase KubernetesClientClusterService.

El método más complejo de la clase es la implementación del método getDeploymentLogs. Este método se encarga de consultar y agregar las trazas (ordenadas por fecha/hora) de todos los Pods de un Deployment específico. Describiré con más detalle esta implementación debido a su complejidad. El resto de métodos deberían de ser evidentes en el código.

El método comienza creando un cliente para la API de Apps V1. Utilizaremos esta API para consultar información del Deployment correspondiente al nombre proporcionado en el namespace configurado.

A continuación emplearemos las entradas del campo spec.selector.matchLabels del Deployment obtenido para obtener la lista de Pods que concuerdan con este selector. Convertimos la lista de Pods en un Stream al que hacemos flatMap para mapearlos en un stream de entradas en el log de cada uno de los Pods. La implementación de este mapeo la vemos en el método getPodLog.

El método getPodLog utiliza la API Core V1 para leer las entradas de los logs de un determinado Pod incluyendo los timestamps. A continuación transformamos cada una de las trazas obtenidas para dividirlas por separadores de línea y así poder incluir el nombre del Pod en cada una de las líneas después del timestamp.

Finalmente, en el método getDeploymentLogs una vez el mapeo de los logs se ha completado, se ordenan las entradas y se combinan en un único String que será el resultado del método.

A pesar de la complejidad que supone transformar, combinar y ordenar las trazas de todos los Pods correspondientes a un Deployment, las interfaces declarativas y “streamable” de YAKC lo convierten en una tarea sencilla. La implementación resultante también es muy legible y se puede conseguir con muy pocas líneas de código.

Cluster Resource

En la clase ClusterResource puedes ver la implementación de los distintos endpoints REST que expondrá la aplicación. Esta clase es un RestController estándar de Spring. La clase contiene distintos métodos anotados con GetMapping que permiten consultar el nombre del namespace configurado, los Deployments y Pods en este namespace, así como las trazas agregadas de todos los Pods de un Deployment determinado.

Por ejemplo, para el método que he descrito en la sección anterior, podemos hacer una petición GET a http://cluster-ingress-url/deployments/deployment-name/logs y así obtener el Log agregado para el Deployment especificado:

Desplegando la aplicación en el Cluster

Una vez hemos destripado la aplicación y hemos visto como utilizar YAKC para interactuar con el Cluster, es el momento de desplegarla.

Lo primero que debemos hacer es configurar el cluster para permitir que el Pod pueda acceder a la API del cluster. Para ello debemos proporcionar acceso al service account por defecto del Pod. Esto lo podemos conseguir ejecutando el siguiente comando:

A partir de este momento, el service account por defecto (credenciales proporcionadas en la ruta /var/run/secrets/kubernetes.io/serviceaccount/token) del Pod podrá acceder a la API REST del cluster.

Eclipse JKube

Para desplegar la aplicación utilizaré el Kubernetes Maven Plugin de Eclipse JKube ya que nos permite desplegar cualquier aplicación Java con una mínima configuración.

Configuramos el plugin en la sección build del pom.xml:

He vinculado las tareas build, resource y apply del plugin a la fase package. Con esto conseguiremos que la imagen Docker de la aplicación de construya y despliegue en el cluster automáticamente cuando ejecutemos el comando mvn package.

También podéis observar que he añadido una configuración para los enrichers de JKube de manera que el Service generado sea de tipo NodePort.

Si vamos a desplegar la aplicación en Minikube, es conveniente compartir el acceso al Docker daemon de Minikube a nuestro sistema anfitrión. Esto nos permitirá no tener que publicar la imagen construida en un registro compartido.

  • eval $(minikube docker-env) on Linux
  • @FOR /f "tokens=*" %i IN ('minikube -p minikube docker-env') DO @%i on Windows

Una vez configurado el entorno, podemos proceder a desplegar la aplicación (mvn clean package):

Access Cluster From Pod JKube mvn package

Si todo ha ido bien, la aplicación debería de estar ahora desplegada. Si estamos utilizando Minikube, podemos probar los endpoints de la aplicación ejecutando los siguientes comandos:

Access Cluster From Pod curl

Conclusión

En esta publicación os he mostrado como podemos acceder con facilidad a la API REST de Kubernetes desde una aplicación Java corriendo en un Pod meidante YAKC (Yet Another Kubernetes Client). También os he mostrado como construir la imagen Docker de la aplicación y como desplegarla en el cluster con una mínima configuración empleando el Plugin de Maven para Kubernetes de Eclipse JKube.

Puedes encontrar el código fuente completo de este post en la sección quickstarts del repositorio de GitHub de YAKC.

YAKC - Yet Another Kubernetes Client

Dejar un Comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *