A logo showing the text blog.marcnuri.com
English
Inicio»Proyectos personales»Isotope Mail: Cómo desplegar Isotope+Traefik en Kubernetes

Entradas Recientes

  • Fabric8 Kubernetes Client 7.2.0 está disponible!
  • Conectarse a un servidor MCP con JavaScript y AI SDK
  • Conectarse a un servidor MCP con JavaScript y LangChain.js
  • El Futuro de las Herramientas para Desarrolladores en la era de la IA
  • Conectarse a un servidor Model Context Protocol (MCP) con Java y LangChain4j

Categorías

  • Antiguo
  • Front-end
  • Go
  • Herramientas
  • Industria y negocios
  • Inteligencia Artificial
  • Java
  • JavaScript
  • Operaciones
  • Personal
  • Proyectos personales

Archivos

  • mayo 2025
  • abril 2025
  • marzo 2025
  • febrero 2025
  • enero 2025
  • diciembre 2024
  • noviembre 2024
  • agosto 2024
  • junio 2024
  • mayo 2024
  • abril 2024
  • marzo 2024
  • febrero 2024
  • enero 2024
  • diciembre 2023
  • noviembre 2023
  • octubre 2023
  • septiembre 2023
  • agosto 2023
  • julio 2023
  • junio 2023
  • mayo 2023
  • abril 2023
  • marzo 2023
  • febrero 2023
  • enero 2023
  • diciembre 2022
  • noviembre 2022
  • octubre 2022
  • agosto 2022
  • julio 2022
  • mayo 2022
  • marzo 2022
  • febrero 2022
  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021
  • diciembre 2020
  • octubre 2020
  • agosto 2020
  • junio 2020
  • mayo 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • noviembre 2019
  • octubre 2019
  • julio 2019
  • diciembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • marzo 2018
  • febrero 2018
  • noviembre 2017
  • octubre 2017
  • agosto 2017
  • julio 2017
  • enero 2017
  • julio 2016
  • enero 2016
  • diciembre 2015
  • noviembre 2015
  • diciembre 2014
  • marzo 2014
  • febrero 2011
  • junio 2008
  • mayo 2008
  • abril 2008
  • enero 2008
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007

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

2019-11-14 en Proyectos personales / Operaciones / Antiguo etiquetado Contenedores / DevOps / Docker / Correo Electrónico / Isotope Mail / Kubernetes / Correo / Traefik / Webmail por Marc Nuri | Última actualización: 2021-11-30
English version

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.

1---
2kind: ClusterRole
3apiVersion: rbac.authorization.k8s.io/v1beta1
4metadata:
5  name: traefik-ingress-controller
6rules:
7  - apiGroups:
8      - ""
9    resources:
10      - services
11      - endpoints
12      - secrets
13    verbs:
14      - get
15      - list
16      - watch
17  - apiGroups:
18      - extensions
19    resources:
20      - ingresses
21    verbs:
22      - get
23      - list
24      - watch
25  - apiGroups:
26      - extensions
27    resources:
28      - ingresses/status
29    verbs:
30      - update
31---
32kind: ClusterRoleBinding
33apiVersion: rbac.authorization.k8s.io/v1beta1
34metadata:
35  name: traefik-ingress-controller
36roleRef:
37  apiGroup: rbac.authorization.k8s.io
38  kind: ClusterRole
39  name: traefik-ingress-controller
40subjects:
41  - kind: ServiceAccount
42    name: traefik-ingress-controller
43    namespace: kube-system
44---
45apiVersion: v1
46kind: ServiceAccount
47metadata:
48  name: traefik-ingress-controller
49  namespace: kube-system

traefik.rbac.yaml

1kubectl apply -f https://raw.githubusercontent.com/manusa/isotope-mail/master/deployment-examples/k8s/traefik.rbac.yaml
Kubectl Isotope Traefik RBAC
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).

1---
2kind: DaemonSet
3apiVersion: apps/v1
4metadata:
5  name: traefik-ingress-controller
6  namespace: kube-system
7  labels:
8    k8s-app: traefik-ingress-lb
9spec:
10  selector:
11    matchLabels:
12      k8s-app: traefik-ingress-lb
13  template:
14    metadata:
15      labels:
16        k8s-app: traefik-ingress-lb
17        name: traefik-ingress-lb
18    spec:
19      serviceAccountName: traefik-ingress-controller
20      terminationGracePeriodSeconds: 60
21      containers:
22        - image: traefik:v1.7
23          name: traefik-ingress-lb
24          ports:
25            - name: http
26              containerPort: 80
27              hostPort: 80
28            - name: admin
29              containerPort: 8080
30              hostPort: 8080
31          securityContext:
32            capabilities:
33              drop:
34                - ALL
35              add:
36                - NET_BIND_SERVICE
37          args:
38            - --api
39            - --kubernetes
40            - --logLevel=INFO
41---
42kind: Service
43apiVersion: v1
44metadata:
45  name: traefik-ingress-service
46  namespace: kube-system
47spec:
48  selector:
49    k8s-app: traefik-ingress-lb
50  ports:
51    - protocol: TCP
52      port: 80
53      name: web
54    - protocol: TCP
55      port: 8080
56      name: admin

