Blog de Amazon Web Services (AWS)
Creación de una solución SaaS multi-tenant con Amazon EKS
Por Toby Buckley, Arquitecto de Soluciones para Partners en AWS y
Ranjith Raman, Arquitecto de soluciones para Partner en AWS
A medida que más organizaciones se desplazan hacia un modelo de entrega de software como servicio (SaaS), muchas eligen Amazon Elastic Kubernetes Service (Amazon EKS) como plataforma de sus soluciones. El modelo de programación, la rentabilidad, la seguridad, la implementación y los atributos operativos de EKS representan un modelo convincente para los proveedores SaaS.
El Modelo de EKS también presenta a los arquitectos y desarrolladores de SaaS una colección de nuevas consideraciones para varios tenants. Ahora toca pensar en cómo se realizan los principios fundamentales de SaaS (aislamiento, incorporación, identidad) en un entorno EKS.
Para proporcionar una visión más clara de cómo se crean estos principios, hemos creado una solución SaaS de EKS de ejemplo que proporciona a los arquitectos y desarrolladores un ejemplo práctico. Esto ilustra cómo las mejores prácticas de diseño y arquitectura de varios tenants cobran vida en un entorno EKS.
En este post, vamos a recorrer los elementos arquitectónicos clave de la arquitectura de ejemplo de EKS. Analizaremos cómo aislar a los tenants dentro de un clúster de EKS, automatizar la incorporación de tenants, administrar las identidades de los tenants y dar soporte al enrutamiento de las cargas de trabajo de los tenants.
Esta solución incluye una experiencia de trabajo completa con una aplicación SaaS de ejemplo y una consola de administración que administra su entorno SaaS.
Explore aquí la solución de ejemplo SaaS de EKS >>
Eligiendo un modelo de aislamiento
Existen innumerables formas de diseñar y crear una solución SaaS multi-tenants en Amazon EKS, cada una con su propio conjunto de retos y beneficios. En EKS, existen varias opciones que podrían afectar el esfuerzo de implementación, la complejidad operativa y la rentabilidad.
Por ejemplo, algunos pueden optar por emplear un modelo de clúster por tenant para aislar a sus tenants. Esto tendría una historia de aislamiento simple, pero también podría venir con un precio elevado.
Otros pueden utilizar un modelo de cómputo compartido en el que todos los tenants se combinan dentro del clúster, los namespaces (Espacio de Nombres) y el aislamiento se gestiona a nivel de aplicación. Como cabría esperar, esto logra una gran eficiencia operativa y rentable; también representa un modelo de aislamiento menos convincente.
En medio de estos dos extremos se encuentra el aislamiento de namespace por tenant, donde cada tenant se despliega en el mismo clúster pero se separa unos de otros utilizando namespaces y una serie de construcciones Kubernetes nativas y complementarias. Esto es lo que comúnmente se conoce como modelo de «silo» en el que los tenants no comparten los recursos.
Este modelo por tenant representa una buena combinación de aislamiento y rentabilidad. Por este motivo, hemos optado por implementar este modelo en la solución de ejemplo SaaS de EKS. Esta elección termina teniendo un impacto significativo en nuestra solución, incluida la incorporación de tenants, el aislamiento de tenants y el enrutamiento del tráfico de tenants.
Arquitectura de alto nivel
Antes de profundizar en los detalles de la solución SaaS EKS, veamos los elementos de alto nivel de la arquitectura que emplea esta solución de ejemplo. A continuación, verá cada una de las capas que forman parte de la solución SaaS de EKS.
En primer lugar, tenemos tres tipos diferentes de aplicaciones que forman parte de la experiencia SaaS de EKS. Estas se correlacionan con los tipos comunes de aplicaciones que tendría en muchos entornos SaaS. La primera aplicación, la página de inicio, representa la página de orientación pública en la que el cliente puede encontrar y suscribirse a nuestra solución. Los nuevos clientes pueden acceder a este sitio, activar el proceso de registro y crear un nuevo tenant en el sistema.
La siguiente aplicación es la aplicación de comercio de muestra. Aquí, hemos creado una sencilla aplicación de comercio electrónico que proporciona algunas funciones básicas de pedidos y productos mientras nos comunicamos con microservicios específicos de tenants que se ejecutan en el clúster de EKS. Aquí es donde aterriza su aplicación SaaS multi-tenants.
La última aplicación es la consola de administración del proveedor SaaS. También utiliza Amazon Cognito para controlar el acceso. Como proveedor de SaaS, utilizaría esta aplicación para configurar y administrar las políticas y la configuración de los tenants. Cada una de estas aplicaciones interactúa con los servicios que se ejecutan en un clúster de EKS.
Hay dos categorías de servicios diferentes que se ejecutan en este clúster. En primer lugar, la capa de servicios compartidos representa todos los servicios comunes necesarios para admitir todas las capacidades operativas, de administración, de identidad, de incorporación y de configuración de un entorno SaaS.
La otra categoría de servicios forma parte de los entornos de tenants administrados. Los servicios que se ejecutan aquí representan los diferentes entornos de tenants implementados que ejecutan los microservicios de nuestra aplicación. Tenemos implementaciones separadas para cada tenant de nuestro sistema y exploraremos los fundamentos de esa decisión de arquitectura a continuación.
Qué se aprovisiona
Ahora que conocemos la arquitectura de alto nivel, vamos a profundizar un nivel más para ver qué se aprovisiona al instalar la solución SaaS de EKS.
Infraestructura de referencia
Antes de empezar a pensar en los tenants y las aplicaciones, necesitamos implementar la versión de referencia de nuestro entorno.
Esta infraestructura se compone del clúster EKS que aloja nuestro servicio. También incluye la infraestructura de soporte necesaria, como los roles de AWS Identity and Access Management (IAM), las distribuciones de Amazon CloudFront y el respaldo de Amazon Simple Storage Service (Amazon S3).
El clúster de EKS, junto con su nube privada virtual (VPC), subredes y puertas de enlace de traducción de direcciones de red (NAT) correspondientes, se implementa a través de la herramienta CLI eksctl. Esta interfaz de línea de comandos (CLI) simplifica la creación de los distintos scripts de AWS CloudFormation necesarios para implementar un clúster EKS listo para usar. Este clúster ejecuta los entornos compartidos y los entornos de tenant de su solución SaaS de EKS.
Si bien hemos aprovechado patrones comunes para configurar e implementar el clúster, querrá pensar en cómo proteger aún más la red y el clúster en función de las necesidades específicas de su entorno. Obtenga más información sobre las prácticas recomendadas para crear un clúster EKS totalmente seguro.
Una vez instalado el clúster, implementamos varios objetos API de Kubernetes en el clúster, incluidos el controlador de entrada NGINX de código abierto y el DNS externo.
El controlador de entrada desempeña un papel clave ayudando a dirigir las solicitudes de varios tenants desde aplicaciones cliente. Funciona en conjunto con DNS externo, que crea automáticamente entradas DNS de Amazon Route 53 para cualquier subdominio al que se hace referencia en nuestros recursos de ingreso.
En nuestro caso, esto es solo API.Domain.com.
El DOMINIO al que se hace referencia aquí representa un dominio personalizado que configurará en el momento de la implementación.
Esta arquitectura de referencia incluye Amazon S3 y es donde cada una de las aplicaciones web presentadas en esta solución se alojan como sitios web estáticos. Utilizamos distribuciones de CloudFront con nombres de dominio personalizados para la distribución de contenido. Cada sitio web se crea y copia en su bucket de S3 respectivo tras la implementación.
Además de los buckets de S3 y los servicios CloudFront compatibles, el stack de línea base aprovisiona un certificado comodín (wildcard) correspondiente al nombre de dominio personalizado proporcionado cuando se implementa. Este certificado se utiliza para proporcionar conexiones HTTPS a todas las entidades web públicas de esta solución, incluidas las tres aplicaciones web descritas anteriormente, así como los servicios web compartidos y específicos del tenant orientados al público.
La configuración de este entorno de referencia también incluye la implementación de la parte de servicios compartidos de nuestro entorno SaaS (registro, administración de tenants y administración de usuarios). Estos respaldan nuestra capacidad de incorporar y administrar tenants, así como administrar usuarios administradores.
Los servicios compartidos dependen de varios recursos de AWS. La administración de tenants almacena y administra la información de los tenants en una tabla de Amazon DynamoDB. La administración de usuarios administra los usuarios que se almacenan en Cognito.
Todos los microservicios que se ejecutan en EKS se implementan en Java Spring Boot. Durante la implementación de la pila de referencia, se crea un repositorio de Amazon Elastic Container Registry (Amazon ECR) para cada uno de los microservicios del sistema. En el momento de la implementación, cada servicio se crea y se envía a su repositorio respectivo.
Como último paso de la configuración de referencia, se añaden registros DNS de Amazon Route 53 para dos de las tres aplicaciones web de esta solución. La consola de administración se configura como Admin.domain.com
y la página de destino se configura como www.Domain.com.
La página de aplicación de comercio electrónico de ejemplo no recibe un alias de Route 53 hasta que se implementa un tenant.
Infraestructura del Tenant
Una vez creada la infraestructura de referencia, puede empezar a pensar más en la infraestructura necesaria para dar soporte a los tenants a medida que se incorporan a su aplicación SaaS.
La arquitectura que hemos seleccionado aquí utiliza un modelo de namespace por tenant para implementar nuestro aislamiento, que requiere la implementación de recursos independientes para cada tenant. A continuación, exploraremos este modelo de aislamiento con más detalle.
La arquitectura anterior ilustra cómo se implementan los microservicios de nuestra aplicación en nuestra infraestructura de referencia. Los hemos aterrizado en el mismo clúster que se utilizó para implementar los servicios compartidos del entorno. La diferencia clave es que ninguno de estos microservicios y namespaces se crean hasta que un tenant realmente se ha agregado.
Por supuesto, las construcciones necesarias para dar vida a estos microservicios tienen más partes móviles. El siguiente diagrama proporciona una vista más detallada de los elementos de nuestros entornos de tenants.
En cuanto al flujo básico aquí, tenemos los activos utilizados por la aplicación SaaS para acceder a cada uno de nuestros namespaces de tenants. Se utilizan grupos de usuarios y dominios independientes para autenticar y dirigir a los tenants a nuestro entorno.
A medida que avanza más abajo, la solución utiliza un controlador de entrada NGINX para enrutar el tráfico a nuestros namespaces. Otra solución que se puede utilizar aquí es AWS Load Balancer Controller.
Nuestros servicios de pedidos y productos representan el backend de nuestra aplicación de comercio electrónico de muestra. Aunque estos servicios se implementan desde el repositorio ECR compartido por todos los tenants, cada tenant obtiene su propia copia de estos microservicios, que se configuran con información específica del tenant en el momento de la implementación.
Todos nuestros artefactos específicos del tenant, incluidos los microservicios y los recursos de ingreso de NGINX, se implementan en su propio namespace. Asignamos una política de IAM para la cuenta de servicio del tenant, así como políticas de seguridad de pods y redes para mayor seguridad.
Los servicios AWS Code*, representados en la parte inferior de la figura 4, se utilizan como la «máquina» que organiza la configuración y la implementación de estos objetos en nuestro clúster de EKS. Los proyectos Code* se definen como recursos de CloudFormation con parámetros que sirven como marcadores de posición para los datos específicos del tenant.
A la derecha, notarás nuestras tablas de DynamoDB. Queríamos mostrar varios ejemplos de partición de datos en la solución SaaS de EKS. Nuestro microservicio de pedidos, por ejemplo, utiliza un modelo de partición de almacenamiento en silo en el que cada tenant tiene una tabla de DynamoDB independiente. Se crea una nueva tabla de pedidos para cada nuevo tenant que se agrega al sistema.
El microservicio del producto utiliza un modelo de partición agrupado en el que los datos del tenant se combinan en la misma tabla y se accede a través de una clave de partición que se rellena con un identificador de tenant.
Las tablas de pedidos están protegidas con roles de IAM que impiden el acceso de cualquier tenant cruzado. El acceso a las tablas de productos también se controla mediante roles de IAM. En este caso, hemos utilizado condiciones de IAM basadas en claves de partición específicas del tenant de la tabla DynamoDB.
Incorporación (Onboarding) de tenants
Los nuevos tenants se introducen en el sistema mediante un proceso de incorporación sin fricciones que orquesta todos los servicios necesarios para poner en marcha a ese tenant. Contar con una experiencia de incorporación automatizada y de baja fricción es clave para permitir que los proveedores de SaaS tengan un mecanismo escalable y repetible para introducir nuevos tenants.
Para esta solución, tenemos varias piezas móviles que se incluyen en el proceso de incorporación. En primer lugar, debemos crear un nuevo tenant y el usuario administrativo para ese tenant. A continuación, tenemos que configurar el namespace y las políticas de Kubernetes para el tenant, e implementar los microservicios de aplicaciones.
En la figura 5 se describe el flujo de incorporación. El proceso comienza con el llenado de un formulario de inscripción, que simula la típica página que ofrecerías como experiencia pública para los nuevos tenants. La aplicación de administración puede activar la incorporación.
Hemos incluido este flujo para ilustrar cómo sería tener esta misma experiencia de incorporación gestionada por un proceso interno. La clave es que ambos procesos se basan en el mismo mecanismo subyacente para incorporar a un tenant al sistema.
En los siguientes pasos se describe la secuencia de eventos involucrados durante el proceso de incorporación de tenants:
- El servicio de registro de tenants recibe una solicitud de la página de inicio o de la aplicación administrativa que incluye los datos de incorporación del tenant.
- El servicio de registro llama al servicio de administración de tenants para registrar los detalles del tenant en Amazon DynamoDB.
- El servicio de registro crea un nuevo grupo de usuarios para el tenant.
- El servicio de registro llama al servicio de administración de usuarios para crear el usuario de administración de tenants en el grupo de usuarios recién creado.
- El servicio de registro inicia el aprovisionamiento de los servicios de aplicaciones del tenant mediante AWS CodePipeline y AWS CodeBuild para orquestar la implementación de los recursos del tenant. Esto incluye crear el namespace para el tenant y la implementación de microservicios de productos y pedidos.
- Las políticas de seguridad de aislamiento del tenant se aplican a nivel de red y datos.
Más allá del aislamiento de los namespaces
Como se ha descrito anteriormente, utilizamos un modelo de namespace por tenant para crear una capa de aislamiento para los tenants y sus recursos dentro de un clúster de Amazon EKS.
Sin embargo, este método de forma predeterminada no proporciona un límite de aislamiento sólido para los recursos que se encuentran dentro de ese namespace. Debemos introducir componentes adicionales para evitar el acceso de cualquier tenant cruzado.
En este ejemplo, hemos utilizado políticas de red y seguridad de pods para evitar el acceso entre tenants a nivel del namespace del pod. Hemos utilizado roles de IAM para la cuenta de servicio para hacer cumplir el aislamiento.
Este enfoque introduce el aislamiento de credenciales, lo que garantiza que un contenedor solo pueda recuperar las credenciales del rol de IAM asociado a la cuenta de servicio a la que pertenece. Esto significa que un contenedor nunca puede acceder a las credenciales de un contenedor que pertenece a otro pod que se ejecuta en otro namespace.
A medida que continua en el diagrama de la Figura 6, puede ver cómo aplicamos el aislamiento a medida que cada recurso aislado intenta acceder a otro recurso de tenant (en este caso, tablas de DynamoDB). Existen dos variaciones diferentes de aislamiento para las tablas de productos y pedidos.
Para nuestro microservicio de pedidos, cada tenant tiene una tabla de pedidos independiente (utilizando un modelo de almacenamiento en silo). Tenemos políticas de IAM que restringen el acceso a nivel de la tabla de DynamoDB.
El microservicio del producto tiene una sola tabla para todos los tenants. En este escenario, nuestras políticas de IAM restringen el acceso a los elementos de la tabla.
Si bien estas configuraciones ayudan a aplicar nuestro modelo de aislamiento, también debe pensar en cómo aislarse a nivel de red. De forma predeterminada, se permite todo el tráfico de pod a pod en Kubernetes y, sin ningún control, todos los pods pueden comunicarse libremente con todos los demás pods dentro y entre los namespaces de un clúster de EKS.
Para evitar esta situación de acceso entre namespaces, hemos implementado políticas de red mediante Tigera Calico, lo que nos permite lograr el aislamiento de la red aplicando políticas de red detalladas a nivel de namespaces.
Conclusión
En esta publicación se examinan algunas de las consideraciones clave que pueden influir en la forma en que aborda el diseño y la creación de una solución SaaS con Amazon EKS. Debe quedar claro que la potencia y la flexibilidad de EKS también requieren que encuentre formas creativas de realizar algunos de los principios arquitectónicos fundamentales de SaaS.
A medida que investigue la aplicación de ejemplo SaaS de EKS que presentamos aquí, obtendrá una mejor idea de la experiencia integral general de crear una solución SaaS de EKS completa en funcionamiento en AWS. Esto debería proporcionarle una buena ventaja y, al mismo tiempo, permitirle moldearlo en torno a las políticas que se ajustan a las necesidades de su entorno SaaS.
Para obtener una visión más detallada de esta solución, le invitamos a que eche un vistazo al repositorio de soluciones. Allí encontrará instrucciones de implementación paso a paso, así como una guía más centrada en el desarrollo para ayudar a comprender todas las partes móviles del entorno.
Acerca de AWS SaaS Factory
AWS SaaS Factory ayuda a las organizaciones en cualquier etapa del recorrido de SaaS. Ya sea que busque crear nuevos productos, migrar aplicaciones existentes o optimizar las soluciones SaaS en AWS, podemos ayudarlo. Visite AWS SaaS Factory Insights Hub para descubrir más contenido técnico y empresarial y mejores prácticas.
Se recomienda a los creadores de SaaS que se comuniquen con su representante de cuentas para preguntar sobre los modelos de participación y trabajar con el equipo de AWS SaaS Factory.
Regístrese para mantenerse informado sobre las últimas noticias, recursos y eventos de SaaS de AWS.
Este artículo fue traducido del Blog de AWS en Inglés.
Sobre los autores
Toby Buckley es Arquitecto de Soluciones para Partners en AWS.
Ranjith Raman es Arquitecto de Soluciones para Partners en AWS.
Sobre los traductores
Armando Barrales es Arquitecto de Soluciones en AWS.
Rene Roldan es Arquitecto de Soluciones en AWS.