Introducción

Si te dedicas al mundo del desarrollo es posible que estes cansado de escuchar está palabra, ¿pero por qué esta tecnología está en boca de todos? ¿qué la hace tan atractiva? En este post partimos de cero y te vamos a contar en que consiste Kubernetes.

¿Qué tengo que saber?

Para poder seguir este post, tienes que tener conceptos básicos de tecnología de contenedores (Docker), si no estas familiarizados con esto puedes leer nuestro post introductorio Hola Docker

Pongamonos en contexto...

Todo comienza con un contenedor. La manera más sencilla de entender un contenedor, es que se trata de software que corre de manera independiente. Por ejemplo, digamos que quiero probar Mongo. Tradicionalmente, lo que haría, es irme a la página oficial, descargar los binarios, instalarlos, comprobar que mi instalación ha sido correcta; si no ha sido correcta, aplicar las modificaciones necesarias dependiendo de mi configuración y sistema operativo, volver a comprobar que el software corre como esperamos; si no vuelta a empezar...

Flujo tradicional instalación MongoDB

Flujo tradicional instalación MongoDB

Si por el contrario utilizo un contenedor, los pasos a seguir se simplifican, imaginemos que queremos instalar el motor de base de datos de mongo, podríamos proceder de la siguiente forma:

  • Descargo la `plantilla` de Mongo.

  • Creo una nueva instancia (contenedor) de Mongo a partir de la `plantilla` descargada

  • Me conecto a Mongo

Tirando de MongoDB Dockerizado

Tirando de MongoDB Dockerizado

Vale, la aproximación a través de contenedores es mucho más sencilla, y punto a parte ¿por qué no utilizar Máquinas Virtuales par esto? Bueno básicamente un contenedor es mucho más ligero. Si quieres ver esto en más detalle puedes consultar nuestro artículo Hola Docker.

Al igual que hemos descargado un `plantilla` de Mongo, y lo hemos ejecutado en nuestras máquinas, de manera independiente, también podemos hacer lo mismo con nuestras aplicaciones, es lo que se conoce como contenerizar una aplicación.

Nuestras aplicaciones pueden estar constituidas por multiples subaplicaciones, por ejemplo una aplicación simple, se podría componer de las siguientes subaplicaciones:

  • Una aplicación que hace de balanceador de carga

  • Una aplicación que sirva los ficheros estáticos

  • Una aplicación que sirva datos a través de una API

  • Una aplicación que de persistencia a los datos (una base de datos)

Aplicación con un frontal web, api rest y base de datos

Aplicación con un frontal web, api rest y base de datos

Simplemente, sustituyamos aplicación por contenedor..., y voila, ya tenemos una aplicación contenerizada. Una duda razonable es… ¿Cómo vamos a gestionar todas estas aplicaciones? Se hace preciso un buen timonel, para que nuestras contenedores lleguen a buen puerto.

Kubernetes

La definición oficial de Kubernetes: Kubernetes (K8s) is an open-source system for automating deployment, scaling, and management of containerized applications.

Básicamente nos va a permitir gestionar nuestras aplicaciones basadas en contenedores. Pero aunque resulte ingenuo ¿que es lo que tenemos que gestionar? Yo tengo mis contenedores, los despliego en un servidor y a volar ¿no? Bueno, ¿qué ocurre si uno o varios de nuestros contenedores se caen? Necesitamos tener un proceso que pueda monitorizar esos contenedores y devolverlos a la vida.

Vayamos un poco más lejos, ¿cómo hacemos que estos contenedores se comuniquen entre si? Si estamos usando _Docker_, podemos establecer una red interna usando docker-compose, pero está tecnología no estaba pensada para esto, en cuanto introduzcamos más de un servidor en la ecuación nos vamos a encontrar con un montón de obstáculos.

Además ¿Qué ocurre cuando queramos escalar nuestra aplicación?, ¿Que ocurre si queremos que el sistema sea resilente, nos permita añadir nuevos servidores...?

No sería estupendo si:

  • Contamos con un proceso que gestione nuestra aplicación de contenedores de manera independiente.

  • Nos podemos olvidar de la gestión de estos contenedores.

  • Eliminamos puntos de posibles fallos

  • Podemos escalar contenedores de manera fácil.

  • Podemos actualizar contenedores sin detener la aplicación.

  • Contar con una red robusta para nuestros contenedores.

  • Podemos tener opciones de persistencia de datos.

Kubernetes, es nuestro ansiado timonel, algunas de sus características:

  • Detección de servicios / Balanceo de carga - Acceso a los servicios a través de etiquetas y balanceo de carga a las distintas instancias de un servicio.

  • Rollouts / Rollbacks automatizados

  • Despliegues de nuevas versiones, y capacidad de volver a la versión anterior.

  • Auto reparación: cuando una instancia no esta 'saludable', la eliminará y la reemplazará por una nueva.

  • Gestión y configuración de secretos - Passwords, cadenas de conexión...

  • Escalado horizontal: capacidad para crear nuevas instancias de nuestras aplicaciones dentro del clúster

