Después de estabilizar el clúster, el siguiente paso es poner en marcha aplicaciones. Pero ¿qué es exactamente lo que hay que desplegar?: ¿pods?, ¿replication controllers?, ¿deployments?

Muchos artículos empiezan creando el fichero YAML para un pod, después construyen el replication controller, etc… Sin embargo, revisando la documentación oficial, crear pods directamente en Kubernetes no tiene mucho sentido.

En este artículo intento determinar qué objetos son los que deben crearse en un clúster Kubernetes.

Pod

La unidad fundamental de despliegue en Kubernetes es el Pod. Un pod sería el equivalente a la mínima unidad funcional de la aplicación.

En general, un pod contendrá únicamente un contenedor, aunque no tiene que ser así: si tenemos dos contenedores que actúan de forma conjunta, podemos desplegarlos dentro de un solo pod. Dentro de un pod todos los contenedores se pueden comunicar entre ellos usando localhost, por lo que es una manera sencilla de desplegar en Kubernetes aplicaciones que, aunque hayan sido containerizadas, no puedan modificarse para comunicarse con otras partes de la aplicación usando una IP o un nombre DNS (porque la aplicación espera que el resto de partes de la aplicación estén en el mismo equipo).

En este sentido, todos los contenedores dentro de un pod se podría decir que están instaladas en una mismo equipo (como un stack LAMP).

Sin embargo, un pod es un elemento no-durable, es decir, que puede fallar o ser eliminado en cualquier momento. Por tanto, no es una buena idea desplegar pods individuales en Kubernetes.

Como indica la documentación para los pods de la API para la versión 1.6 de Kubernetes:

It is recommended that users create Pods only through a Controller, and not directly.

ReplicaSet y Replication Controller

El Replication Controller o la versión mejorada, el ReplicaSet se encarga de mantener un determinado número de réplicas del pod en el clúster.

El ReplicaSet asegura que un determinado número de copias -réplicas- del pod se encuentran en ejecución en el clúster en todo momento. Por tanto, si alguno de los pods es eliminado, el ReplicaSet se encarga de crear un nuevo pod. Para ello, el ReplicaSet incluye una plantilla con la que crear nuevos pods.

Así, el ReplicaSet define el estado deseado de la aplicación: cuántas copias de mi aplicación quiero tener en todo momento en ejecución en el clúster. Modificando el número de réplicas para el ReplicaSet podemos escalar (incrementar o reducir) el número de copias en ejecución en función de las necesidades.

Por tanto, parece que el mejor candidato para ponerse a definir ficheros YAML y desplegar aplicaciones en el clúster de Kubernetes sería un ReplicaSet.

Si embargo, la documentación oficial nos ofrece otra opción:

In many cases it is recommended to create a Deployment instead of ReplicaSet.

Es decir, tenemos una opción mejor: el Deployment.

Deployment

El Deployment añade la capacidad de poder actualizar la aplicación definida en un ReplicaSet sin pérdida de servicio, mediante actualización continua (rolling update).

Si el estado deseado de la aplicación son tres réplicas de un pod basado en yomismo/app-1.0 y queremos actualizar a yomismo/app-2.0, el Deployment se encarga de realizar la transición de la versión 1.0 a la 2.0 de forma que no haya interrupción del servicio. La estrategia de actualización puede definirse manualmente, pero sin entrar en detalles, Kubernetes se encarga de ir eliminado progresivamente las réplicas de la aplicación v1.0 y sustituirlas por las de la v2.0.

El proceso se hace de forma controlada, por lo que si surgen problemas con la nueva versión de la aplicación, la actualización se detiene y es posible realizar marcha atrás hacia la versión estable.

Resumiendo

Así pues, después de leer la sección de Concepts de la documentación de Kubernetes, parece que ya tengo claro cuál es el proceso para desplegar aplicaciones en Kubernetes.

  • En Docker
    1. Crear fichero Dockerfile
    2. Construir imagen personalizada
    3. Subir imagen a un Registry (de momento, DockerHub)
  • En Kubernetes
    1. Crear fichero YAML definiendo el Deployment
    2. Crear Deployment en el clúster

Hay otros objetos específicos que pueden ser más adecuados para tus necesidades:

  • DaemonSets : despliegan una copia de un pod en cada nodo del clúster. Por ejemplo, un antivirus, o una herramienta de gestión de logs, etc
  • Jobs y CronJobs: crean pods hasta asegurar que un número determinado finaliza con éxito, lo que completa el job.
  • StatefulSets : todavía en Beta, asignan una identidad única a los pods, lo que garantiza que se creen o escalen en un orden determinado.

Siguientes pasos

Al final de este proceso tendré una aplicación simple desplegada en el clúster. Con “sencilla” quiero decir que las diferentes instancias de la aplicación actuan de forma independiente. Un ejemplo sería un servidor web: con el deployment sería posible escalar la aplicación para dar respuesta a la demanda en todo momento y actualizar el contenido de la web sin interrupciones.

El siguiente paso es crear una aplicación compleja en la que tengamos, por ejemplo, un frontend y un backend. Para estas situaciones, necesitaremos definir un servicio.