Patrones de implementación heterogéneos con Kubernetes

En este artículo, se describen patrones comunes para crear implementaciones heterogéneas a nivel de producción con Kubernetes. Analizaremos tres casos prácticos y describiremos los detalles arquitectónicos que puedes usar para crear las implementaciones correspondientes. Las descripciones arquitectónicas incluyen Kubernetes en general y Google Kubernetes Engine (GKE) en particular.

Implementaciones heterogéneas

Las implementaciones heterogéneas en general implican la conexión de dos o más entornos o regiones de infraestructura distintos para abordar una necesidad operativa o técnica específica. Las implementaciones heterogéneas se llaman “híbridas”, “de varias nubes”, o “pública-privada”, según los datos específicos de la implementación. A los efectos de este artículo, las implementaciones heterogéneas incluyen aquellas que abarcan regiones en un único entorno de nube, múltiples entornos de nube pública (múltiples nubes) o una combinación de entornos de nube locales y públicas (híbridas o pública-privada).

Pueden surgir varios desafíos comerciales y técnicos en las implementaciones que se limitan a un único entorno o región como los siguientes:

  • Recursos agotados: en cualquier entorno único, en particular en los entornos locales, es posible que no tengas los recursos de procesamiento, herramientas de redes y almacenamiento para satisfacer tus necesidades de producción.
  • Alcance geográfico limitado: las implementaciones en un entorno único requieren personas que estén geográficamente distantes entre sí para acceder a una implementación. Su tráfico puede viajar por todo el mundo a una ubicación central.
  • Disponibilidad limitada: los patrones del tráfico a escala de la Web desafían a las apps a permanecer tolerantes a los errores y resilientes.
  • Compromiso con el proveedor: las abstracciones de infraestructura y plataforma a nivel del proveedor pueden evitar la portabilidad de las apps.
  • Recursos inflexibles: sus recursos pueden estar limitados a un conjunto particular de soluciones de procesamiento, almacenamiento o herramientas de redes.

Las implementaciones heterogéneas pueden ayudar a abordar estos desafíos, pero su arquitectura debe usar procesos y procedimientos programáticos y deterministas. Los procedimientos de implementación por única vez o ad-hoc pueden lograr que las implementaciones o procesos sean intolerantes a los fallos y frágiles. Los procesos ad-hoc pueden perder datos o disminuir el tráfico. Los buenos procesos de implementación deben ser repetibles y usar enfoques comprobados para administrar el aprovisionamiento, la configuración y el mantenimiento.

Tres situaciones comunes para la implementación heterogénea son las implementaciones de múltiples nubes, el fronting de datos locales y los procesos de integración continua y entrega continua (IC/EC).

En las siguientes secciones, se describen algunos casos prácticos comunes para implementaciones heterogéneas, junto con enfoques de buena arquitectura que usan Kubernetes y otros recursos de infraestructura.

Múltiples nubes

Las implementaciones de múltiples nubes, en las que todas las implementaciones son similares, son algunos de los patrones de implementación heterogéneos más comunes usados con Kubernetes.

Uno de los usos de las implementaciones de múltiples nubes implica elegir cómo se dirige el tráfico. En las implementaciones más simples, puedes elegir si enviar porcentajes específicos de tráfico entrante para implementaciones específicas. En las implementaciones compiladas en infraestructura de nube pública y local, puedes enviar más tráfico a la infraestructura de nube, para facilitar una migración a largo plazo o a fin de lograr recursos locales limitados.

Otro uso común para las implementaciones de múltiples nubes es configurar una implementación con alta disponibilidad, capaz de resistir la falla de cualquier entorno único. En estas situaciones, puedes organizar la misma implementación de Kubernetes en cada uno de los entornos deseados. Cada implementación debe ser capaz de escalar para satisfacer las necesidades de todo el tráfico, si algún entorno único falla.

Por último, puedes usar implementaciones de múltiples nubes para crear implementaciones que estén más cerca de manera física a los usuarios. Ubicar las implementaciones lo más cerca posible de los usuarios puede minimizar la latencia de respuesta y solicitud.

