Ruta de modernización para las aplicaciones de .NET en Google Cloud

En este documento, se analizan las limitaciones comunes de las aplicaciones monolíticas y se describe un proceso gradual, pero estructurado, para modernizarlas.

Este documento está dirigido a arquitectos de nube, administradores de sistemas y directores de tecnología que están familiarizados con el ecosistema de Windows y .NET, y que quieran obtener más información sobre la modernización. Aunque este documento se centra en las aplicaciones de servidor personalizadas (como las apps de ASP.NET o de los servicios de Windows), puedes aplicar las lecciones a otros casos de uso.

Comparación entre aplicaciones heredadas y modernas: ¿por qué modernizarlas?

Modernizar las aplicaciones heredadas es un proceso largo. Los puntos de partida y de finalización del proceso, así como los beneficios asociados, dependen mucho del estado de tus aplicaciones y del tiempo y el esfuerzo que puedes dedicar a la modernización.

En el contexto de las aplicaciones de .NET, ¿qué es heredado y qué es moderno? Esta pregunta no es fácil de responder de forma exhaustiva o definitiva. Cada aplicación tiene necesidades específicas de herencia y modernización. Sin embargo, las aplicaciones heredadas comparten algunas limitaciones comunes.

En el siguiente diagrama, se resumen las características de las aplicaciones heredadas y las aplicaciones modernas basadas en la nube.

Diferencias entre las aplicaciones monolíticas y las aplicaciones modernas basadas en la nube.

Por lo general, una aplicación de .NET heredada es monolítica y se compila en .NET Framework, se aloja en un servidor de Microsoft Windows local y está conectada a un servidor local que ejecuta Microsoft SQL Server. Los detalles de tu arquitectura pueden diferir de estas características generales, pero la mayoría de las aplicaciones monolíticas tiene las siguientes limitaciones:

  • Necesidad de administrar servidores locales con Windows y SQL Server
  • Entornos de implementación limitados y costos de licencia asociados con la dependencia de Windows
  • Dificultad para actualizar las aplicaciones heredadas que se compilan en una arquitectura monolítica
  • Poca agilidad para planificar, presupuestar y escalar con recursos locales.

Las aplicaciones compiladas para una arquitectura basada en la nube ofrecen varios beneficios:

  • Sobrecarga de administración mínima mediante la integración con los servicios administrados.
  • Movilidad total con .NET Core y contenedores, sin dependencias de Windows ni costos de licencia asociados
  • Ruta de actualización de alta velocidad y basada en microservicios que se pueden implementar de forma independiente
  • Agilidad completa para escalar y definir presupuestos con una arquitectura sin servidores

En comparación con el enfoque local convencional, una arquitectura en la nube ofrece una forma más rentable, eficiente y resiliente para ejecutar tus aplicaciones. En un enfoque basado en la nube, tienes más flexibilidad para elegir dónde y cuándo implementar tus aplicaciones.

Ruta de modernización

Si bien los beneficios de una arquitectura basada en la nube son evidentes, la ruta a la nube podría no estar tan clara. La modernización de una arquitectura heredada de .NET a una basada en la nube no sigue un patrón único de tamaño. Como se muestra en el siguiente diagrama, la modernización implica una serie de pasos, en los que cada uno quita una limitación, aumenta las capacidades de la aplicación y genera oportunidades para las fases posteriores de la modernización.

Proceso, tecnologías y servicios involucrados en el proceso de modernización.

Los pasos para la modernización se agrupan en tres fases:

  1. Cambia de host en la nube (también conocido como lift-and-shift)
  2. Cambia de plataforma
  3. Rediseña la arquitectura y cambia la compilación

Evaluación y aprendizaje previos a la modernización

Antes de comenzar la modernización, debes prepararte. El primer paso es evaluar tus aplicaciones y sus dependencias a fin de determinar cuáles son adecuadas para modernizarse y cuáles no se pueden cambiar ni trasladar (por lo general, debido a razones normativas o porque son heredadas). Para obtener más información, consulta Migración a Google Cloud: evalúa y descubre tus cargas de trabajo.

