Isotope Mail: Cómo desplegar Isotope+Traefik en Kubernetes


Introducción

Isotope mail client es una aplicación webmail de código libre y uno de los proyectos personales en los que he invertido más tiempo durante el pasado año. Puedes leer más información acerca de las funcionalidades de Isotope en una publicación anterior.

A pesar de que todavía no hay una versión oficial, la aplicación está bastante estable. En este post describiré la forma en la que se puede desplegar Isotope un un clúster de Kubernetes. En el tutorial se ha empleado minikube + kubectl, pero los mismos pasos podrían reproducirse en un clúster de K8s en producción.

Traefik v1

Pese a que no forma parte de la implementación, Traefik (o cualquiera de sus alternativas) es una pieza fundamental del despliegue ya que actuará como API gateway (reverse-proxy) enrutando cada una delas peticiones al componente/servicio pertinente de Isotope.

El primer paso es crear un Ingress controller para Traefik (en el caso en el que todavía no haya ninguno en el clúster). Seguiremos la documentación oficial de Traefik para crear el nuevo Ingress controller.

Role Based Access Control configuration (Sólo Kubernetes 1.6+)

A partir de la versión 1.6 de Kubernetes, se ha introducido Role Based Access Control (RBAC) para permitir un control de acceso más granular a recursos basándose en los roles de usuarios individuales.

Para permitir que Traefik pueda acceder a la API global de Kubernetes es necesario crear un ClusterRole y un ClusterRoleBinding.

traefik.rbac.yaml

Kubectl Isotope Traefik RBAC

Desplegar Traefik empleando un DaemonSet

El siguiente paso es desplegar el ingress controller de Traefik utilizando un DaemonSet.

Si seguimos la documentación oficial de Traefik’, veremos que este paso también se puede conseguir empleando un Deployment. Para este tutorial y debido a que estamos usando Minikube, utilizaremos un DaemonSet ya que es más fácil de configurar y exponer con Minikube (Minikube tiene problemas a la hora de asignar IPs externas a un Ingress que utilice un Ingress controller de Traefik desplegado con un Deployment).

traefik.ds.yaml

Kubectl Isotope Traefik DaemonSet

Traefik UI

De forma opcional podemos crear un Servicio y un Ingress para el dashboard de Traefik para poder monitorizar el despliegue del nuevo DaemonSet.

traefik.ui.yaml

Kubectl Isotope Traefik web UI

Es importante resaltar que para la configuración del Ingress estamos empleando traefik-ui.minikube como el host público. En un entorno de producción deberíamos de añadir el hostname real. En este sentido, en nuestro entorno de desarrollo, es necesario añadir la IP de nuestro clúster de Kubernetes local (minikube ip / kubectl get ingress) en nuestro fichero de hosts del sistema (/etc/hosts).

Por último, podemos apuntar nuestro navegador hacia traefik-ui.minikube  y cargar el dashboard de Traefik.

Traefik Web UI Dashboard

Isotope

El último paso del tutorial es desplegar Isotope.

isotope.yaml

Kubectl Isotope Mail Client

Secret

La primera entrada en la configuración Yaml es un Kubernetes secret codificado en Base64 que se utilizará para configurar la clave simétrica de encriptado del componente Isotope Server.

Isotope Server Deployment

La siguiente entrada en el Yaml es la configuración del Deployment para el componente Isotope Server. Debido a que este deployment es más complejo que el del componente Client, la configuración común de ambos componentes se describirá en la siguiente sección (Isotope Client Deployment).

En la sección env, declaramos la variable de entrono ENCRYPTION_PASSWORD y le asignamos el valor del Secret que hemos declarado en el paso anterior. Esta variable estará disponible para todos los Pods creados por Kubernetes a partir de la configuración de este Deployment, por tanto, todos los Pods compartirán la misma clave de encriptado y serán compatibles entre sí.

