sábado, 19 de mayo de 2018

Kubernetes [Best Practices ] apagando según el manual


Nota del editor: En Google Cloud Español seguimos con las entregas de  serie de videos y blogs en siete partes de Google Developer Advocate Sandeep Dinesh sobre cómo aprovechar al máximo su entorno de Kubernetes.

Cuando se trata de sistemas distribuidos, manejar los fallo sen muy importante. Kubernetes ayuda con esto al utilizar controladores que pueden ver el estado de su sistema y reiniciar los servicios que han dejado de funcionar. Por otro lado, Kubernetes a menudo puede terminar su aplicación a la fuerza como parte del funcionamiento normal del sistema.

En este episodio de "Kubernes best Practices", veamos cómo puede ayudar a Kubernetes a hacer su trabajo de manera más eficiente y reducir el tiempo de inactividad que puede aparecer en  sus aplicaciones.




Antes de la aparción de los  contenedores, la mayoría de las aplicaciones se ejecutaban en máquinas virtuales o máquinas físicas. Si una aplicación se bloquea, llevó bastante tiempo arrancar o reinicar de nuevo. Si solo tenía una o dos máquinas para ejecutar la aplicación, este tipo de tiempo de recuperación es inaceptable.

En cambio, se volvió común usar la supervisión a nivel de proceso para reiniciar aplicaciones cuando se bloqueaban. Si la aplicación se bloqueó, el proceso de monitoreo podría capturar el código de salida y reiniciar la aplicación al instante.

Con la llegada de sistemas como Kubernetes, los sistemas de monitoreo de procesos ya no son necesarios, ya que Kubernetes maneja el reinicio de las aplicaciones bloqueadas. Kubernetes usa un ciclo de eventos para asegurarse de que los recursos como los contenedores y los nodos están en un estado correcto o funcionado. Esto significa que ya no necesita ejecutar estos procesos de monitoreo manualmente. Si un recurso no pasa un control de checking, Kubernetes automáticamente activa un proceso de reinicio.

Tienes ya publicado en el blog que indican como activar el checking de tus servicios para ver cómo puede configurar comprobaciones de salud personalizadas.


El ciclo de vida de terminación de Kubernetes


Kubernetes hace mucho más que controlar su aplicación en caso de fallo. Puede crear más copias de su aplicación para ejecutar en múltiples máquinas, actualizar su aplicación e incluso ejecutar múltiples versiones de su aplicación al mismo tiempo.

Esto significa que hay muchas razones por las que Kubernetes podría terminar un contenedor  que este perfecto. Si actualiza su implementación con una actualización continua, Kubernetes termina lentamente las antiguas unidades mientras activa otras nuevas. Si termina un nodo, Kubernetes termina todas los pods en ese nodo. Si un nodo se queda sin recursos, Kubernetes termina los pods para liberar esos recursos (consulte esta entrada anterior para obtener más información sobre los recursos).

¡Es importante que su aplicación controle la terminación con cuidado para que tenga un impacto mínimo en el usuario final y el tiempo de recuperación sea lo más rápido posible!

En la práctica, esto significa que su aplicación necesita controlar el mensaje SIGTERM y comenzar a apagar cuando lo recibe. Esto significa guardar todos los datos que se deben guardar, cerrar las conexiones de red, finalizar el trabajo restante y otras tareas similares.

Una vez que Kubernetes ha decidido finalizar su pod, se produce una serie de eventos. Veamos cada paso del ciclo de vida de terminación de Kubernetes.

1 - Pod se establece en el estado "Terminating" y se elimina de la lista de puntos finales de todos los Servicios

En este punto, el pod deja de recibir nuevo tráfico. Los contenedores que se ejecutan en los pods no se verán afectados.

2 - Se ejecuta preStop Hook

PreStop Hook es un comando especial o una solicitud http que se envía a los contenedores en el pod.

Si su aplicación no se cierra de forma correcto (el clasico "cuelge de la aplicación"), al recibir un SIGTERM, puede usar este hook para activar un apagado correcto. La mayoría de los programas se cierran correctamente al recibir un SIGTERM, pero si utiliza un código de terceros o está administrando un sistema que no tiene control, el Hook preStop es una gran manera de activar un apagado ordenado sin modificar la aplicación.

3 - La señal SIGTERM se envía al pod

En este punto, Kubernetes enviará una señal SIGTERM a los contenedores en el pod. Esta señal les permite a los contenedores saber que van a cerrar pronto.

Tu código debería escuchar este evento y comenzar a cerrarse limpiamente en este punto. Esto puede incluir detener cualquier conexión de larga duración (como una conexión a una base de datos o un flujo de WebSocket), guardar el estado actual, o algo por el estilo.

Incluso si está utilizando el Hook preStop, es importante que pruebe lo que le sucede a su aplicación si le envía una señal SIGTERM, ¡para que no se sorprenda de la producción!

4 - Kubernetes espera un período de gracia

En este punto, Kubernetes espera durante un tiempo específico llamado  "período de gracia" -> termination grace,  de terminación. Por defecto, esto es 30 segundos. Es importante tener en cuenta que esto sucede en paralelo al Hook preStop y la señal SIGTERM. Kubernetes no espera a que finalice el Hook preStop.

Si su aplicación termina cerrándose y se cierra antes de finalizar terminationGracePeriod, Kubernetes pasa al siguiente paso inmediatamente.

Si su módulo se demora generalmente más de 30 segundos para apagarse, asegúrese de aumentar el período de gracia. Puede hacerlo configurando la opción terminationGracePeriodSeconds en el Pod YAML. Por ejemplo, para cambiarlo a 60 segundos:


apiVersion: v1 
Kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: busybox
  terminationGracePeriodSeconds: 60


5 - La señal de SIGKILL se envía al pod y se retira el pod

Si los contenedores siguen funcionando después del período de gracia, se les envía la señal SIGKILL y se los elimina por la fuerza. En este punto, todos los objetos de Kubernetes se limpian también.

Conclusión

Kubernetes puede finalizar los pods por una variedad de razones, y asegurarse de que su aplicación maneje estas terminaciones correctamente es fundamental para crear un sistema estable y proporcionar una excelente experiencia de usuario.