Dirigir el tráfico

Una implementación de múltiples nubes robusta usa un servicio de administración de tráfico de DNS para resolver las consultas de DNS a las implementaciones individuales. En los casos prácticos de división de tráfico generales, puedes configurar mecanismos de administración de tráfico de DNS para dividir el tráfico por porcentajes, en implementaciones individuales.

Dividir el tráfico

Para implementaciones con alta disponibilidad, puedes configurar el mecanismo de DNS mediante verificaciones de estado personalizadas de cada entorno. Cuando un entorno se pone en mal estado, deja de enviar actualizaciones de estado en buen estado y el mecanismo de DNS puede cambiar el tráfico a implementaciones que están aún en buen estado.

Cuando la latencia al usuario es fundamental, los mecanismos de DNS pueden usar una consulta entrante de una dirección IP para determinar su ubicación aproximada, y, luego, dirigir el tráfico a la implementación más cercana a esa región geográfica. Puedes usar proveedores de servicios de infraestructura de DNS, como NS1, Dyn, Akamai y otros, para dirigir el tráfico entre implementaciones múltiples.

Controlar solicitudes

Si DNS dirige el tráfico a implementaciones particulares, un balanceador de cargas debe recibir consultas entrantes y luego dirigirlas a un clúster de Kubernetes. Kubernetes ofrece dos mecanismos para exponer pods a tráfico entrante: Ingress y servicios.

Cuando los pods se implementan en un clúster de Kubernetes, no es fácil que otras apps o sistemas dentro o fuera del clúster accedan a ellos. Para lograr que los pods sean accesibles, primero tienes que crear un servicio. Por configuración predeterminada, un servicio acepta las conexiones de manera automática del interior del clúster, pero también se puede configurar para que acepte conexiones del exterior del clúster.

Cuando configuras un servicio para que acepte consultas externas, debes configurar el tipo de servicio como NodePort o LoadBalancer.

Configurar el tipo de servicio a NodePort expone un puerto único para cada servicio en todos los nodos del clúster de Kubernetes. Este puerto único permite que cada nodo acepte conexiones y consultas entrantes de balanceo de cargas proxy a los pods adecuados.

El tipo de servicio LoadBalancer es un superconjunto de NodePort. Además de proporcionar la configuración de puerto en cada nodo, configurar el tipo a LoadBalancer aprovisiona de manera automática un balanceador de cargas externo y lo configura al tráfico directo en el clúster y en los pods posteriores.

Los servicios en Kubernetes son una construcción de Capa 4, lo que significa que pueden admitir la accesibilidad solo mediante las direcciones IP y números de puerto. Ingress, una HTTP(S) (Capa 7) mecanismo de balanceo de cargas, es una colección de reglas que permiten que las conexiones entrantes alcancen servicios de clúster de Kubernetes backend. Puedes configurar el mecanismo Ingress para darle a los servicios una funcionalidad de capa de app adicional como URL accesibles de manera externa, balanceo de cargas de tráfico entrante, terminación de SSL o hosting virtual basado en nombre. El tráfico entrante se puede dirigir a los pods, expuesto a través de servicios, con encabezados de host HTTP o rutas de URL HTTP.

Tráfico dirigido a los pods

Servicios compartidos

Cuando ejecutas implementaciones de múltiples nubes, puede que necesites ejecutar uno o más servicios compartidos, como una base de datos, en cada implementación. La comunicación entre servicios compartidos tiene que ser a una latencia baja y segura.

Para una conectividad de ancho de banda alto y latencia baja, puedes conectar las redes subyacentes en cada implementación mediante el intercambio de tráfico directo o interconexiones de red administradas por terceros. GCP ofrece conectividad directa a través de intercambio de tráfico con Google en cualquiera de las ubicaciones de la red perimetral disponibles. Para facilitar el intercambio de tráfico directo, existen varios requisitos técnicos. Cuando no es posible cumplir con esos requisitos, otra opción es Cloud Interconnect. Puedes usar proveedores de servicios de Cloud Interconnect para conectarte a la red perimetral de Google con conectividad de calidad empresarial.

