Contenedores: cómo es el ciclo de vida de una aplicación en Kubernetes
Tags: docker, kubernetes, tools, spanish
Published: 2019-08-20 08:58:02

---
title: Contenedores: cómo es el ciclo de vida de una aplicación en Kubernetes
published: true
tags: Docker,Kubernetes,Tools,Spanish
canonical_url: https://www.campusmvp.es/recursos/post/contenedores-como-es-el-ciclo-de-vida-de-una-aplicacion-en-kubernetes.aspx
cover_image: https://www.campusmvp.es/recursos/image.axd?picture=/2019/1T/kubernetes.png
---

>Post original escrito por **Eduard Tomás** en [campusMVP](https://www.campusmvp.es/recursos/post/contenedores-como-es-el-ciclo-de-vida-de-una-aplicacion-en-kubernetes.aspx)

Hace poco os explicaba en un artículo **[qué es Kubernetes, cuál es su arquitectura y su funcionamiento básico](https://dev.to/campusmvp/qu-es-kubernetes-y-cmo-funciona-mbd-temp-slug-5971176)**. Léelo antes de continuar si no tienes claros estos conceptos.

En esta ocasión voy a continuar con aquella explicación analizando cómo es el ciclo de vida de una aplicación que está desplegada con Kubernetes.

Lo primero que debemos tener claro es que **en Kubernetes nunca se ejecutan contenedores de forma directa**. Es decir, no se puede desplegar un contenedor o parar un contenedor. En su lugar se opera con lo que se llaman **_pods_**.

**Un _pod_ es la unidad mínima de despliegue y operación en Kubernetes**. Es decir, desplegamos _pods_, escalamos _pods_ y son los _pods_ los que se ejecutan en los distintos nodos.

La relación entre _pod_ y contenedor no tiene por qué ser de uno a uno: es decir,  **en un único _pod_ se pueden ejecutar varios contenedores**. Solo recuerda que en este caso se escalarán y desplegarán de forma conjunta (ya que se escala o despliega todo el _pod_).

Aunque es posible, teóricamente, desplegar en un _pod_ una web y su API en dos contenedores, eso no es lo que suele hacer. En la gran mayoría de casos las relaciones entre _pod_ y contenedor son, efectivamente, de uno a uno. Pero que un _pod_ pueda ejecutar varios contenedores habilita ciertos escenarios avanzados como p. ej. tener un contenedor que ofrezca servicios a otro contenedor (como podría ser hacer de _proxy_, de _logger_ o similar).

Es importante tener presente que **todos los contenedores que se ejecutan en un mismo _pod_ comparten espacio de red**. Es decir, se comunican entre ellos usando _localhost_ y no pueden abrir los mismos puertos. También comparten el espacio [IPC](https://es.wikipedia.org/wiki/Comunicaci%C3%B3n_entre_procesos) por lo que pueden usar cualquier técnica de IPC (como semáforos) para comunicarse entre ellos.

## Los distintos estados de un _pod_

Un _pod_ pasa por varias fases a lo largo de su ciclo de vida:

- **_Pending_** : el _pod_ ha sido creado, pero aún no se han creado sus contenedores ni se ha decidido qué nodo lo va a ejecutar.
- **_Running_** : los contenedores del _pod_ han sido creados y el _pod_ ya se está ejecutando en un nodo. Al menos un contenedor del _pod_ se está ejecutando o está en proceso de creación.

> **Esto es importante** : que un _pod_ esté en estado _running_ no significa que sus contenedores estén ejecutándose. P. ej. se pueden estar iniciando o reiniciando.

- **_Succeeded_** : los contenedores del _pod_ han finalizado (todos) su ejecución de forma satisfactoria.
- **_Failed_** : los contenedores del _pod_ han finalizado (todos) su ejecución y al menos uno de ellos lo ha hecho con error.
- **_Unknown_** : el estado del _pod_ no se puede saber. Esto suele indicar un error de comunicación con el nodo _minion_ que está ejecutando el _pod_.
- **_CrashLoopBackOff_** : el _pod_ está corriendo, pero uno de sus contenedores se está reiniciando debido a que ha terminado (generalmente de forma errónea).

Es importante **separar el ciclo de vida del _pod_ del ciclo de vida de sus contenedores**. Un _pod_ puede estar en la fase de _running_ pero uno de sus contenedores puede no estar ejecutándose. Cuando un _pod _está en fase de _CrashLoopBackOff_ eso significa que uno de los contenedores está en proceso de reinicio, pero otros contenedores del _pod_ pueden estar ejecutándose.

> Muchas veces se dice que Kubernetes reinicia un _pod_ pero esa expresión no es estrictamente cierta: Kubernetes reinicia contenedores de un _pod_, pero el _pod_ en sí mismo sigue ejecutándose durante todo este tiempo. Que Kubernetes decida reiniciar o no los contenedores de un _pod_ (y en qué casos) depende de la configuración del _pod_. Es decir, para ciertos _pods_ no hay posibilidad de que entren nunca en fase de _Succeeded_ ya que su misión es estar ejecutándose permanentemente (p. ej. una API), por lo que si un contenedor termina será reiniciado por Kubernetes.

Los _pods_ se consideran "objetos transitorios", en el sentido de que hay determinados eventos del clúster a los cuales no sobreviven. P. ej. si el nodo _minion_ se cae, todos los _pods_ que se estén ejecutándose en él se caen también. **Los _pods_ no se mueven de nodo ni se reinician** (sí se reinician sus contenedores como se ha comentado antes).

En general **no se suele crear nunca _pods_ de forma directa** , en su lugar usamos lo que llamamos un **controlador**. Un controlador es el responsable de garantizar que en todo momento se cumple una cierta condición al respecto de los _pods_ que controla, como que en todo momento haya N instancias de este _pod_.

> Hago aquí un inciso de nomenclatura: cuando digo "N instancias de un _pod_" me refiero a N _pods _idénticos (ejecutando los mismos contenedores y con la misma configuración) pero son N _pods_.

Si estamos usando un controlador y deseamos tener en todo momento 2 instancias de un determinado _pod_ y uno de los dos _pods_ se muere (porque se muere su nodo p. ej.), el controlador creará otro _pod_ para asegurar de que siga habiendo dos instancias.

Cuando tenemos N instancias, los N _pods_ se consideran todos "idénticos". Si por algún motivo (p. ej. debe desescalarse) debe eliminarse algún _pod_, el controlador eliminará uno cualquiera, sin preferencias. Eso encaja con el modelo _stateless_ de aplicación en el que los contenedores encajan perfectamente. Es decir, como desarrollador debes asegurar que tus contenedores sean _stateless_, ya que en cualquier momento Kubernetes puede decidir eliminar el _pod_ (y por lo tanto el contenedor) y recrearlo en otra parte.

Este modelo _stateless_ no siempre aplica: a veces, si tenemos N instancias de un _pod_ hay alguno que juega un rol especial y por lo tanto se requiere que estos tengan identidad. Un ejemplo es una configuración de base de datos en modo maestro/esclavo. Si uno de los _pods_ se cae, el nuevo que se cree debe ser del mismo tipo, y no solo eso, sino que debe recibir el estado que tenía el _pod_ caído. Kubernetes es capaz de gestionar estos casos mediante un controlador específico (llamado `StatefulSet`), pero lo ideal es que nuestras aplicaciones sean _stateless_.

>Post original escrito por **Eduard Tomás** en [campusMVP](https://www.campusmvp.es/recursos/post/contenedores-como-es-el-ciclo-de-vida-de-una-aplicacion-en-kubernetes.aspx)