Hablando en claro... Kubernetes nos va a permitir gestionar nuestras aplicaciones basadas en contenedores. ¿Pero qué entendemos por gestionar?, cuando por ejemplo te llevas un sistema basado en microservicios o aplicaciones modulares de complejidad media/alta a producción, tu quieres:

  • Poder detectar sobrecarga en las aplicaciones y que autoescale.

  • Simplificar la gestión de comunicaciones / red de esa infraestructura.

  • Poder hacer subidas a producción sin tener que parar el sistema.

  • Poder hacer subidas a producción parciales, que n usuarios de tu sistema usen la versión nueva y el resto sigan con la antigua, pudiendo así detectar rápidamente si tu nueva versión funciona bien y en caso de que no poder deshacer los cambios con un impacto mínimo en tu negocio.

  • Optimizar tu inversión en infraestructura, no gastar más dinero de la cuenta en hierro, ni tener servidores sobrecargados y otros muertos de risa.

¿Pero cómo puede hacer este trabajo nuestro timonel?

La definición de Kubernetes, nos indica que es un sistema para orquestar contenedores. Para realizar esta orquestación, el sistema se subdivide en distintos componentes, capaces de proveer las distintas funcionalidades expuestas anteriormente.

Antes de continuar, cuando hablamos de un sistema en Kubernetes nos referimos a un clúster, es decir: una agrupación lógica de máquinas físicas o virtuales. Cuando nos referimos a una de esas máquinas físicas o virtuales en el lenguaje de Kubernetes nos referimos a un nodo.

Estos nodos los podemos dividir en dos:

  • Nodos maestros: se encargan de la gestión de los nodos trabajadores que existen dentro del clúster. Estos nodos (máquinas) integran lo que se conoce como el plano de control.

  • Nodos trabajadores: se encarga de ejecutar las "aplicaciones".

control plane / nodes

control plane / nodes

Analicemos las distintas partes que integran el plano de control:

  1. Store (etcd): Se encuentra dentro de los nodos _maestro_, y podemos pensar en el _store_ como una especie de base de datos, para todo lo que necesita observar dentro del cluster el plano de control

  2. Controller manager: Es el responsable de que cuando llegue una nueva petición, actuar sobre la misma y planificarla usando el _scheduler_

  3. Scheduler: El scheduler determina cuando los nodos, y los diferentes objetos de Kubernetes que están corriendo dentro de esos nodos nacen o mueren.

  4. API Server: Podemos interactuar con el plano de control lanzando instrucciones, para que nuestro clúster pase de un estado con `n` objetos a otro estado con `m` objetos, usando la línea de comandos kubectl. Es importante destacar que se trata de un servicio REST. Por ejemplo, si ejecutamos `kubectl create -f ./pod.json` mandamos al API server la petición para crear lo que contenga el fichero `pod.json`, o si ejecutamos por ejemplo `kubectl get pods` estamos mandando una petición al API server para que nos devuelva un listado de los pods.

Ahora que tenemos una idea de que partes componen el plano de control, pasemos a analizar las partes que componen un nodo trabajador.

Worker node

Worker node

  1. Pod: La unidad mínima que podemos crear y gestionar en Kubernetes. Un Pod es un grupo de uno o más contenedores que comparten almacenamiento y recursos de red, y una especificación de cómo correr los contenedores que componen una aplicación. Cómo simplificación exagerada, la manera más sencilla de arrancar, es pensar en la relación un pod un contenedor.

  2. Kubelet: Cada nodo precisa de comunicación bidireccional con el _master_. Para tal fin, los nodos tienen un _agente_ ligero instalado, y que registra ese nodo con el cluster para llevar acabo esa comunicación.

  3. Container Runtime: Dentro de los nodos, van a existir pods y necesitamos un runtime que sea capaz de ejecutar los contenedores dentro estos pods.

  4. Kube proxy: En los nodos vamos a necesitar capacidades de red, _kube proxy_ nos asegura que cada nodo tome una dirección IP única dentro del cluster.

node

node

Conclusiones

En este artículo hemos visto qué ventajas nos ofrece Kubernetes, desde un punto de vista del desarrollador, y las posibilidades que nos brinda. Además, hemos comenzado a entender las distintas partes que componen Kubernetes, y hemos visto a alto nivel como interactúan entre ellas.


¡Conocer al timonel es esencial para decidir si dejamos que lleve a buen puerto nuestros contenedores!

Siguientes pasos

Ahora que tenemos una idea aproximada de las distintas partes que componen Kubernetes lo mejor es pasar a la acción, en nuestro siguiente post nos pondremos manos a la obra.

¿Te gusta el mundo Devops?

En Lemoncode impartimos un Bootcamp Devops Online, en el encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Devops.