Después de que se estableció la conectividad, el próximo paso es asegurar el vínculo entre cada entorno mediante VPN. En cada implementación, necesitas una puerta de enlace para asegurar el tráfico entre las implementaciones. En GCP, Cloud VPN asegura el tráfico mediante una conexión de VPN con IPSec. Cloud VPN admite múltiples túneles VPN para agregar ancho de banda y admite enrutamiento estático o dinámico mediante Cloud Router.

Administración de clústeres

En tu implementación de múltiples nubes, puedes administrar y controlar cada clúster de Kubernetes como una entidad individual. Para lograr eso, debes crear de manera manual los pods y servicios en cada clúster. El beneficio es que, mientras que cada implementación puede tener algunas apps y servicios compartidos, también puede tener apps y servicios adecuados solo para sí misma.

Por ejemplo, puedes necesitar que tus implementaciones estén distribuidas geográficamente, pero puede haber servicios específicos de un país o región que no sean compatibles con todas las geografías.

En las implementaciones en las que la división del tráfico se distribuye de manera desigual se puede necesitar implementar pods y servicios por clúster, para asegurar que el tráfico y las consultas entrantes se controlen de manera apropiada.

Service Discovery

En las implementaciones de múltiples nubes, se usa Service Discovery para asegurar que las diferentes apps y servicios puedan encontrarse con facilidad en el tiempo de ejecución. Service Discovery elimina la necesidad de convenciones o esquemas con nombres complejos o frágiles que tienen que conocerse antes de la implementación. Los mecanismos de Service Discovery tienen que ser transparentes a las apps de destino y origen. En implementaciones de múltiples nubes, estos mecanismos deben habilitar apps y servicios para descubrir servicios que se estén ejecutando de manera local y remota en otros clústeres.

En implementaciones que se diseñan y se implementan como clústeres individuales independientes, los mecanismos de Service Discovery tienen que ser conscientes del centro de datos. Eso quiere decir que deben ser capaces de operar como sistemas distribuidos y coordinados con la capacidad de enviar consultas al clúster correcto basado en la consulta entrante, la disponibilidad local y la capacidad de carga. Existen sistemas de terceros, como Consul, Linkerd y otros, que pueden facilitar la detección de servicios entre distintos clústeres y entornos con implementaciones de Kubernetes en múltiples nubes.

Kubernetes proporciona asistencia a fin de resolver zonas privadas de DNS en el clúster Kubernetes. Esta asistencia es útil en situaciones híbridas o de múltiples nubes en las que los nombres de dominio totalmente calificados de los otros clústeres se conocen y el tráfico se puede enrutar con facilidad a ellos. Puedes configurar el acceso a dominios “stub” privados mediante ConfigMap. Puedes usar asistencia de Kubernetes a fin de resolver zonas de DNS privadas como un mecanismo independiente para enviar consultas a clústeres de Kubernetes específicos o en conjunción con sistemas externos como Consul.

Arquitectura

En el siguiente diagrama, se muestra un ejemplo de arquitectura de implementación de múltiples nubes.

Implementación de múltiples nubes

Fronting de datos locales

Puedes diseñar tus implementaciones de nube para extender las capacidades más allá de lo que se encuentra disponible en tus implementaciones locales o privadas. Por ejemplo, puedes implementar y diseñar apps basadas en la nube que puedan acceder a sistemas o infraestructuras de datos privados.

Recuerda que las implementaciones privadas o locales pueden tener una disponibilidad, portabilidad o flexibilidad de recursos limitados. La migración a implementaciones basadas en la nube puede abordar estas limitaciones, pero puede que eso no sea posible debido a arquitecturas heredadas, cumplimiento de seguridad o algún otro requisito del software. En esas situaciones, puedes implementar y compilar apps nuevas en entornos de nube que tengan una mayor flexibilidad o capacidad que los entornos locales o privados.

Arquitectura

