Todo lo que hemos dicho hasta ahora es acerca de stateless, stateless es realmente donde nuestras aplicaciones no se preocupan por qué red están utilizando y no necesitan ningún almacenamiento permanente. Mientras que las aplicaciones y bases de datos stateful, por ejemplo, para que dicha aplicación funcione correctamente, deberás asegurarte de que los pods puedan alcanzarse entre sí a través de una identidad única que no cambie (nombres de host, IP, etc.). Ejemplos de aplicaciones stateful incluyen clústeres MySQL, Redis, Kafka, MongoDB y otros. Básicamente, a través de cualquier aplicación que almacene datos.
StatefulSets representan un conjunto de Pods con identidades únicas y persistentes y nombres de host estables que Kubernetes mantiene independientemente de dónde se programen. La información de estado y otros datos resilientes para cualquier Pod dado de StatefulSet se mantienen en almacenamiento de disco persistente asociado con StatefulSet.
Algo que verás en nuestra demostración en breve es que cada pod tiene su propia identidad. Con una aplicación stateless, verás nombres aleatorios. Por ejemplo, `app-7469bbb6d7-9mhxd`, mientras que una aplicación stateful estaría más alineada con `mongo-0` y luego, cuando se escala, creará un nuevo pod llamado `mongo-1`.
Estos pods se crean a partir de la misma especificación, pero no son intercambiables. Cada pod de StatefulSet tiene un identificador persistente en cualquier reprogramación. Esto es necesario porque cuando requerimos cargas de trabajo stateful como una base de datos donde requerimos escribir y leer en una base de datos, no podemos tener dos pods escribiendo al mismo tiempo sin conciencia ya que esto nos dará inconsistencia de datos. Necesitamos asegurarnos de que solo uno de nuestros pods esté escribiendo en la base de datos en cualquier momento dado, sin embargo, podemos tener múltiples pods leyendo esos datos.
Cada pod en un StatefulSet tendría acceso a su volumen persistente y copia de réplica de la base de datos para leer, esto se actualiza continuamente desde el maestro. También es interesante destacar que cada pod almacenará su estado de pod en este volumen persistente, si luego `mongo-0` muere, cuando se provisione uno nuevo, tomará el estado de pod almacenado en el almacenamiento.
Mencionamos anteriormente que cuando tenemos una aplicación con estado, debemos almacenar el estado en algún lugar y aquí es donde surge la necesidad de un volumen. Por defecto, Kubernetes no proporciona persistencia.
Necesitamos una capa de almacenamiento que no dependa del ciclo de vida del pod. Este almacenamiento debe estar disponible y accesible desde todos los nodos de Kubernetes. El almacenamiento también debe estar fuera del clúster de Kubernetes para poder sobrevivir incluso si el clúster de Kubernetes falla.
En la sesión de ayer recorrimos la creación de una aplicación sin estado, ahora queremos hacer lo mismo pero utilizando nuestro clúster de minikube para implementar una carga de trabajo con estado.
Un resumen del comando de minikube que estamos utilizando para tener la capacidad y complementos para utilizar la persistencia es `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --Kubernetes-version=1.21.2`
Este comando utiliza el controlador CSI-hostpath-driver, que es lo que nos proporciona nuestra clase de almacenamiento, algo que mostraré más adelante.
Sin embargo, hay un paso más que debemos realizar antes de comenzar a implementar nuestra aplicación y es asegurarnos de que nuestra clase de almacenamiento (CSI-hostpath-sc) sea la predeterminada. Podemos verificar esto ejecutando el comando `kubectl get storageclass`, pero de forma predeterminada, el clúster de minikube mostrará la clase de almacenamiento estándar como predeterminada, por lo que debemos cambiarla con los siguientes comandos.
Luego implementaremos nuestro archivo YAML. `kubectl create -f pacman-stateful-demo.yaml`. Puedes ver que con este comando estamos creando varios objetos dentro de nuestro clúster de Kubernetes.
A continuación, puedes ver en la siguiente imagen y en el comando `kubectl get all -n pacman` que hay varias cosas sucediendo dentro de nuestro espacio de nombres. Tenemos nuestros pods ejecutando nuestra interfaz web NodeJS, tenemos mongo ejecutando nuestra base de datos de backend. Hay servicios tanto para Pacman como para mongo para acceder a esos pods. Tenemos una implementación para Pacman y un conjunto de estado para mongo.
También tenemos nuestro volumen persistente y la solicitud de volumen persistente mediante el comando `kubectl get pv` nos mostrará nuestros volúmenes persistentes sin espacio de nombres y ejecutando `kubectl get pvc -n pacman` nos mostrará nuestras solicitudes de volumen persistente con espacio de nombres.
Debido a que estamos utilizando Minikube, como se mencionó en la aplicación sin estado, tenemos algunos obstáculos para acceder a nuestra aplicación. Sin embargo, si tenemos acceso a un Ingress o a un balanceador de carga dentro de nuestro clúster, el servicio está configurado para obtener automáticamente una dirección IP de ellos para acceder externamente (puedes ver esto arriba en la imagen de todos los componentes en el espacio de nombres de Pacman).
Para esta demostración, vamos a utilizar el método de "port forwarding" para acceder a nuestra aplicación. Abriendo una nueva terminal y ejecutando el siguiente comando `kubectl port-forward svc/pacman 9090:80 -n pacman`, al abrir un navegador ahora tendremos acceso a nuestra aplicación. Si estás ejecutando esto en AWS u otras ubicaciones específicas, también se mostrará la nube y la zona, así como el host que corresponde a tu pod dentro de Kubernetes, nuevamente puedes volver atrás y ver este nombre de pod en nuestras capturas de pantalla anteriores.
¡Ok, genial! Tenemos una puntuación alta, pero ¿qué sucede si eliminamos nuestro pod `mongo-0`? ejecutando `kubectl delete pod mongo-0 -n pacman` puedo eliminarlo y si aún estás en la aplicación, verás que la puntuación alta no estará disponible, al menos por unos segundos.
Ahora, si vuelvo a mi juego, puedo crear un nuevo juego y ver mis puntuaciones altas. La única forma en que realmente puedas creerme es si lo intentas tú mismo y compartes tus puntuaciones altas en las redes sociales.
Con la implementación, podemos aumentar la escala utilizando los comandos que vimos en la sesión anterior, pero en particular aquí, especialmente si quieres organizar una gran fiesta de Pacman, puedes escalar esto usando `kubectl scale deployment pacman --replicas=10 -n pacman`
Hasta ahora, con nuestros ejemplos, hemos utilizado "port-forward" o hemos utilizado comandos específicos dentro de Minikube para acceder a nuestras aplicaciones, pero esto no funcionará en producción. Queremos una mejor forma de acceder a nuestras aplicaciones a gran escala con múltiples usuarios.
Ingress nos proporciona una mejor forma de exponer nuestras aplicaciones, lo cual nos permite definir reglas de enrutamiento dentro de nuestro clúster de Kubernetes.
Si estás utilizando un proveedor de servicios en la nube que ofrece Kubernetes administrado, es muy probable que tengan su opción de Ingress para tu clúster o te proporcionen su opción de balanceador de carga. No necesitas implementar esto tú mismo, es uno de los beneficios de Kubernetes administrado.
Ahora debemos crear nuestra configuración YAML de Ingress para acceder a nuestro servicio Pacman. He agregado este archivo al repositorio [pacman-ingress.yaml](Kubernetes)
Luego se me informa que, debido a que estamos utilizando Minikube en WSL2 en Windows, debemos crear el túnel de Minikube usando `minikube tunnel --profile=mc-demo`
Si alguien lo ha logrado o puede hacerlo funcionar en Windows y WSL, agradecería los comentarios. Abriré un problema en el repositorio para esto y volveré a él una vez que tenga tiempo y una solución.
ACTUALIZACIÓN: Siento que este blog ayuda a identificar quizás la causa de que esto no funcione con WSL [Configuring Ingress to run Minikube on WSL2 using Docker runtime](https://hellokube.dev/posts/configure-minikube-ingress-on-wsl2/)
Aquí concluye la sección de Kubernetes, hay mucho contenido adicional que podríamos ver sobre Kubernetes y 7 días nos brinda conocimientos fundamentales, pero hay personas que están pasando por [100DaysOfKubernetes](https://100daysofkubernetes.io/overview.html) donde se puede profundizar más.