De forma paralela a esta evaluación, tu equipo necesita aprender sobre las capacidades de la nube. Google Cloud ofrece certificaciones, guías técnicas y codelabs sobre Windows y .NET que pueden acelerar el proceso de aprendizaje.

Después de identificar qué aplicaciones se modernizarán, puedes comenzar a migrar tus aplicaciones convencionales a la nube tal como están o con cambios mínimos en el código o la configuración de la app.

Fase 1: Cambia el host en la nube

El objetivo principal de esta primera fase es transferir la carga de la administración del servidor de tus recursos locales a la infraestructura de nube. En esta fase, te aseguras de que tu infraestructura esté lista para la nube, de modo que puedas optimizarla en fases posteriores.

Migración manual frente a migración basada en herramientas

Por lo general, una migración lift-and-shift de aplicaciones de .NET basadas en Windows comienza con el traslado de instancias locales de Windows Server y SQL Server a instancias de máquina virtual (VM) de Compute Engine. Puedes realizar este proceso de forma manual o automatizarlo con la ayuda de una herramienta de migración.

En una migración manual, puedes usar las imágenes de Windows Server de Compute Engine para iniciar instancias. Google Cloud Marketplace también tiene soluciones listas para implementar en Compute Engine, como la solución de ASP.NET Framework, que brinda una VM de Windows Server que incluye IIS, SQL Express y ASP.NET.

Del mismo modo, puedes iniciar instancias de SQL Server desde imágenes de SQL Server o puedes usar directamente una solución más administrada: Cloud SQL para SQL Server.

Google Cloud también ofrece herramientas de migración como Migrate to Virtual Machines o VMware Engine para ayudarte a trasladar las VM de VMware locales a un entorno de VMware en Google Cloud

Después de configurar las VMs, por lo general, debes crear imágenes de VMs personalizadas para que puedas volver a crear instancias nuevas a pedido. Este paso también es importante para las plantillas de instancias, que se analizan más adelante en este documento.

Si necesitas servicios de dominio en la nube, puedes implementar un entorno de Active Directory de Microsoft tolerante a errores en Compute Engine con una nube privada virtual (VPC) o ir directamente a Servicio administrado para Microsoft Active Directory.

Conectividad local y en la nube

Cuando migras VM a la nube, es habitual mantener algunas cargas de trabajo en el entorno local; por ejemplo, si tienes aplicaciones que requieren hardware o software heredado, o si necesitas cumplir con requisitos legales y normativas locales. Necesitas una VPN o una solución de interconexión para conectar de manera segura los recursos locales y aquellos en la nube. Para conocer varias formas de crear y administrar esta conexión, además de otras consecuencias de ejecutar cargas de trabajo en nubes híbridas y locales, consulta Migración a Google Cloud: construye tu base.

Beneficios iniciales

Cuando termina la fase 1, tienes una infraestructura básica que se ejecuta en la nube y proporciona beneficios como los siguientes:

  • Optimizaciones de costos. Puedes crear un tipo personalizado de máquina (CPU, memoria y almacenamiento) y pagar por lo que usas; iniciar y detener las VM y los entornos de recuperación ante desastres cuando lo desees y solo pagar cuando se estén ejecutando, y obtener recomendaciones de redimensionamiento antes de la migración.
  • Más eficacia operativa. Puedes conectar discos persistentes a las VM y crear instantáneas para simplificar la creación de copias de seguridad y el restablecimiento.
  • Mayor confiabilidad. Ya no es necesario programar períodos de mantenimiento gracias a la migración en vivo.

Estos beneficios iniciales son útiles, pero se obtienen muchos más cuando comienzas a optimizar para la nube.

Fase 2: Cambiar de plataforma

Cuando rediseñas una plataforma, optimizas tu aplicación actualizando partes de sus componentes (como su base de datos, capa de almacenamiento en caché o sistema de almacenamiento), sin cambiar la arquitectura de la aplicación y con cambios mínimos en la base de código. El objetivo de la fase 2 es comenzar a usar funciones en la nube para mejorar la administración, resiliencia, escalabilidad y elasticidad de tu aplicación sin reestructurarla de manera significativa ni salir del entorno de VM.