En el siguiente diagrama, se muestra un ejemplo de arquitectura que demuestra infraestructura de datos locales de fronting de apps de nube.

Fronting de datos locales

Herramientas de redes

Para implementaciones en las que las apps de nube realizan un fronting de infraestructura de datos locales, necesitas una conectividad de latencia baja y segura para minimizar el tiempo de respuesta general de la app de los usuarios. Puedes usar Cloud Interconnect o intercambio de tráfico directo para minimizar la latencia y maximizar el ancho de banda disponible entre tus entornos de nube y locales. Después de que se estableció la conectividad, cada implementación debe tener una puerta de enlace VPN para asegurar el tráfico entre las implementaciones. En GCP, Cloud VPN asegura el tráfico con una conexión de VPN de IPSec. Cloud VPN admite múltiples túneles VPN para agregar ancho de banda y admite enrutamiento estático o dinámico mediante Cloud Router. Debido a que la seguridad es una preocupación cuando se realiza el fronting de infraestructura de datos locales, debes configurar rutas y firewall locales para permitir tráfico solo desde conjuntos de instancias GCP específicos.

Arquitectura de la nube

En la parte de la nube de las implementaciones híbridas, los componentes arquitectónicos deben incluir un balanceador de cargas adecuado, una infraestructura de hosting de app, una puerta de enlace VPN y un mecanismo de descubrimiento de servicio. La elección del balanceador de cargas depende de los requisitos de las apps orientadas al usuario final. Para las implementaciones en GCP, Cloud Load Balancing ofrece asistencia en HTTP(S), TCP, y UDP con una IP anycast única y disponible a nivel global.

En situaciones híbridas como estas, puedes implementar pods y servicios en GKE, una implementación administrada por Kubernetes disponible en GCP. GKE dirige el tráfico saliente a la infraestructura local. GKE usa Cloud VPN para asegurar el tráfico y usa Cloud Router a fin de configurar rutas estáticas o dinámicas. Esta configuración asegura de que solo el tráfico del clúster de GKE desvíe la conexión de VPN.

Arquitectura local

La parte local de esta implementación contiene la infraestructura de datos que respalda las apps de nube. Para la mayoría de las implementaciones de esta naturaleza, implementar una API de CRUD frente a los sistemas de datos ofrece muchos beneficios.

Si los sistemas de datos requieren altos niveles de seguridad o cumplimiento, una API de CRUD puede ser útil para ayudar a auditar y a registrar conexiones y consultas entrantes. Si la infraestructura de datos se ejecuta en un sistema heredado, una API de CRUD puede ayudar a proporcionar opciones de conectividad más modernas para las apps más nuevas.

En ambos casos, la API de CRUD puede ayudar a separar mecanismos de autorización y autenticación de base de datos integrados de aquellos que las apps necesiten, y proporcionar solo la cantidad de funcionalidad CRUD necesaria para las apps. En particular, si solo un subconjunto de datos necesita estar expuesto a las apps descendentes, una API puede ser útil para administrar el acceso a los datos.

Mediante las consultas y conexiones en auditoría, la API puede ayudar también a definir la estrategia de migración a largo plazo de los datos subyacentes. Si solo se necesita un subconjunto de datos y no satisface las políticas de seguridad ni de cumplimiento estrictas, esos datos pueden migrar a las plataformas de la nube.

En el diagrama de arquitectura anterior, se muestra la API de CRUD alojada en Kubernetes que se ejecuta de manera local. No es técnicamente obligatorio usar Kubernetes de manera local, pero ofrece ventajas: mientras más equipos consideren Kubernetes como un destino de implementación en una infraestructura de nube, se pueden beneficiar del desarrollo de experiencia adicional para usar y operar el sistema.

En la infraestructura local, se debe configurar la puerta de enlace VPN y cualquier firewall para permitir que el tráfico alcance la API de CRUD solo desde fuentes conocidas, a fin de minimizar posibles problemas de seguridad.

Service Discovery

