Pod

En esta página se describen los objetos de tipo pod de Kubernetes y sus usos en Google Kubernetes Engine.

¿Qué es un pod?

Los pods son los objetos más pequeños y básicos que se pueden implementar en Kubernetes. Un pod representa una instancia única de un proceso en ejecución en el clúster.

Los pods comprenden uno o más contenedores, como los de Docker. Cuando un pod ejecuta varios contenedores, estos se administran como una sola entidad y comparten los recursos del pod. En general, ejecutar varios contenedores en un solo pod representa un caso práctico avanzado.

Los pods también poseen recursos compartidos de red y almacenamiento para sus contenedores:

  • Red: A los pods se les asignan direcciones IP únicas de manera automática. Los contenedores del pod comparten el mismo espacio de nombres de red, incluida la dirección IP y los puertos de red. Los contenedores en un pod se comunican entre sí dentro del pod en localhost.
  • Almacenamiento: Los pods pueden especificar un conjunto de volúmenes de almacenamiento compartido que se puede compartir entre los contenedores.

Puedes pensar que un pod es un “host lógico” autónomo y aislado que posee las necesidades sistémicas de la aplicación para la que funciona.

El objetivo de un pod es ejecutar una única instancia de tu aplicación en el clúster. Sin embargo, no se recomienda crear pods individuales directamente. En su lugar, puedes crear un conjunto de pods idénticos, llamados réplicas, para ejecutar la aplicación. Un controlador, como una implementación, crea y administra ese conjunto de pods replicados. Los controladores administran el ciclo de vida de sus pods constituyentes, y pueden realizar escalamientos horizontales y cambiar el número de pods según sea necesario.

Aunque puede que, en ocasiones, interactúes con pods directamente a fin de depurar, solucionar problemas o inspeccionarlos, se recomienda que uses un controlador para administrar los pods.

Los pods se ejecutan en los nodos del clúster. Una vez creado, un pod permanece en su nodo hasta que se completa su proceso; entonces, el pod se borra y se expulsa del nodo debido a falta de recursos o hasta que el nodo falla. Si un nodo falla, se programa automáticamente la eliminación de sus pods.

Ciclo de vida de los pods

Los pods son efímeros; no están diseñados para funcionar en forma permanente y no se pueden recuperar cuando finalizan. En general, los pods no desaparecen hasta que un usuario o un controlador los borra.

Los pods no se “regeneran” ni se reparan por sí mismos. Por ejemplo, si se programa un pod en un nodo que luego falla, este se borrará. De forma similar, un pod no se reemplaza a sí mismo si se lo expulsa de un nodo por algún motivo.

Cada pod tiene un objeto de la API de PodStatus, que se representa mediante el campo status de un pod. Los pods publican su fase en el campo status: phase, y esta es un resumen de alto nivel del pod en su estado actual.

Cuando usas el comando kubectl get pod para inspeccionar un pod que se ejecuta en el clúster, este puede tener una de las siguientes fases:

  • Pendiente: El clúster creó y aceptó al pod, pero uno o más de sus contenedores aún no se ejecutan. En esta fase se incluye el tiempo dedicado a la programación en un nodo y a la descarga de imágenes.
  • En ejecución: El pod se vinculó a un nodo y se crearon todos los contenedores; al menos uno de ellos se está ejecutando, está en proceso de iniciarse o se está reiniciando.
  • Exitoso: Todos los contenedores en el pod finalizaron con éxito; los pods cerrados no se reinician.
  • Con errores: Todos los contenedores en el pod finalizaron y al menos un contenedor falló. Un contenedor “falla” si sale con un estado que no es cero.
  • Desconocido: No se puede determinar el estado del pod.

Además, PodStatus contiene un arreglo llamado PodConditions, que se representa en el manifiesto del pod como conditions e incluye los campos type y status. conditions indica con más exactitud las condiciones dentro del pod que causan su estado actual.

El campo type puede contener PodScheduled, Ready, Initialized y Unschedulable. El campo status corresponde con el campo type y puede contener True, False o Unknown.

Crea pods

Debido a que los pods son efímeros, no es necesario crear pods directamente. Del mismo modo, como los pods no pueden repararse o reemplazarse ellos mismos, no se recomienda crear pods directamente.

En su lugar, puedes usar un controlador, tal como una implementación, para que cree y administre los pods por ti. Los controladores también son útiles para implementar actualizaciones, como cambiar la versión de una aplicación que se ejecuta en un contenedor, ya que el controlador administra todo el proceso de actualización por ti.

Solicitudes de pods

Cuando un pod comienza a ejecutarse, solicita una cantidad de CPU y memoria. Esto ayuda a Kubernetes a programar el pod en un nodo apropiado para ejecutar la carga de trabajo. No se programará un pod en un nodo que no tenga los recursos para cumplir con su solicitud. Una solicitud es la cantidad mínima de CPU o memoria que Kubernetes garantiza a un pod.