Aprovecha Compute Engine

Compute Engine proporciona algunas características estándar que es recomendable explorar. Por ejemplo, puedes usar plantillas de instancias en Compute Engine para crear plantillas a partir de configuraciones de VM existentes. Los grupos de instancias son una flota de VM idénticas que te permiten escalar de manera eficiente el rendimiento y la redundancia de la aplicación. Además del balanceo de cargas simple y la redundancia, los grupos de instancias administrados tienen características de escalabilidad, como el ajuste de escala automático, y funciones de alta disponibilidad, como la reparación automática y las implementaciones regionales, además de funciones de seguridad, como las actualizaciones automáticas.

Con estas funciones, puedes permanecer en la VM, pero aumentar la resiliencia, redundancia y disponibilidad de tus aplicaciones sin necesidad de reestructurarlas por completo.

Busca reemplazos locales

A medida que trasladas tu aplicación a la nube, debes buscar oportunidades para reemplazar la infraestructura alojada por las opciones de la nube administrada de Google y los socios externos en Cloud Marketplace, que incluye lo siguiente:

  • Cloud SQL en lugar de SQL Server, MySQL o Postgres autoalojados. Cloud SQL permite enfocarte en administrar la base de datos en lugar de la infraestructura (como aplicar parches de seguridad a las VM de la base de datos o administrar copias de seguridad) con el beneficio adicional de quitar el requisito de una licencia de Windows.
  • Servicio administrado para Microsoft Active Directory en lugar de Active Directory autoalojado
  • Memorystore, en lugar de instancias autoalojadas de Redis.

Estos reemplazos no deberían requerir cambios de código y solo implican cambios mínimos en la configuración. Además, ofrecen las ventajas de la administración mínima, la seguridad mejorada y la escalabilidad.

Primeros pasos con los contenedores de Windows

Después de optimizar las funciones básicas para la nube, puedes comenzar a migrar de VM a contenedores.

Un contenedor es un paquete liviano que contiene una aplicación y todas sus dependencias. En comparación con ejecutar tus aplicaciones directamente en una VM, los contenedores te permiten hacerlo en varios entornos y de una manera más coherente, predecible y eficaz (especialmente si ejecutas varios contenedores en un mismo host). El ecosistema en torno a los contenedores (como Kubernetes, Istio y Knative) también proporciona una serie de funciones de administración, resiliencia y supervisión que pueden acelerar aún más la transformación de tu aplicación monolítica a un conjunto de microservicios enfocados.

Por un tiempo, la creación de contenedores era una característica exclusiva de Linux. Las aplicaciones de Windows no podían beneficiarse de los contenedores. Esto cambió con los contenedores de Windows y su compatibilidad adicional con Kubernetes y Google Kubernetes Engine (GKE).

Los contenedores de Windows son una opción si no deseas migrar aplicaciones de .NET Framework a .NET Core, pero de todos modos quieres aprovechar los beneficios de los contenedores (como agilidad, portabilidad y control). Debes elegir el SO adecuado al cual te orientarás según la versión de .NET Framework, y debes recordar que no toda la pila de Windows es compatible con los contenedores de Windows. Para conocer las limitaciones de este enfoque y sus alternativas, consulta Contenedores de .NET Core y Linux más adelante en este documento.

Después de crear contenedores para tu aplicación de .NET Framework en un contenedor de Windows, recomendamos que la ejecutes en un clúster de Kubernetes. Kubernetes proporciona funciones estándar, como detectar cuando un Pod de contenedor está inactivo y volver a crearlo, ajustar automáticamente la escala de un Pod, realizar lanzamientos o reversiones automáticos, y realizar verificaciones de estado. GKE incluye funciones como ajuste de escala automático de clústeres, clústeres regionales, planos de control con alta disponibilidad y asistencia para nubes híbridas y múltiples con Anthos. Si decides usar GKE o Anthos, puedes utilizar Migrate to Containers para simplificar y acelerar la migración de las VM de Windows a los contenedores. Migrate to Containers automatiza la extracción de aplicaciones de VM a contenedores sin necesidad de volver a escribir o rediseñar la arquitectura de las aplicaciones.