En situaciones de implementación híbrida, debes usar Service Discovery para asegurar de que las diferentes apps y servicios puedan conectarse unas con otras con facilidad en el tiempo de ejecución. Con el tiempo, se pueden implementar más apps de nube que aprovechen diferentes componentes de la API de CRUD local. La API de CRUD puede agregar funcionalidad adicional a lo largo del tiempo, como API de tareas específicas o API para realizar un fronting de infraestructura de datos locales adicionales. En estos tipos de situaciones de implementación, el ciclo de lanzamiento de las apps de nube y la funcionalidad local de CRUD pueden diferir de manera significativa. Si usas un mecanismo externo de detección de servicios, como Consul o Linkerd, puedes proporcionar acoplamiento bajo de recursos y versiones para que iteren de manera independiente en cada entorno.

Si planeas implementar apps de nube solo en GKE o Kubernetes, puedes configurar el mecanismo interno de Kubernetes de DNS kube-dns para resolver dominios privados de DNS a direcciones IP privadas en el entorno local. En esa configuración, los pods que se ejecutan en el entorno de nube pueden usar consultas de DNS estándar para acceder con facilidad a servicios que están en ejecución en el entorno local. Para obtener más información, consulta Configurar zonas de DNS privadas y Nameservers ascendentes en Kubernetes.

Cargas de trabajo IC y EC

Las cargas de trabajo de múltiples nubes que se inician a partir de implementaciones locales se pueden beneficiar con la migración de cargas de trabajo más enfocadas a entornos de nube.

Las cargas de trabajo de integración continua (IC) son buenas candidatas para la migración, debido a que la capacidad de los entornos de nube de escalar de manera automática recursos de procesamiento puede ayudar a reducir el tiempo desde la finalización de código hasta los artefactos integrados.

Las cargas de trabajo de entrega continua (EC) también se pueden ejecutar en entornos de nube, lo que habilita una implementación y aprovisionamiento más fácil de entornos de prueba. La migración puede aumentar el número de procesos compilados en paralelo para la prueba de unidades. Otro beneficio posible es aumentar el número de implementaciones de prueba para pruebas de integración de extremo a extremo y otras pruebas automatizadas.

Las cargas de trabajo de IC y EC centradas en el contenedor y basadas en Cloud suelen usar los siguientes procesos de alto nivel:

  • Desarrollo. Los desarrolladores confirman y envían cambios de código a repositorios de origen locales o alojados de manera remota.
  • Creación. Un servicio de compilación que sondea de manera continua el repositorio de código fuente. Cuando hay cambios nuevos, el servicio comienza un proceso de compilación.
  • Prueba de unidades. En el proceso, se compilan fuentes, se ejecutan pruebas de unidades y se compila una imagen de contenedor resultante.
  • Prueba de integración. En el proceso, se crea un clúster de prueba, se implementa la imagen de contenedor con sus artefactos asociados y se ejecutan las pruebas de integración.
  • Preparación. Al completarse con éxito, las imágenes de contenedor se etiquetan con metadatos de la versión de lanzamiento.
  • Implementación. De manera opcional, los desarrolladores o administradores pueden implementar artefactos nuevos en la producción.

Casos prácticos

Las herramientas de IC y EC que más se usan con GCP son Jenkins y Spinnaker. Jenkins es un sistema de IC y EC de código abierto popular que se puede implementar en instancias de procesamiento independientes o como una serie de pods y servicios en Kubernetes. Spinnaker es un sistema de EC de código abierto capaz de organizar y automatizar la entrega de software a varios objetivos. Spinnaker puede aprovechar sistemas de IC como Jenkins o alguna otra herramienta como Cloud Build.

Jenkins y Kubernetes

Para las cargas de trabajo de IC y CE que usan Jenkins con Kubernetes, consulta la siguiente documentación que revisa recomendaciones, patrones de configuración comunes y organización de entrega continua:

Spinnaker

