Ciclo de vida de un contenedor en Kubernetes
Objetivos del capítulo y requisitos previos
Los capítulos anteriores han cubierto muchas de las nociones del uso de Kubernetes, a través de la implementación de la aplicación MailHog. Esta aplicación se ha implementado de varias maneras:
-
Manualmente, usando el dashboard de Kubernetes.
-
A través de la creación de objetos, usando kubectl.
-
Por último, utilizando archivos de definición de los elementos por crear.
Este capítulo se centrará en el ciclo de vida de un contenedor a través de dos aspectos:
-
La correspondencia entre un pod y su contenedor a nivel del motor Docker.
-
El mecanismo de seguimiento de contenedores.
Gestión de los crashs de la aplicación
1. Consultar el estado de los pods
La aplicación MailHog desplegada en Kubernetes actualmente no está supervisada. Lo único que hace Kubernetes es asegurarse de que el contenedor funcione correctamente.
Una buena manera de comprobar esto es conectarse al contenedor asociado a la aplicación MailHog, matar el proceso de MailHog y ver cómo aumenta el contador de inicio.
A continuación, se muestra el comando que permite verificar el estado de los pods de la aplicación, que llevan la etiqueta app=mailhog:
$ kubectl get pods -l app=mailhog
He aquí el resultado de este comando:
NAME READY STATUS RESTARTS AGE
mailhog-5c76b9bb6c-hc7s8 1/1 Running 0 3m31s
2. Conexión al pod
La conexión a un pod se realiza con el comando kubectl, seguido de estos parámetros:
-
La palabra clave exec.
-
La opción para indicar que se trata de una conexión interactiva (-i).
-
La opción para asignar un terminal (tty) a la conexión (-t).
-
El nombre del pod (ver comando anterior) o una referencia al objeto de despliegue (deployment/mailhog).
-
El indicador de opciones de kubectl (--).
-
El comando que se debe lanzar: sh para un shell.
En resumen, el comando que se debe lanzar será el siguiente:
$ kubectl exec -it deployment/mailhog - sh
Una vez proyectado en el contexto del contenedor MailHog, es posible consultar la lista de procesos presentes con el comando ps, seguido de la opción -ef:
$ ps -ef
Este comando devuelve la lista de los procesos presentes en el contenedor:
PID USER TIME COMMAND
1 mailhog 0:00 MailHog
13 mailhog 0:00 sh
22 mailhog 0:00 ps -ef
Además de los procesos 13 y 22, que se corresponden con el shell y el comando ps, el único proceso presente es el de MailHog que lleva el número 1.
Antes de eliminar el proceso de MailHog, se creará un directorio de prueba...
Estado de un contenedor
1. ¿Por qué supervisar el estado de un contenedor?
Un proceso detenido es la señal innegable de que una aplicación no está disponible. Sin embargo, lo contrario no es necesariamente cierto. De hecho, un proceso, incluso si se inicia, puede estar:
-
en un estado congelado,
-
o en un bucle infinito,
-
o en un estado saturado.
Una buena práctica consiste en ir más allá de la simple verificación de la presencia de un proceso realizando pruebas de aplicación.
Por supuesto, estas pruebas dependerán en gran medida del tipo de aplicación y de lo que el administrador esté dispuesto a implementar. Se debe tener en cuenta la relación coste/beneficio, ya sea en términos de consumo de recursos o del desarrollo que se ha de realizar para establecer esta supervisión. Estas pruebas pueden ser de varios tipos (de más sencillas a más complicadas):
-
Supervisar la presencia de un puerto de escucha.
-
Supervisar la presencia de un archivo.
-
Realizar una conexión HTTP.
-
Conectarse a una base de datos.
-
Acceder a una página de diagnóstico.
2. Readiness vs Liveness
Kubernetes permite definir dos tipos de monitoreo en un contenedor:
-
Pruebas «readiness», que permiten saber si un contenedor está listo (¿está iniciado? ¿Están listas sus dependencias?).
-
Pruebas «liveness», que permiten saber si un contenedor todavía es utilizable (¿tiene suficiente memoria? ¿Responde siempre a tiempo?).
En el caso de una prueba «readiness» negativa, el contenedor se eliminará del tráfico, pero no se borrará. Una prueba de tipo «liveness» negativa tendrá consecuencias más serias para el contenedor. En caso de error, este último se detendrá para ser sustituido por uno nuevo.
Además de estas dos pruebas, se utiliza una prueba adicional durante el arranque del contenedor «startupProbe». Una vez que se devuelve un resultado válido, las otras dos pruebas toman el relevo. Se recomienda utilizar este campo para contenedores con una fase de puesta en marcha prolongada.
3. Utilización y buena práctica
Las pruebas de liveness no deben depender de otros componentes. De hecho, en caso de no disponibilidad de un componente externo (base de datos o dependencias de...
Definición de la capacidad de un pod
1. ¿Por qué definir una capacidad?
Hasta ahora, los pods desplegados nunca han estado limitados en su consumo. Si un pod comienza a entrar en un bucle infinito o consume todos los recursos de memoria a la vez, puede afectar al resto de los pods del mismo nodo.
La definición de la capacidad de un pod permite evitar este consumo excesivo. En el caso de la CPU, el pod simplemente se limitará al consumo máximo asignado. El programa solo se verá afectado en aquel que vaya más lento. Por otro lado, un consumo excesivo de memoria dará como resultado la finalización del proceso a través del mecanismo de OOM Killer (Out-Of-Memory Killer) del kernel Linux.
2. Reserva y sobreasignación
En cuanto a los límites, hay dos: un valor reservado y un valor máximo. El primero reservará el recurso y el segundo permitirá exceder temporalmente esta reserva.
Tenga cuidado de no jugar demasiado con estos límites. Una máquina en la que el recurso de memoria está sobreasignado más allá de un cierto límite puede provocar crashes o un comportamiento errático.
Otro punto importante es que el recurso de la CPU es mucho más propenso que la memoria a ser sobreasignado. Por supuesto, manténgase dentro de lo razonable en términos de esta sobreasignación.
3. Asignación de recursos a un contenedor
Para el resto del capítulo, los ejemplos se tomarán con la aplicación MailHog previamente implementada.
En un despliegue, la asignación de recursos se realiza a nivel del campo spec --> containers --> resources de un pod. Este campo acepta dos registros:
-
El campo limits para definir el consumo máximo de un contenedor.
-
El campo request para definir la reserva de recursos.
Estos dos campos reciben las mismas opciones como parámetros:
-
El campo memory, con la cantidad de memoria que hay que utilizar.
-
El campo cpu, con la cantidad de CPU que hay que asignar.
Respecto al contenido de estos campos, preste atención a la interpretación automática que realiza YAML:
-
Un valor de 1 se interpretará como un número.
-
Una cadena de 0,5 se interpretará como un número en coma flotante.
Para Kubernetes, estos campos deben tener obligatoriamente forma de cadena de caracteres. Añada...