Si bien puedes obtener muchos beneficios usando las funciones correctas en Compute Engine, cambiarte a contenedores y GKE te ayuda a aprovechar tus VM al máximo. Para ello, empaqueta varios Pods en las mismas VM. Esta estrategia podría generar menos costos de VM y de licencias de Windows.

La administración declarativa de los contenedores de Windows y Linux con Kubernetes y GKE también puede optimizar la administración de tu infraestructura. Con la creación de contenedores, tu equipo está preparado para la siguiente fase de la modernización.

Fase 3: Rediseña la arquitectura y cambia la compilación

Rediseñar la plataforma es solo el comienzo para aprovechar al máximo la nube. Si transformas tu arquitectura en una plataforma basada en la nube, obtendrás varios beneficios, como los que se mencionan a continuación:

La migración hacia los servicios administrados

Cuando comiences a reescribir partes de tu aplicación, te recomendamos que inicies la transición de servicios alojados a servicios administrados. Por ejemplo, puedes usar lo siguiente:

Si bien necesitas código adicional para integrar tu aplicación en estos servicios, vale la pena invertir en ello, ya que transfieres el trabajo pesado de la administración de plataformas a Google Cloud. Las bibliotecas cliente de Google Cloud para .NET, Tools for Visual Studio y Cloud Code para Visual Studio Code pueden ayudarte a seguir usando las herramientas y el entorno de .NET mientras realizas la integración en esos servicios.

Los servicios administrados también pueden admitir operaciones para tu aplicación. Puedes almacenar los registros de tu app en Cloud Logging y enviar sus métricas a Cloud Monitoring, donde puedes crear paneles con métricas de servidor y aplicación. Google Cloud ofrece bibliotecas cliente de .NET para Cloud Logging, Cloud Monitoring y Cloud Trace.

Contenedores de .NET Core y Linux

Si tu aplicación es heredada de .NET Framework y solo se ejecuta en Windows, es posible que quieras seguir ejecutándola en un servidor de Windows en Compute Engine, o bien en un contenedor de Windows Server en GKE. Aunque este enfoque podría funcionar a corto plazo, puede limitar mucho tu desarrollo a largo plazo. Windows incluye tarifas de licencias y una huella de recursos generalmente mayor que la de Linux. Estos factores pueden generar un costo de propiedad más elevado a largo plazo.

.NET Core es la versión moderna y modular de .NET Framework. La orientación de Microsoft establece que .NET Core es el futuro de .NET. Aunque Microsoft planea admitir .NET Framework, las nuevas características se agregarán solo a .NET Core (y, en última instancia, a .NET 5). Incluso si aún deseas usar Windows, cualquier desarrollo nuevo debe ocurrir en .NET Core.

Uno de los aspectos más importantes de .NET Core es que es multiplataforma. Es decir, puedes crear contenedores para una aplicación de .NET Core en un contenedor de Linux. Los contenedores de Linux son más livianos que los de Windows y se ejecutan en más plataformas con mayor eficiencia. Este factor crea opciones de implementación para las aplicaciones de .NET y te libera de la dependencia de Windows y los costos de licencia asociados.

Porta aplicaciones de .NET Framework a .NET Core

Una buena forma de comenzar a pasar a .NET Core es leer la Descripción general de la portabilidad de .NET Framework a .NET Core. Las herramientas como .NET Portability Analyzer y .NET API Analyzer pueden ayudarte a determinar si las ensamblajes y las API son portátiles. Otras herramientas de portabilidad, como dotnet try-convert, pueden ser útiles.

Las herramientas externas pueden ayudarte a identificar problemas de compatibilidad y a decidir qué componentes migrar primero. En última instancia, debes crear proyectos de .NET Core, trasladar gradualmente tu código de .NET Framework al proyecto nuevo y solucionar cualquier incompatibilidad durante el proceso. Antes de transferir tu código, es fundamental organizar pruebas y, luego, probar tu funcionalidad después de que te portes. Recomendamos que uses pruebas A/B para probar el código antiguo y el nuevo. Con las pruebas A/B, puedes seguir ejecutando la aplicación heredada y dirigir a algunos usuarios a la aplicación nueva. Este enfoque te permite probar los resultados, la escalabilidad y la resiliencia de la aplicación nueva. Para ayudarte con las pruebas A/B, Google Cloud ofrece soluciones de balanceo de cargas, como Traffic Director.