Puedes configurar las solicitudes de CPU y memoria para un pod en función de los recursos que las aplicaciones necesiten. También puedes especificar solicitudes para contenedores individuales que se ejecutan en el pod. Ten en cuenta lo siguiente:

  • La solicitud predeterminada para la CPU es de 100 M. Esto es demasiado pequeño para muchas aplicaciones, y es probable que sea mucho más pequeño que la cantidad de CPU disponible en el nodo.
  • No hay ninguna solicitud predeterminada para la memoria. Un pod sin una solicitud de memoria predeterminada se podría programar en un nodo sin suficiente memoria para ejecutar las cargas de trabajo del pod.
  • Configurar un valor demasiado pequeño para las solicitudes de CPU o memoria podría causar que se programen demasiados pods o una combinación subóptima de pods en un nodo determinado y reducir el rendimiento.
  • Si se configura un valor demasiado grande para las solicitudes de CPU o memoria, podría suceder que el pod no pueda programarse y aumentaría el costo de los recursos del clúster.
  • Además de configurar los recursos de un pod, o en lugar de hacerlo, puedes especificar recursos para contenedores individuales que se ejecutan en el pod. Si solo especificas recursos en los contenedores, las solicitudes del pod son la suma de las solicitudes especificadas para los contenedores. Si especificas ambos, la suma de solicitudes para todos los contenedores no debe exceder las solicitudes del pod.

Se recomienda que configures las solicitudes para los pods en función de los requisitos de las cargas de trabajo reales. Para obtener más información, consulta las prácticas recomendadas de Kubernetes sobre límites y solicitudes de recursos en el blog de Google Cloud.

Límites de pods

De forma predeterminada, un pod no tiene límite superior en la cantidad máxima de CPU o memoria que puede usar en un nodo, si bien puedes configurar límites para controlar ambas cantidades. Un límite es la cantidad máxima de CPU o memoria que Kubernetes garantiza a un pod.

Además de configurar los límites de un pod, o en lugar de hacerlo, puedes especificar límites para contenedores individuales que se ejecutan en el pod. Si solo especificas límites en los contenedores, los límites del pod son la suma de los límites especificados para los contenedores. Sin embargo, cada contenedor solo puede acceder a cierta cantidad de recursos según su límite. Por lo tanto, si decides especificar los límites solo en contenedores, debes especificar límites para cada contenedor. Si especificas ambos, la suma de los límites para todos los contenedores no debe exceder el límite del pod.

Cuando se programan pods no se tienen en cuenta los límites, pero estos pueden evitar la contención de recursos entre pods de un mismo nodo o que un pod cause inestabilidad en el sistema del nodo si le quita recursos al sistema operativo subyacente.

Se recomienda que configures límites para los pods en función de los requisitos de las cargas de trabajo reales. Para obtener más información, consulta las prácticas recomendadas de Kubernetes sobre límites y solicitudes de recursos en el blog de Google Cloud.

Plantillas de pod

Los objetos del controlador, como implementaciones y StatefulSets, contienen un campo de plantilla de pod. Las plantillas de pod contienen una especificación de pod que determina cómo debe ejecutarse cada pod, así como qué contenedores deben ejecutarse dentro de ellos y qué volúmenes deben activar.

Los objetos del controlador usan plantillas de pod para crear pods y administrar su “estado deseado” dentro del clúster. Cuando se cambia una plantilla de pod, todos los pods futuros usarán la plantilla nueva, pero no lo harán así todos los existentes.

Para obtener más información sobre cómo funcionan las plantillas de pod, consulta Crea una implementación en la documentación de Kubernetes.

Controla en qué nodos se ejecuta un pod

De forma predeterminada, los pods se ejecutan en los nodos del grupo de nodos predeterminado para el clúster. Puedes configurar el grupo de nodos que un pod selecciona de forma explícita o implícita:

  • Puedes forzar de forma explícita a un pod para que se implemente en un grupo de nodos específico mediante la configuración de nodeSelector en el manifiesto del pod. Esto fuerza a un pod a ejecutarse solo en los nodos de ese grupo de nodos.

  • Puedes especificar las solicitudes de recursos para los contenedores que ejecutes. Se ejecutará el pod solo en los nodos que cumplan con las solicitudes de recursos. Por ejemplo, si la definición del pod incluye un contenedor que requiere cuatro CPU, el servicio no seleccionará a los pods que se ejecutan en nodos con dos CPU.

Patrones de uso de pods

Hay dos formas principales de usar pods:

  • Pods que ejecutan un solo contenedor. El patrón de pod más simple y común es un contenedor único por pod, donde el contenedor único representa una aplicación completa. En este caso, puedes pensar en un pod como un wrapper.
  • Pods que ejecutan varios contenedores que deben trabajar en conjunto. Los pods con varios contenedores se usan en particular para brindar compatibilidad con programas de ubicación y administración conjunta que deben compartir recursos. Estos contenedores de ubicación conjunta pueden formar una unidad de servicio coherente única: un contenedor entrega archivos desde un volumen compartido mientras que otro contenedor actualiza esos archivos. El pod une estos contenedores y recursos de almacenamiento, y forma una sola entidad administrable.

El objetivo de cada pod es ejecutar una única instancia de una aplicación dada. Si quieres ejecutar varias instancias, debes usar un pod por cada instancia de la aplicación. En general, esto se conoce como replicación. Un controlador, como una implementación, crea y administra los pods replicados.

Finalización de un pod

Los pods finalizan de forma estable cuando sus procesos se completan. Kubernetes impone un período de gracia predeterminado de 30 segundos para la finalización. Cuando borras un pod, puedes anular este período de gracia si estableces la marca --grace-period en la cantidad de segundos de espera hasta que el pod termine antes de forzar su cierre.

Próximos pasos