Cómo funcionan las implementaciones de Kubernetes

Completado

La aplicación de seguimiento de drones tiene varios componentes que se implementan de forma independiente. Nuestra tarea consiste en configurar las implementaciones de estos componentes en el clúster. Aquí podrá ver algunas de las opciones de implementación disponibles para implementar estos componentes.

Diagram of the high-level architecture that shows the drone-tracking solution components.

Opciones de implementación de pods

Al usar kubectl, hay varias opciones para administrar la implementación de pods en un clúster de Kubernetes. Las opciones son las siguientes:

  • Plantillas de pod
  • Controladores de replicación
  • Conjuntos de réplicas
  • Implementaciones

Puede usar cualquiera de estas cuatro definiciones de tipo de objeto de Kubernetes para implementar uno o varios pods. En estos archivos, se utiliza YAML para describir el estado previsto del pod o de los pods que se van a implementar.

¿Qué es una plantilla de pod?

Una plantilla de pod permite definir la configuración del pod que se quiere implementar. Contiene información, como el nombre de la imagen de contenedor, y qué registro de contenedor se va a usar para capturar las imágenes. La plantilla también incluye información de configuración de ejecución, como los puertos que se van a usar. Las plantillas se definen mediante YAML de la misma manera que cuando se crean archivos de Docker.

Puede usar plantillas para implementar pods manualmente, pero un pod implementado manualmente no se reinicia después de que se produzca un error, se elimine o finalice. Para administrar el ciclo de vida de un pod, debe crear un objeto de Kubernetes de nivel superior.

¿Qué es un controlador de replicación?

Un controlador de replicación usa plantillas de pod y define un número especificado de pods que se deben ejecutar. El controlador ayuda a ejecutar varias instancias del mismo pod, y garantiza que los pods siempre se ejecuten en uno o más nodos del clúster. De este modo, el controlador reemplaza los pods en ejecución con los nuevos pods si se produce un error, se eliminan o finalizan.

Por ejemplo, suponga que implementa el sitio web front-end de seguimiento de drones y que los usuarios empiezan a acceder a dicho sitio web. Si se produce un error en todos los pods por cualquier motivo, el sitio web no estará disponible para los usuarios, a menos que iniciemos pods nuevos. Un controlador de replicación le ayuda a asegurarse de que el sitio web está siempre disponible.

¿Qué es un conjunto de réplicas?

Los conjuntos de réplicas reemplazan al controlador de replicación como opción preferida para implementar réplicas. Un conjunto de réplicas incluye la misma funcionalidad que un controlador de replicación, pero tiene una opción de configuración adicional para incluir un valor de selector.

Un selector permite que el conjunto de réplicas identifique todos los pods que se ejecutan de manera subyacente. Esta característica permite administrar los pods etiquetados con el mismo valor que el valor del selector pero que no se han creado con el conjunto de réplicas.

¿Qué es una implementación?

Una implementación crea un objeto de administración un nivel superior a un conjunto de réplicas y le permite implementar y administrar las actualizaciones de pods en un clúster.

Imagine que tiene cinco instancias de la aplicación implementada en el clúster. Hay cinco pods que ejecutan la versión 1.0.0 de la aplicación.

Diagram that shows five pods running on a node with the same pod version.

Si decide actualizar la aplicación manualmente, puede eliminar todos los pods y luego iniciar nuevos que ejecuten la versión 2.0.0 de la aplicación. Con esta estrategia, la aplicación experimenta tiempo de inactividad.

En vez de esto se recomienda ejecutar una actualización gradual en la que los pods con la nueva versión de la aplicación se inicien antes de eliminar los que ejecutan la versión anterior de la aplicación. Las actualizaciones graduales inician un pod a la vez, en lugar de desconectar todos los pods más antiguos de golpe. Las implementaciones respetan el número de réplicas configuradas en la sección donde se describe la información sobre los conjuntos de réplicas. Mantiene el número de pods especificado en el conjunto de réplicas a medida que reemplaza los antiguos con nuevos.

Diagram that shows five pods, two pods set as version 1 and 3 pods set as version 2.

Al actualizar los pods, las implementaciones proporcionan de manera predeterminada una estrategia de actualizaciones graduales. También puede usar una estrategia de recreación. Esta estrategia finaliza los pods antes de iniciar pods nuevos.

Las implementaciones también proporcionan una estrategia de reversión, que se puede ejecutar con kubectl.