Transformación cultural

La transformación de los servidores de .NET Framework y Windows a contenedores de .NET Core y Linux no es solo técnica. Este cambio requiere una transformación cultural en tu organización. El personal que solo está acostumbrado a usar entornos específicos de Windows deberá adaptarse a los entornos multiplataforma. Esta transformación cultural requiere tiempo y presupuesto para realizar capacitaciones en .NET Core, Linux y herramientas de contenedores como Docker y Kubernetes. Sin embargo, transformarse de una organización que solo usa Windows a una multiplataforma te permite acceder a un conjunto más grande de herramientas y habilidades.

Descomposición de aplicación monolítica

El traslado de .NET Framework a .NET Core puede generar varias preguntas, incluidas las siguientes:

  • ¿Se reescribe toda la aplicación en .NET Core?
  • ¿Divides tu aplicación en servicios más pequeños y los escribes en .NET Core?
  • ¿Solo escribes servicios nuevos en .NET Core?

La forma en que respondas estas preguntas debe abordar los beneficios, el tiempo y los costos asociados con cada enfoque. Es bueno tener un enfoque equilibrado en el que no reescribas todo de una sola vez. En su lugar, puedes escribir servicios nuevos en .NET Core y dividir la aplicación monolítica existente en servicios más pequeños en .NET Core a medida que surjan oportunidades. Los siguientes informes pueden ayudarte a planificar:

Opciones de implementación para contenedores de .NET Core

Como se menciona en Implementa apps de .NET en Google Cloud, tienes diferentes opciones para implementar contenedores de .NET Core en Google Cloud. A medida que deconstruyas tu aplicación monolítica en microservicios, recomendamos que uses más de una solución de hosting, según la arquitectura y el diseño de tus microservicios.

Responde las siguientes preguntas para decidir la mejor estrategia de hosting:

  • ¿Qué activa tu aplicación? Todas las soluciones de hosting son adecuadas para HTTP(S) estándar, pero si tu protocolo es TCP/UDP o un protocolo patentado, es posible que GKE sea tu única opción.
  • ¿Tu aplicación requiere hardware específico? Cloud Run ofrece una cantidad razonable pero limitada de RAM y CPU para cada solicitud. Cloud Run for Anthos ofrece más opciones de personalización, como GPU, más memoria y espacio en el disco.
  • ¿Cuáles son tus expectativas de escalamiento? Si tu aplicación tiene períodos de inactividad, las soluciones sin servidores como Cloud Run pueden ofrecerte la opción de reducir la escala verticalmente a cero.
  • ¿Qué tan importante es la latencia y qué tan tolerante es tu aplicación a los inicios en frío? Si la tolerancia a los inicios en frío es baja, debes considerar usar una cantidad mínima de instancias en Cloud Run o GKE con el ajuste de escala automático.

Te recomendamos que leas la documentación para cada entorno de hosting a fin de familiarizarte con sus capacidades, fortalezas y debilidades, y modelo de precios.

Como regla general, si quieres crear microservicios que entreguen solicitudes HTTP, debes implementar en Cloud Run siempre que sea posible y volver a GKE si deseas permanecer en el ecosistema de Kubernetes o si requieres más opciones de personalización. GKE también es la opción predeterminada si tienes un proceso de larga duración, como un proceso que escucha en una cola o una aplicación que usa protocolos distintos de HTTP(S).

Cloud Functions también es una buena opción de implementación sin servidores, pero no se analiza aquí, ya que Cloud Run proporciona la mayoría de las funciones que proporciona Cloud Functions y Cloud Functions no admite las versiones más recientes de .NET Core.

Kubernetes y GKE

Si deseas ejecutar en un entorno optimizado para contenedores, ese enfoque posiblemente involucre Kubernetes y su versión administrada, GKE. Kubernetes y GKE son especialmente útiles si planeas implementar muchos contenedores con diferentes requisitos y deseas un control detallado sobre cómo se implementa y administra cada uno de ellos.