También definiremos dos probes de manera que Traefik y Kubernetes sepan cuándo los Pods del componente Isotope Server están listos y ya se puede enrutar tráfico hacia ellos. Liveness probe se empleará para determinar si el contenedor sigue “vivo”. En caso contrario, Kubernetes reiniciará el Pod ya que el estado de la aplicación se considerará “roto”. También vamos a utilizar la propiedad initialDelaySeconds ya que Isotope Server tarda varios segundos en arrancar, de este modo podremos evitar falsos positivos. En este sentido, si la versión de Kubernetes del clúster lo soporta, es preferible definir un Startup probe (adicional) y evitar configurar la propiedad initialDelaySeconds ya que su resultado no es determinista (la aplicación podría tardar algo más en arrancar de lo especificado).

También hemos definido un Readiness probe en esta sección. Esta sonda es similar al Liveness probe y se empleará para indicar si la aplicación esta disponible para recibir tráfico. Si por cualquier razón la aplicación no admite tráfico (número máximo de conexiones, etc.) la sonda marcará el Pod como “down” pero, a diferencia de la anterior, Kubernetes no lo reiniciará.

Para ambas sondas estamos utilizando una petición HTTP apuntando al endpoint de “health check” de Spring Actuator configurado en el componente Isotope Server.

Isotope Client Deployment

Del mismo modo que hemos hecho para el componente Servidor, ahora definiremos un Deployment para el componente Client de Isotope.

En la sección spec definimos el número de réplicas que queremos de nuestros Pods, en este caso, una. La propiedad selector, aunque opcional en versiones anteriores del API, ahora es obligatoria y se empleará por Kubernetes para determinar el número de Pods que hay actualmente en ejecución y arrancar más réplicas si es necesario (deberán coincidir con las “labels” de la sección template).

La propiedad template dentro de la sección spec se utiliza para definir las especificaciones de los Pod. Para Isotope Cliente estamos deifiniendo un Pod de un único contenedor basado en la imagen Docker marcnuri/isotope:client-latest y exponiendo el puerto Http.

De igual forma que para del Deployment de Isotope Server, definimos un Liveness probe para identificar si el Pod está inestable y estado “roto” para que Kubernetes pueda reiniciarlo de forma automática.

Services

La siguiente sección de la configuración Yaml define un Service para cada uno de los Deployments (server/client) de forma que estos queden expuestos al clúster.

Para facilitar la definición del Ingress en el siguiente paso, ambos servicios expondrán el puerto Http (80).

Ingress

La última sección de la configuración define un Ingress empleando el Ingress Controller que hemos desplegado en los primeros pasos del tutorial.

Vamos a emplear isotope.minikube como public host, aunque cómo ya se ha mencionado antes, en un entorno de producción deberíamos de utilizar un hostname real (al igual que antes, tendremos que añadir una nueva entrada en el fichero de hosts del sistema /etc/hosts).

La configuración especifica que todo el tráfico que llegue hasta http://isotope.minikube/api debe ser enrutado por Traefik al servicio isotope-server, y todo el que llegue a http://isotope.minikube/ al servicio isotope-client.

La entradatraefik.frontend.rule.type: PathPrefixStrip en la configuración quita  /api del path en las peticiones al servicio isotope-server, de este mode, no hay que modificar ni añadir configuraciones extra al componente Isotope Server para que sea compatible con nuestro despliegue.

Traefik dashboard conIsotope

Una vez la configuración de Isotope se haya desplegado, el dashboard de Traefik se actualizará automáticamente y mostrará las nuevas rutas para Isotope.

Traefik Dashboard with Isotop

Isotope deployment

Si todo ha ido correctamente el dashboard de Traefik mostrará los componentes de Isotope en estado healthy y podremos apuntar nuestro navegador a http://isotope.minikube dónde Isotope estará listo y disponible.

Isotope in Kuberentes

Isotope + Kuberentes

Dejar un Comentario

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