Spinnaker es una plataforma de EC de múltiples nubes y código abierto en la que se pueden organizar flujos de trabajo de implementación de software y administración de clúster. Las características de administración de clúster de Spinnaker proporcionan la capacidad para aprovisionar y controlar recursos de la nube como grupos de instancias, instancias, firewalls y balanceadores de cargas. Las cargas de trabajo de implementación de software incluyen canalizaciones, y cada una de ellas incluye una secuencia de acciones, llamadas etapas. Una etapa en una canalización de Spinnaker puede pasar parámetros a la siguiente etapa. Las canalizaciones se pueden iniciar de manera manual o a través de activadores automáticos, como sistemas de IC externos, secuencias de comandos cron, y otras canalizaciones. Spinnaker se envía con varias etapas empaquetadas con anterioridad para preparar imágenes, implementar imágenes, trabajar con grupos de instancias y solicitar la entrada de usuario. En la siguiente imagen se describe cómo las canalizaciones de Spinnaker realizan un lanzamiento de software.

Canalización de Spinnaker

El software se compila y, luego, se prueba. Si pasa todas las pruebas, una imagen inmutable se prepara y se vuelve accesible en la nube. Después de que la imagen está disponible, se puede implementar en clústeres para actualizar su software de ejecución.

Arquitectura

Cuando trabajas con implementaciones de contenedores, Spinnaker aprovecha los sistemas de IC externos como Jenkins o Cloud Build para ejecutar los pasos de compilación, prueba y preparación. Spinnaker organiza luego la implementación de destino mediante etapas de canalización estándar. En la siguiente imagen, se muestra la arquitectura de ese sistema.

Spinnaker con Jenkins

Para obtener más información sobre la implementación de Spinnaker en GCP, consulta Ejecutar Spinnaker en Compute Engine.

Compilar con Jenkins

Jenkins funciona bien con la asistencia de Spinnaker de activaciones para iniciar canalizaciones. Puedes usar las compilaciones de Jenkins para activar de manera automática las canalizaciones de Spinnaker. En una canalización de Spinnaker, las etapas de secuencia de comandos de Jenkins pueden ejecutar las etapas de prueba y preparación de los procesos de lanzamiento. Las etapas de administración de clúster incorporadas de Spinnaker pueden organizar la implementación de destino. Para obtener más información, consulta el ejemplo Implementación de Hello de Spinnaker.

Compilar con Cloud Build

Cloud Build es un servicio de GCP completamente administrado que compila imágenes de contenedor en un entorno rápido, coherente y confiable. Cloud Build se integra de manera directa a Cloud Source Repositories para activar de forma automática compilaciones basadas en cambios a las etiquetas de repositorio o fuentes. Cloud Build ejecuta las compilaciones en contenedores de Docker y puede admitir cualquier paso de compilación personalizado que se pueda empaquetar en un contenedor. Las compilaciones en Cloud Build son muy personalizables con asistencia para secuencia de pasos y simultaneidad. Los cambios de estado en el proceso de compilación se publican de manera automática en un tema de Cloud Pub/Sub.

Aunque Spinnaker no es compatible de manera directa con Cloud Build, proporciona asistencia para Container Registry, el registro de contenedores que usa Cloud Build de manera automática. Puedes configurar Spinnaker a fin de sondear Container Registry y para iniciar la canalización basada en la detección de versiones o etiquetas de imagen de contenedor actualizadas. En estas situaciones, debes configurar Cloud Build para ejecutar las etapas de compilación, la prueba y la preparación del proceso de lanzamiento. Puedes consultar más detalles sobre la configuración de Spinnaker para aprovechar Container Registry en la documentación de Spinnaker.

Organizar las implementaciones de Kubernetes

Los mecanismos de administración de clúster incorporado de Spinnaker admiten Kubernetes. Los grupos de servidores y los balanceadores de cargas en Spinnaker se corresponden con los conjuntos y servicios de réplicas dentro de Kubernetes, respectivamente.

En la siguiente documentación, hay una revisión de los pasos necesarios para configurar Spinnaker a fin de implementar pods y servicios en Kubernetes:

Pasos siguientes

  • Prueba otras funciones de Google Cloud Platform por tu cuenta. Revisa nuestros instructivos.
¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...