Las implementaciones usan archivos de definición basados en YAML y facilitan la administración de las implementaciones. Recordemos que las implementaciones permiten aplicar cualquier cambio en el clúster. Así pues, podemos implementar versiones nuevas de una aplicación, actualizar etiquetas y ejecutar otras réplicas de nuestros pods.

kubectl tiene una sintaxis bastante práctica para crear una implementación automáticamente cuando usamos el comando kubectl run para implementar un pod. Este comando crea una implementación con el conjunto de réplicas y los pods necesarios, pero no crea ningún archivo de definición. Es un procedimiento recomendado para administrar todas las implementaciones con archivos de definición de implementación y realizar un seguimiento de los cambios mediante un sistema de control de versiones.

Consideraciones de la implementación

Kubernetes tiene requisitos específicos sobre cómo configurar las redes y el almacenamiento de un clúster. El modo en que estos dos aspectos se configuran afecta a las decisiones sobre cómo exponer las aplicaciones en la red en clúster y almacenar los datos.

Por ejemplo, cada uno de los servicios de la aplicación de seguimiento de drones tiene requisitos específicos respecto al acceso de usuarios, al acceso a la red entre procesos, así como al almacenamiento de datos. Ahora echemos un vistazo a estos aspectos de un clúster de Kubernetes y a cómo afectan a la implementación de aplicaciones.

Redes de Kubernetes

Imagine que tiene un clúster con un plano de control y dos nodos. Al agregar nodos a Kubernetes, se asigna una dirección IP automáticamente a cada nodo desde un intervalo de red privada interno. Por ejemplo, si nuestro intervalo de red local fuera 192.168.1.0/24:

Diagram of nodes with assigned IP addresses in a cluster.

Cada pod que implementemos obtiene una dirección IP de un grupo de direcciones IP. Por ejemplo, imagine que nuestra configuración usara el intervalo de red 10.32.0.0/12, como se muestra en la imagen siguiente.

Diagram of nodes and pods with assigned IP addresses in a cluster.

De forma predeterminada, los pods y los nodos no se pueden comunicar entre sí usando intervalos de direcciones IP diferentes.

Para complicar aún más las cosas, recordemos que los pods son transitorios. La dirección IP del pod es temporal y no se puede usar para volver a conectarse a un pod recién creado. Esta configuración afecta al modo en que la aplicación se comunica con sus componentes internos y a la forma en que tanto el usuario como los servicios interactúan con ella externamente.

Para simplificar la comunicación, Kubernetes espera que configuremos las funciones de red de manera que permita lo siguiente:

  • Los pods pueden comunicarse entre sí entre nodos sin traducción de direcciones de red (NAT).
  • Los nodos pueden comunicarse con todos los pods, y viceversa, sin NAT.
  • Los agentes de un nodo pueden comunicarse con todos los nodos y pods.

Kubernetes ofrece varias opciones de red que se pueden instalar para configurar las funciones de red. Entre los ejemplos encontramos Antrea, Cisco Application Centric Infrastructure (ACI), Cilium, Flannel, Kubenet, VMware NSX-T y Weave Net.

Los proveedores de nube también proporcionan sus propias soluciones de redes. Por ejemplo, Azure Kubernetes Service (AKS) es compatible con la interfaz de red de contenedor (CNI) de Azure Virtual Network, Kubenet, Flannel, Cilium y Antrea.

Servicios de Kubernetes

Un servicio de Kubernetes es un objeto de Kubernetes que proporciona redes estables para pods. Un servicio de Kubernetes permite la comunicación entre los nodos, pods y usuarios de la aplicación, tanto internos como externos, y el clúster.

Cuando un servicio se crea, Kubernetes le asigna una dirección IP, al igual que sucede en el caso de un nodo o un pod. Estas direcciones se asignan desde un intervalo IP del clúster de servicio; por ejemplo, 10.96.0.0/12. A un servicio también se le asigna un nombre DNS, que refleja el nombre del servicio, y un puerto IP.

En la aplicación de seguimiento de drones, la comunicación de red se produce de la siguiente manera:

  • Los usuarios fuera del clúster pueden acceder al sitio web y a la API RESTful.

  • El front-end y la API RESTful pueden acceder a la caché en memoria y a los servicios de cola de mensajes, respectivamente, pero no los usuarios externos.

  • La cola de mensajes debe acceder al servicio de procesamiento de datos, pero no a los usuarios externos.

  • La caché en memoria y el servicio de procesamiento de datos pueden acceder a la base de datos NoSQL, pero no a los usuarios externos.