traefik.ds.yaml

1kubectl apply -f https://raw.githubusercontent.com/manusa/isotope-mail/master/deployment-examples/k8s/traefik.ds.yaml
Kubectl Isotope Traefik DaemonSet
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.

1---
2apiVersion: v1
3kind: Service
4metadata:
5  name: traefik-web-ui
6  namespace: kube-system
7spec:
8  selector:
9    k8s-app: traefik-ingress-lb
10  ports:
11    - name: web
12      port: 80
13      targetPort: 8080
14---
15apiVersion: extensions/v1beta1
16kind: Ingress
17metadata:
18  name: traefik-web-ui
19  namespace: kube-system
20spec:
21  rules:
22    - host: traefik-ui.minikube
23      http:
24        paths:
25          - path: /
26            backend:
27              serviceName: traefik-web-ui
28              servicePort: web

traefik.ui.yaml

1kubectl apply -f https://raw.githubusercontent.com/manusa/isotope-mail/master/deployment-examples/k8s/traefik.ui.yaml
Kubectl Isotope Traefik web UI
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
Traefik Web UI Dashboard

Isotope

El último paso del tutorial es desplegar Isotope.

1---
2apiVersion: v1
3kind: Secret
4metadata:
5  name: isotope-secrets
6type: Opaque
7data:
8  encryptionPassword: U2VjcmV0SzhzUGFzd29yZA==
9---
10kind: Deployment
11apiVersion: apps/v1
12metadata:
13  name: isotope-server
14  labels:
15    app: isotope
16    component: server
17spec:
18  replicas: 1
19  selector:
20    matchLabels:
21      app: isotope
22      component: server
23      version: latest
24  template:
25    metadata:
26      labels:
27        app: isotope
28        component: server
29        version: latest
30    spec:
31      containers:
32        - name: isotope-server
33          image: marcnuri/isotope:server-latest
34          imagePullPolicy: Always
35          ports:
36            - containerPort: 9010
37          env:
38            - name: ENCRYPTION_PASSWORD
39              valueFrom:
40                secretKeyRef:
41                  name: isotope-secrets
42                  key: encryptionPassword
43          livenessProbe:
44            httpGet:
45              path: /actuator/health
46              port: 9010
47            failureThreshold: 6
48            periodSeconds: 5
49          # Use startupProbe instead if your k8s version supports it
50            initialDelaySeconds: 60
51          readinessProbe:
52            httpGet:
53              path: /actuator/health
54              port: 9010
55            failureThreshold: 2
56            periodSeconds: 5
57#          startupProbe:
58#            httpGet:
59#              path: /actuator/health
60#              port: 9010
61#            initialDelaySeconds: 20
62#            failureThreshold: 15
63#            periodSeconds: 10
64---
65kind: Deployment
66apiVersion: apps/v1
67metadata:
68  name: isotope-client
69  labels:
70    app: isotope
71    component: client
72spec:
73  replicas: 1
74  selector:
75    matchLabels:
76      app: isotope
77      component: client
78      version: latest
79  template:
80    metadata:
81      labels:
82        app: isotope
83        component: client
84        version: latest
85    spec:
86      containers:
87        - name: isotope-client
88          image: marcnuri/isotope:client-latest
89          imagePullPolicy: Always
90          ports:
91            - containerPort: 80
92          livenessProbe:
93            httpGet:
94              path: /favicon.ico
95              port: 80
96            failureThreshold: 6
97            periodSeconds: 5
98---
99apiVersion: v1
100kind: Service
101metadata:
102  name: isotope-server
103spec:
104  ports:
105    - name: http
106      targetPort: 9010
107      port: 80
108  selector:
109    app: isotope
110    component: server
111---
112apiVersion: v1
113kind: Service
114metadata:
115  name: isotope-client
116spec:
117  ports:
118    - name: http
119      targetPort: 80
120      port: 80
121  selector:
122    app: isotope
123    component: client
124---
125apiVersion: extensions/v1beta1
126kind: Ingress
127metadata:
128  name: isotope
129  annotations:
130    kubernetes.io/ingress.class: traefik
131    traefik.frontend.rule.type: PathPrefixStrip
132spec:
133  rules:
134    - host: isotope.minikube
135      http:
136        paths:
137          - path: /
138            backend:
139              serviceName: isotope-client
140              servicePort: http
141          - path: /api
142            backend:
143              serviceName: isotope-server
144              servicePort: http

isotope.yaml

1kubectl apply -f https://raw.githubusercontent.com/manusa/isotope-mail/master/deployment-examples/k8s/isotope.yaml
Kubectl Isotope Mail Client
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 con Isotope

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 Isotope
Traefik Dashboard with Isotope

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 en Kubernetes
Isotope en Kubernetes
Isotope + Kubernetes
Isotope + Kubernetes
Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Navegador de artículos
Quarkus + Fabric8 Maven Plugin + GraalVMFedora: Cómo instalar el entorno de escritorio Cinnamon
© 2007 - 2025 Marc Nuri