Kubernetes está diseñado para ejecutar contenedores a gran escala y proporciona componentes esenciales como Pods, Services, Deployments y conjuntos de réplicas. Comprender y usar correctamente estas construcciones puede ser un desafío, pero te permiten transferir la mayor parte del trabajo pesado de administración de contenedores a Kubernetes. También son adecuadas para la arquitectura de microservicios, en la que un microservicio es un Deployment con un conjunto de Pods con balanceo de cargas detrás de un Service.

Además de Kubernetes, GKE ofrece funciones como el ajuste de escala automático de clústeres, la reparación automática y la actualización automática para simplificar la administración de Kubernetes, y características de seguridad como el aislamiento de contenedores y los registros privados. Aunque se te cobra por cada nodo en el clúster de GKE, GKE admite VM interrumpibles para reducir costos.

GKE puede administrar contenedores de Windows y Linux. Esto es útil si deseas mantener un solo entorno híbrido para aplicaciones basadas en Windows y apps modernas basadas en Linux.

Knative y Cloud Run

Knative y su versión administrada, Cloud Run, proporcionan un entorno de contenedores sin servidores para tus contenedores de .NET Core. Los contenedores sin servidores ofrecen beneficios como el aprovisionamiento, el ajuste de escala automático y el balanceo de cargas sin sobrecarga de administración de la infraestructura.

Para implementar contenedores en un clúster de Kubernetes, Knative proporciona una superficie de API que es de mayor nivel y más ligera que Kubernetes. Knative puede ayudarte a evitar las complejidades de Kubernetes, lo que te facilita la implementación de contenedores.

Cloud Run sigue a la API de Knative, pero se ejecuta en la infraestructura de Google, lo que elimina la necesidad de clústeres de Kubernetes. Cloud Run ofrece una opción sin servidores para los contenedores. Según la configuración predeterminada, los contenedores en Cloud Run tienen un ajuste de escala automático y se facturan durante la duración de la solicitud. El tiempo de implementación se expresa en segundos. Cloud Run también proporciona funciones útiles, como revisiones y división del tráfico.

Cloud Run for Anthos es la versión más flexible de Cloud Run que ofrece la simplicidad de Knative y Cloud Run con la flexibilidad operativa de Kubernetes. Por ejemplo, Cloud Run on Anthos te permite agregar GPU a instancias subyacentes que ejecutan tus contenedores o te permite escalar verticalmente tu aplicación a muchos contenedores.

Cloud Run se integra en otros servicios, como Pub/Sub, Cloud Scheduler, Cloud Tasks y los backends, como Cloud SQL. Se puede usar para frontends web con ajuste de escala automático o microservicios internos que se activan mediante eventos.

Modernización de operaciones

La modernización no se trata solo del código de tu aplicación. Se aplica a todo su ciclo de vida: cómo se compila, se prueba, se implementa y se supervisa. Por lo tanto, cuando pienses en la modernización, debes considerar las operaciones.

Cloud Build puede ayudarte a modernizar y automatizar el ciclo de compilación, prueba e implementación de las aplicaciones. Cloud Build no solo proporciona compiladores para .NET Core, sino que también se integra en el análisis de vulnerabilidades de Container Registry y en la autorización binaria para evitar que las imágenes compiladas a partir de código fuente desconocido o repositorios no seguros se ejecuten en tu entorno de implementación.

Google Cloud's operations suite (anteriormente Stackdriver) ofrece varios servicios que te permiten modernizar la observabilidad de tu aplicación:

Puedes usar la biblioteca Google.Cloud.Diagnostics.AspNetCore para integrar de manera sencilla Google Cloud's operations suite en tus aplicaciones de ASP.NET Core. Para exportar las métricas de OpenTelemetry a operations suite, puedes usar la biblioteca OpenTelemetry.Exporter.Google Cloud operations suite.

Para obtener más información sobre cómo la modernización se aplica a los procesos y la cultura del equipo, consulta las soluciones de Google Cloud para DevOps.

¿Qué sigue?