Para dar cabida a estos escenarios, podemos configurar tres tipos de servicios para exponer los componentes de la aplicación.

Servicio Descripción
ClusterIP Dirección asignada a un servicio que hace que este esté disponible para un conjunto de servicios dentro del clúster. Por ejemplo, la comunicación entre los componentes front-end y back-end de la aplicación.
NodePort Puerto de nodo, entre 30000 y 32767, que el plano de control de Kubernetes asigna al servicio; por ejemplo, 192.169.1.11 en clusters01. Después, configuraremos el servicio con un puerto de destino en el pod que queramos exponer. Por ejemplo, configuraremos el puerto 80 en el pod que ejecuta uno de los servidores front-end. Ahora podemos acceder al front-end a través de una dirección IP de nodo y una dirección de puerto.
LoadBalancer Equilibrador de carga que permite la distribución de la carga entre los nodos que ejecutan la aplicación y exponen el pod al acceso de red pública. Normalmente, los equilibradores de carga se configuran al usar proveedores de nube. En este caso, el tráfico del equilibrador de carga externo se dirige a los pods que ejecutan la aplicación.

En la aplicación de seguimiento de drones, puede optar por exponer el sitio web de seguimiento y la API RESTful mediante LoadBalancer y el servicio de procesamiento de datos mediante ClusterIP.

Procedimiento para agrupar pods

Administrar pods por su dirección IP no es práctico. Las direcciones IP de los pods cambian a medida que los controladores las vuelven a crear, y puede tener cualquier número de pods en ejecución.

Diagram of a service with selector labels.

Un objeto de servicio permite dirigir y administrar pods específicos del clúster usando etiquetas de selector. Hay que establecer la etiqueta del selector en una definición de servicio para que coincida con la etiqueta del pod definida en el archivo de definición del pod.

Imaginemos, por ejemplo, que tenemos varios pods en ejecución. Solo algunos de estos pods están en el front-end, y queremos establecer un servicio LoadBalancer que tenga como destino únicamente los pods front-end. Podemos aplicar el servicio para exponer estos pods haciendo referencia a la etiqueta del pod como un valor de selector en el archivo de definición del servicio. El servicio solo agrupa los pods que coinciden con la etiqueta. Si un pod se quita y se vuelve a crear, el nuevo pod se agregará automáticamente al grupo de servicios con la etiqueta coincidente.

Almacenamiento de Kubernetes

Kubernetes usa el mismo concepto de volumen de almacenamiento que vemos al usar Docker. El grado de administración de volúmenes de Docker es menor que el de volúmenes de Kubernetes, ya que la duración del volumen de Docker no se administra. La duración del volumen de Kubernetes es una duración explícita que coincide con la duración del pod. Esta coincidencia de duración significa que un volumen revive los contenedores que se ejecutan en el pod. Sin embargo, si se quita el pod, también se quita el volumen.

Diagram of a service with selector labels again.

Kubernetes proporciona opciones para aprovisionar el almacenamiento persistente con el uso de PersistentVolumes. También se puede solicitar un almacenamiento específico para pods por medio de PersistentVolumeClaims.

Tenga en cuenta estas dos opciones al implementar componentes de aplicación que requieran almacenamiento persistente, como las colas de mensajes y las bases de datos.

Consideraciones sobre la integración en la nube

Kubernetes no dicta la pila de tecnología que se usa en la aplicación nativa de nube. En un entorno de nube, como Azure, podemos usar varios servicios fuera del clúster de Kubernetes.

Ya le indicamos antes que Kubernetes no proporciona ninguno de los siguientes servicios:

  • Software intermedio
  • Marcos de procesamiento de datos
  • Bases de datos
  • Cachés
  • Sistemas de almacenamiento de clúster

En esta solución de seguimiento de drones hay tres servicios que proporcionan una funcionalidad de middleware: una base de datos NoSQL, un servicio de caché en memoria y una cola de mensajes. Puede seleccionar Atlas de MongoDB para la solución NoSQL, Redis para administrar la caché en memoria y RabbitMQ, o Kafka, en función de las necesidades de la cola de mensajes.

Al usar un entorno de nube, como Azure, se recomienda usar servicios fuera del clúster de Kubernetes. Esta decisión puede simplificar la configuración y la administración del clúster. Por ejemplo, puede usar Azure Cache for Redis para los servicios de almacenamiento en caché en memoria, la mensajería de Azure Service Bus para la cola de mensajes y Azure Cosmos DB para la base de datos NoSQL.