Blog de Amazon Web Services (AWS)

Migración de aplicaciones ASP.NET a contenedores mediante AWS App2Container (A2C)

Por Márcio Morales, Arquitetco de Soluciones en Tech Microsoft,
Caio Ribeiro César, Arquitetco de Soluciones AWS Brasil y
Javier Gálvez, Arquitetco de Soluciones en Tech Microsoft

 

Cada día, hay mas empresas que están migrando y ejecutando aplicaciones heredadas o legacy sobre arquitecturas de contenedores altamente escalables como Amazon Elastic Container Service (ECS) y Amazon Elastic Kubernetes Services (Amazon EKS). Esto se debe a que las aplicaciones legacy, muchas de ellas basadas en tecnologías de Windows, pueden ser difíciles de mantener y administrar y a menudo requieren de una gran cantidad de infraestructura de base para mantenerlas. Dado que muchas de las aplicaciones legacy ya no reciben sus actualizaciones de software y que se ejecutan sobre sistemas operativos que han llegado al fin de su ciclo de vida y alcanzado a su vez el status de fin de soporte, los clientes están buscando nuevas maneras de diseñar, ejecutar y administrar los ciclos de vida de aplicaciones legacy.

Amazon Web Services ha lanzado AWS App2Container, que es un servicio que ayuda a nuestros clientes a crear contenedores desde aplicaciones legacy sin realizar ningún cambio en el código. Esto ayuda a los clientes a migrar y ejecutar aplicaciones legacy basadas en tecnologías de Microsoft sobre Amazon ECS y Amazon EKS de la misma manera que se ejecutan hoy en día las aplicaciones modernas. AWS App2Container es una aplicación cliente-servidor que analiza, extrae, almacena y ayuda a migrar aplicaciones ASP.NET y JAVA a un entorno de Amazon ECS o Amazon EKS, y todo esto en unos pocos pasos. Además tenga en cuenta que AWS proporciona soporte de producción para ejecutar Kubernetes en Windows y es totalmente compatible con nodos de trabajo (worker nodes) basados en Windows, lo que hace que su proceso de modernización sea muy sencillo.

En este tutorial, les mostraremos como contenerizamos una aplicación ASP.NET llamada DNN Platform, que es un sistema de administración de contenido .NET de código abierto desarrollado en ASP.NET y SQL Server. Para este tutorial, la base de datos utilizada por la aplicación DNN fue migrada anteriormente a una  Amazon Relational Database Service (Amazon RDS).

 

Requisitos previos

Para este tutorial, usted debe tener listo los siguientes pre requisitos:

 

Tutorial

En este tutorial vamos a mostrar y ejecutar los siguientes pasos:

  • Creación de un usuario y una política de IAM para utilizarlo con AWS App2Container.
  • Instalación de App2Container en el servidor que preparamos anteriormente para demostrar la ejecución remota de esta herramienta.
  • Crear el inventario y ejecutar el análisis de la aplicación a ser migrada.
  • Extraer la aplicación.
  • Contenerizar la aplicación
  • Generar los artefactos necesarios para desplegar la aplicación contenerizada en ECS o EKS
  • Ejecute la aplicación en un servicio de contenedor administrado.

Paso 1: Crear un usuario y una política de IAM para utilizar AWS App2Container.

a. Cree un usuario de IAM en la interfaz cli de AWS ejecutando el siguiente comando: ( Previamente a este paso, usted deberá configurar la autenticación del cli contra su cuenta de AWS.)

PowerShell

New-IAMUser -Path "/ps-created-users/" -UserName "app2container"

 

 

b. Cree un archivo JSON que contenga la política de IAM que coincida con los requerimientos de Amazon EKS o Amazon ECS, utilizando los ejemplos de la documentación oficial.
c. Cree la política de IAM basada en el archivo JSON generado en el paso anterior y guarde el valor ARN que se obtenga, ya que se utilizará en el siguiente paso.

PowerShell

New-IAMPolicy -PolicyName "app2container" -policyDocument (Get-Content -Raw app2Container.json)

d. Adjunte la política de IAM creada en el paso anterior al usuario de IAM recién creado ejecutando el siguiente comando:

 

 

PowerShell

Register-IAMUserPolicy -UserName app2container -PolicyArn arn:aws:iam::ID-DA-SUA-CONTA:policy/app2container

Paso 2: Instalación de App2Container para ejecutarlo de forma remota

En el blog original de App2Container que fue escrito en julio del 2020, se explicaba el procedimiento para ejecutar App2Container en el mismo servidor donde la aplicación se estaba ejecutando, pero en este nuevo blog vamos a utilizar una nueva versión de App2Container que tiene nuevas funcionalidades. Una de estas nuevas características es la posibilidad de ejecutar App2Container desde un servidor remoto utilizando Windows Remote Shell (WinRM) y eliminar la necesidad de instalar App2Container en el mismo servidor de aplicaciones.

Importante: Desde este enlace podrá acceder al procedimiento completo de App2Container para ejecutarlo en el modelo de acceso remoto.

A continuación les mostraremos los pasos necesarios para configurar App2Container y ejecutar la migración de una aplicación que esta corriendo en un servidor remoto.

En el servidor donde se instalará App2Container debemos realizar los siguientes pasos:

  1. Desde PowerShell ejecutar el comando ¨Set-ExecutionPolicy¨
  2. Vamos a crear un secreto en AWS, que luego se utilizará en la configuración de App2Container ( por ejemplo las credenciales del servidor remoto)
  3. Ejecución del comando «app2container remote configure» donde vamos a configurar la dirección IP del servidor remoto donde la aplicación DNN se esta ejecutando y proveer el nombre del secreto que anteriormente creamos.

 

 

En el servidor de aplicaciones, ejecutemos el siguiente paso para realizar validar que WinRM esta ejecutándose y que el puerto del firewall esta abierto, para esto vamos a ejecutar en la consola de PowerShell: WinRMSetup.ps1.

 

 

Desde el servidor donde ejecutaremos App2Container debemos realizar los siguientes pasos:

a. Descargue AWS App2Container y descomprima el contenido en el servidor.

b. Para instalar AWS App2Container, ejecute el script install.ps1 en una sesión de PowerShell elevada

 

 

c. Configure la herramienta AWS App2Container utilizando el usuario y la política de IAM recién creados configurados a través de aws cli (aws configure) y proporcione los datos del Bucket de S3 creado anteriormente con el siguiente comando:

app2container init

 

 

¡Listo! AWS App2Container está configurado y listo para ser usado en este servidor.

Paso 3: Inventario y análisis de la aplicación a ser migrada

  1. Ahora ejecutaremos el comando App2Container en modo remoto desde la máquina que configuramos para este propósito contra al servidor de aplicaciones:

app2container remote inventory --target ServidordeAplicação_IP/NomeDNS

 

 

En este paso, se muestran todos los sitios del servidor remoto del IIS que la herramienta puede modernizar y convertir a contenedores. Es importante tener en cuenta que AWS App2Container generó un UID (por ejemplo: iis-dnn-5510d5ca0b2b) por cada aplicación, y que a su vez se puede visualizar en el archivo «inventory.json». El UID se utiliza en todos los pasos siguientes y juega un papel esencial en la distinción de cada aplicación.

{

                                "iis-default-web-site-a444e5c46d62": {

                                                                "siteName": "Default Web Site",

                                                                "bindings": "http/*:80:",

                                                                "applicationType": "iis",

                                                                "discoveredWebApps": []

                                },

                                "iis-dnn-5510d5ca0b2b": {

                                                                "siteName": "dnn",

                                                                "bindings": "http/*:80:",

                                                                "applicationType": "iis",

                                                                "discoveredWebApps": []

                                }

}

2. Utilizando el UID generado en la ejecución anterior, revise y analice la aplicación ejecutando el siguiente comando:

app2container remote analyze --application-id APP-UID –target IP/NomeDNS

 

 

En esta ejecución, el comando App2Container analiza y genera un archivo de reporte denominado analysis.json. El informe proporciona un análisis de la aplicación, así como parámetros opcionales que pueden ser utilizados en el proceso de modernización a contenedores para el siguiente paso.

Comprender este archivo de análisis es un paso crucial en todo el proceso. ¡Vamos a analizarlo!

 

{ 

    "Version": "2012-10-17", 

    "Statement": [ 

        { 

            "Sid": "SectionForS3Access", 

            "Action": [ 

                "s3:DeleteObject", 

                "s3:GetBucketAcl",

                "s3:GetBucketLocation",

                "s3:GetObject", 

                "s3:GetObjectAcl", 

                "s3:ListAllMyBuckets", 

                "s3:ListBucket", 

                "s3:PutObject", 

                "s3:PutObjectAcl" 

            ], 

            "Effect": "Allow", 

            "Resource": "<user-provided-bucket-ARN>" 

        }, 

        { 



            "Sid": "SectionForS3ReadAccess", 



            "Effect": "Allow", 

            "Action": [ 

                "s3:ListBucket", 

                "s3:GetBucketAcl" 

            ], 

            "Resource": "arn:aws:s3:::*" 

        }, 

        { 

            "Sid": "SectionForECRAccess", 

            "Action": [ 

                "ecr:BatchCheckLayerAvailability", 

                "ecr:BatchDeleteImage", 

                "ecr:BatchGetImage", 

                "ecr:CompleteLayerUpload", 

                "ecr:CreateRepository", 

                "ecr:DeleteRepository", 



                "ecr:DescribeImages", 

                "ecr:DescribeRepositories", 

                "ecr:GetAuthorizationToken", 

                "ecr:GetDownloadUrlForLayer", 

                "ecr:GetRepositoryPolicy", 



                "ecr:InitiateLayerUpload", 

                "ecr:ListImages", 

                "ecr:PutImage", 

                "ecr:TagResource", 

                "ecr:UntagResource", 

                "ecr:UploadLayerPart" 

            ], 

            "Effect": "Allow", 

            "Resource": "<resource-ARNs>" 

        }, 

        { 

            "Sid": "SectionForECSWriteAccess", 

            "Action": [ 



                "ecs:CreateCluster", 

                "ecs:CreateService", 

                "ecs:CreateTaskSet", 

                "ecs:DeleteCluster", 

                "ecs:DeleteService", 

                "ecs:DeleteTaskSet", 

                "ecs:DeregisterTaskDefinition", 

                "ecs:Poll", 

                "ecs:RegisterContainerInstance", 



                "ecs:RegisterTaskDefinition", 

                "ecs:RunTask", 

                "ecs:StartTask", 

                "ecs:StopTask", 



                "ecs:SubmitContainerStateChange", 

                "ecs:SubmitTaskStateChange", 

                "ecs:UpdateContainerInstancesState", 

                "ecs:UpdateService", 

                "ecs:UpdateServicePrimaryTaskSet", 

                "ecs:UpdateTaskSet" 

            ], 

            "Effect": "Allow", 

            "Resource": "<resource-ARNs>" 

        }, 

        { 

            "Sid": "SectionForPassRoleToECS", 

            "Effect": "Allow", 

            "Action": "iam:PassRole", 

            "Resource": "<ARN for ecsTaskExecutionRole>" 



        }, 

        { 

            "Sid": "SectionForECSReadAccess", 

            "Action": [ 

                "ecs:DescribeClusters", 

                "ecs:DescribeContainerInstances", 

                "ecs:DescribeServices", 

                "ecs:DescribeTaskDefinition", 

                "ecs:DescribeTaskSets", 



                "ecs:DescribeTasks", 

                "ecs:ListClusters", 

                "ecs:ListContainerInstances", 

                "ecs:ListServices", 

                "ecs:ListTaskDefinitionFamilies", 

                "ecs:ListTaskDefinitions", 

                "ecs:ListTasks" 

            ], 

            "Effect": "Allow", 

            "Resource": "*" 

        }, 



        {

            "Sid": "SectionForCodeCommitAccess",

            "Effect": "Allow",

            "Action": [

                "codecommit:GetRepository",

                "codecommit:GetBranch",

                "codecommit:CreateRepository",

                "codecommit:CreateCommit",

                "codecommit:TagResource"

            ],

            "Resource": "arn:aws:codecommit:*:*:*"

        },

        {

            "Sid": "SectionForByoVPC",

            "Effect": "Allow",

            "Action": [

                "ec2:DescribeInternetGateways",

                "ec2:DescribeRouteTables",

                "ec2:DescribeSubnets",

                "ec2:DescribeVpcs"

            ],

            "Resource": "*"

        },

        {

          "Sid": "SectionForEC2",

          "Effect": "Allow",

          "Action": [

             "ec2:DescribeKeyPairs",

             "ec2:CreateKeyPair",

             "ec2:DescribeAvailabilityZones" 

          ],

          "Resource": "*"

        },

        { 

            "Sid": "SectionForMetricsService", 

            "Effect": "Allow", 

            "Action": "execute-api:invoke", 

            "Resource": "arn:aws:execute-api:us-east-1:*:*/prod/POST/put-metric-data" 

        },

        { 

          "Sid": "SectionForUploadSupportBundleService", 

          "Effect": "Allow", 

          "Action": "execute-api:invoke", 

          "Resource": "arn:aws:execute-api:us-east-1:*:*/prod/POST/put-log-data" 

        },

        {

            "Sid": "SectionForSecretManagerAccess",

            "Action": [

                "secretsmanager:GetSecretValue",

                "secretsmanager:DescribeSecret"

            ],

            "Effect": "Allow",

            "Resource": "arn:aws:secretsmanager:<user's region>:<user's account ID>:secret:a2c/*"

        }

    ] 

}

 

    • El atributo «containerBaseImage» es la imagen base de Windows seleccionada en el Registro de Contenedores de Microsoft. Usted tiene la opción de cambiarlo y usar su imagen base personalizada de Windows. Es importante tener en cuenta que la imagen base de Windows debe coincidir con la misma versión de Windows en el clúster de Amazon ECS y/o Amazon EKS.
    • El atributo «imageRepositoryName» es el nombre del repositorio de Amazon Elastic Container (ECR) creado por este mismo proceso para almacenar la imagen de contenedor generada por AWS App2Container. Tenga en cuenta que usted puede elegir un repositorio existente o cambiar el nombre si lo desea.
    • El atributo «imageTag» es el TAG creado para la nueva imagen del contenedor.
    • La opción «IncludeWebApplications» se puede modificar si usted desea incluir otros sitios adicionales de IIS que pueden formar parte de su aplicación web.
    • El atributo «additionlExposedPorts» es una opción para publicar puertos adicionales en lugar del puerto 80 (http) en el contenedor si es que usted lo desea.
    • La opción «appIncludeFiles» permite incluir archivos adicionales que no forman parte del sitio Web de IIS, pero podrían ser requeridos por la aplicación como por ejemplo un archivo DLL.

    Entonces como podrán observar este proceso de análisis produce el archivo report.txt que contiene información como la versión del sistema operativo Windows Server, la configuración de IIS,  grupo de aplicaciones, enlaces o bindings,  directorios y características instaladas en el Windows Server mas allá de IIS. Este archivo contiene además el nombre y ubicación del archivo y el número de la línea de ubicación del parámetro donde se puede cambiar los detalles de autenticación y conexión de la base de datos de la aplicación.

Paso 4. Extracción de la Aplicación

Ejecute el siguiente comando «remote extract»  para generar un archivo comprimido de la aplicación analizada y que opcionalmente podría ser subida al bucket S3 que se especificado en pasos anteriores de este blog. Este archivo contiene todos los archivos necesarios para crear la imagen del contenedor.

app2container remote extract --application-id –target IP/NomeDNS APP-UID

 

 

Paso 5. Migre la aplicación a un contenedor.

Crear un archivo Dockerfile desde cero no es una tarea simple. Al escribir Dockerfiles se debe describir varios pasos en la construcción de la aplicación para minimizar el número de capas y puntos de entrada. AWS App2Container simplifica el proceso de creación de la imagen del contenedor mediante la generación de un Dockerfile completo. A continuación podrán observar los pasos en este proceso:

  1. En el área de trabajo donde vamos a crear el nuevo archivo Dockerfile. Como se explico al principio , en la instancia donde estamos ejecutado la aplicación App2Container estamos utilizando una AMI optimizada para Amazon ECS. Esta instancia viene con DockerMsftProvider ya instalado y con el servicio iniciado, lo cual nos permite ejecutar el comando que nos brindo el paso anterior:

app2Container containerize --input-archive C:\Users\Administrator\AppData\Local\app2container\remote\192.168.5.17\iis-dnn-5510d5ca0b2b\iis-dnn-5510d5ca0b2b.zip

 

2. Después que se ejecuto este proceso, acceda al directorio del espacio de trabajo para ver la siguiente estructura de directorios/archivos:

 

3. Seleccione el directorio «Artifacts», que es el directorio que App2Container utiliza para construir la imagen del contenedor.

 

 

Nota: El directorio «DNN» que es el nombre del sitio Web de IIS que contiene todos los archivos de aplicación Web.

Acá vamos a encontrar varios archivos:

  • Dockerfile: Este es el documento Dockerfile generado por AWS App2Container basado en la configuración actual de IIS y que de ser necesario se podría editar para alguna configuración adicional.
  • ps1: Este es el punto de entrada que se utilizará para enviar los logs del IIS a la consola Docker.
  • Podemos utilizar msi para restaurar la configuración completa de IIS desde el entorno actual de producción para utilizarla en la imagen del contenedor de Windows.
  • WIN-KU.zip es la copia de seguridad de IIS generada por AWS App2Container y se utiliza con WebDeploy en el caso de una restauración de la configuración de IIS a la imagen del contenedor de Windows.

 

# escape= `
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2-windowsservercore-ltsc2019
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

RUN Remove-Website 'Default Web Site';

# Set up Website: dnn
RUN New-Item -Path 'C:\inetpub\dnn' -Type Directory -Force;
RUN if(-NOT (Get-IISAppPool 'dnn')) {New-WebAppPool -Name 'dnn' }
RUN New-Website -Name 'dnn' -PhysicalPath 'C:\inetpub\dnn' -Port 80 -ApplicationPool 'dnn' -Force;
COPY "dnn" "C:\inetpub\dnn"
RUN $path='C:\inetpub\dnn'; `
    $acl = Get-Acl $path; `
    $newOwner = [System.Security.Principal.NTAccount]('BUILTIN\IIS_IUSRS'); `
    $acl.SetOwner($newOwner); `
    dir -r $path | Set-Acl -aclobject  $acl

EXPOSE 80

# Windows Authentication was not detected. Please Uncomment the below RUN commands if you want to use Windows Authentication."
# AppPool's Identity is set as Network Service to enable Windows Authentication using GMSA.
# RUN Install-WindowsFeature -Name Web-Windows-Auth -IncludeAllSubFeature
# RUN Import-Module WebAdministration; Set-ItemProperty 'IIS:\AppPools\dnn' -name processModel.identityType -value 2
# RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/anonymousAuthentication' -Name Enabled -Value False -PSPath 'IIS:\' -Location 'dnn'
# RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/windowsAuthentication' -Name Enabled -Value True -PSPath 'IIS:\' -Location 'dnn'

# Included files:

# Export additional ports 

# Set up log volumes if needed, for example: 
# VOLUME C:\inetpub\logs
# VOLUME C:\yourApp\App_Data\Logs

# The following Windows features are installed on your host, but not in the container.
# You can uncomment the ones you want to have them installed while building docker image.
# RUN Install-WindowsFeature -Name File-Services -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name FS-FileServer -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Web-Mgmt-Tools -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Web-Mgmt-Console -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name NET-Framework-Features -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name NET-Framework-Core -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name InkAndHandwritingServices -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Media-Foundation -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name FS-SMB1 -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name User-Interfaces-Infra -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Gui-Mgmt-Infra -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Desktop-Experience -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Gui-Shell -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name PowerShell-V2 -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name PowerShell-ISE -IncludeAllSubFeature

# Uncomment the following section will restore your server configuration in your container.
# COPY 'WIN-7RTMG2CCH7P_WebServer_20210310193928.zip'  'C:\temp\WIN-7RTMG2CCH7P_WebServer_20210310193928.zip'
# COPY 'WebDeploy_amd64_en-US.msi'  'C:\temp\WebDeploy_amd64_en-US.msi'
# RUN Start-Process 'C:\temp\WebDeploy_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
# RUN Add-PSSnapin 'WDeploySnapin3.0' ; Restore-WDServer -Package 'C:\temp\WIN-7RTMG2CCH7P_WebServer_20210310193928.zip'

 

En este archivo Dockerfile, podemos ver que en el archivo analysis.json que genero el App2Container selecciona la imagen base desde la aplicación ASP.NET. Como comentamos anteriormente, tome nota usted puede editar esta información y elegir otra imagen base según sea necesario,  al hacerlo solo tenemos que asegurarnos de que la nueva imagen coincida con la versión del OS del Container Host.

Los contenedores de Windows no están unidos a un dominio. Para utilizar la autenticación de Windows en un contenedor de Windows se requiere el uso de gMSA y Authentication Changes en IIS (consulte los siguientes artículos para ECS y EKS ). AWS App2Container prepara la imagen del contenedor para soportar la autenticación de Windows mediante la adición de las siguientes opciones de configuración en el Dockerfile:

  • Cambiar el usuario configurado en el IIS Application Pool, por una cuenta de servicio ¨Network Service¨
  • Instalación de la característica IIS ¨Windows Authentication¨
  • Cambiar la autenticación de IIS para deshabilitar la autenticación anónima ¨Anonymous Authentication¨ y habilitar la autenticación de Windows ¨Windows Authentication¨.

App2Container también proporciona dos scripts de PowerShell como outputs al comando “app2container containerize” junto a un archivo con instrucciones. El primer script de  PowerShell DomainJoinAddTosecGroup.ps1 une el host contenedor y lo agrega a un grupo de seguridad de Active Directory. El segundo script de PowerShell CreateCreredSpecFile.ps1 crea el gMSA, concede acceso al grupo de seguridad de AD para recuperar la contraseña de gMSA y genera el archivo de credspec ( credenciales ) Docker.

Paso 6. Genere los artefactos de despliegue para ejecutar la aplicación contenerizada en ECS o EKS.

  1. De forma predeterminada, AWS App2Container genera los artefactos que se utilizarán en un entorno de Amazon ECS, pero usted también puede cambiarlos para generar artefactos que se utilizarían en un entorno de Amazon EKS.

Si usted abre el archivo deployment.json generado por app2container

 

 

Observe que hay varios parámetros de configuración. Entre ellos, estos dos parámetros:

  • CreateECSArtifacts: true
  • CreateeEKSArtifacts: false

Si cambiamos el valor de CreateEKSArtifacts a «true» y el valor de CreateECSArtifacts a «false» , app2container generará los artefactos necesarios para Amazon EKS en lugar de Amazon ECS.

 

{

       "a2CTemplateVersion": "1.0",

       "applicationId": "iis-dnn-c5654c20",

       "imageName": "iis-dnn-c5654c20",

       "exposedPorts": [

              {

                     "localPort": 80,

                     "protocol": "http"

              }

       ],

       "environment": [],

       "ecrParameters": {

              "ecrRepoTag": "latest"

       },

       "ecsParameters": {

              "createEcsArtifacts": false,

              "ecsFamily": "iis-dnn-c5654c20",

              "cpu": 2,

              "memory": 4096,

              "dockerSecurityOption": "",

              "enableCloudwatchLogging": false,

              "publicApp": true,

              "stackName": "a2c-iis-dnn-c5654c20-ECS",

              "resourceTags": [

                     {

                            "key": "example-key",

                            "value": "example-value"

                     }

              ],

              "reuseResources": {

                     "vpcId": "",

                     "reuseExistingA2cStack": {

                            "cfnStackName": "",

                            "microserviceUrlPath": ""

                     },

                     "sshKeyPairName": "",

                     "acmCertificateArn": ""

              },

              "gMSAParameters": {

                     "domainSecretsArn": "",

                     "domainDNSName": "",

                     "domainNetBIOSName": "",

                     "createGMSA": false,

                     "gMSAName": ""

              }

       },

       "eksParameters": {

              "createEksArtifacts": true,

              "stackName": "a2c-iis-dnn-c5654c20-EKS",

              "reuseResources": {

                     "vpcId": "",

                     "reuseExistingA2cStack": {

                            "cfnStackName": ""

                     },

                     "sshKeyPairName": ""

              },

              "gMSAParameters": {

                     "domainSecretsArn": "",

                     "domainDNSName": "",

                     "domainNetBIOSName": "",

                     "createGMSA": false,

                     "gMSAName": ""

              }

       }

}

b. Para gerar os artefatos de aplicativos a serem usados ​​com o Amazon ECS ou o Amazon EKS, execute o comando abaixo (como pré-requisito, o bucket de S3 deve ter sido configurado na etapa de app2container init).

app2container generate app-deployment --application-id APP-UI

 

 

2. Después de ejecutar el comando podemos ver los siguientes archivos:

 

 

  • EksDeployment Directory contiene una plantilla de CloudFormation para implementar el clúster de EKS y los nodos de Windows.
  • yaml es el archivo de manifiesto que podemos utilizar para implementar Windows Pod en Amazon Elastic Kubernetes Services (Amazon EKS).
  • yaml es el archivo de manifiesto que podemos utilizar para implementar el servicio de Kubernetes en Amazon Elastic Kubernetes (Amazon EKS).
  • json es el archivo de manifiesto que podemos utilizar para la implementación de un pipeline de CI /CD que se podría utilizar junto con un clúster de Amazon ECS o de Amazon EKS.

Paso 7. Ejecute la aplicación en un servicio de contenedor administrado.

  1. Ejecute comandos para crear un servicio para la aplicación y un pod en nuestro clúster EKS.

 

kubectl apply -f eks_service.yaml

kubectl apply -f eks_deployment.yaml

 

 

2. Confirme que el pod está funcionando. El estado debe ser «1/1» en la sección READY y «running» en la sección STATUS como abajo se detalla, ejecutando el siguiente comando:

kubectl get pod

 

 

3. A través de su navegador web, acceda al Elastic Load Balancer (ELB) creado por el clúster de Amazon EKS. El valor asignado al ELB, puede ser visualizado desde los resultados de salida del proceso del CloudFormation. Este componente redirigirá la petición al pod donde la aplicación se este ejecutando.

 

¡Listo! Usted acaba de migrar su aplicación legacy ASP.NET a una arquitectura basada en contenedores mediante la herramienta AWS App2Container (A2C).

Como se mencionó anteriormente, en el laboratorio utilizado para este blog elegimos el servicio de Amazon Kubernetes Service (EKS), pero nada nos impide que ejecutemos nuestra aplicación sobre un clúster de Amazon Elastic Container Service (ECS).

Si desea ver una lista con características de cada uno de estos productos, haga clic aquí.

 

Puntos a considerar

Estado de sesión: Si su aplicación almacena el estado de sesión en la memoria, el camino para escalar la aplicación en contenedores podría ser un poco más arduo. Cada contenedor podría contener una información de estado diferente y, en consecuencia, cada solicitud del usuario a la aplicación podría comportarse de manera diferente. Para resolver este problema, podemos utilizar proxis reversos que estén configurados con una función de sticky sessions para intentar que el pedido del usuario siempre llegue al mismo contenedor. Este tipo de soluciones son de la capa de red, pero tenga en cuenta que podemos también manejar el estado de sesión en la capa de aplicación mediante la integración de una base de datos semiestructurada (como DynamoDB ) o incluso soluciones de almacenamiento de sesión en  caché (Elasticache). Dicho esto, por lo general recomendamos utilizar aplicaciones que no mantengan el estado de la sesión en si mismas para simplificar la arquitectura de la aplicación.

 

 

Conclusión

La contenerizacion le permitirá unificar la infraestructura necesaria para operar sus aplicaciones legacy, además que le ayudará a ahorrar en costos de infraestructura y administración. Específicamente, App2Container le ayuda a convertir estas aplicaciones legacy a contenedores y estandarizarlas bajo un único conjunto de herramientas para monitorear, operar el entorno así como habilitar practicas modernas como lo es la entrega de software continua.

Para obtener información adicional sobre cómo monitorear los Pods de Windows de Amazon EKS, le recomendamos leer este  blog de AWS. Para obtener más información sobre la persistencia de datos en contenedores de Windows que se ejecutan en Amazon EKS, consulte este  blog de Amazon.

Para obtener más información sobre la migración de Windows Server o SQL Server, visite nuestro sitio web de Windows en AWS. Para obtener más información sobre cómo AWS puede ayudarle a modernizar sus aplicaciones legacy de Windows, consulte nuestra página de Modernización de Windows.

Y si está interesado, no dude en ponerse en contacto con nosotros para que lo ayudemos en su viaje a la modernización hoy mismo!

 


Sobre los autores

Marcio Morales trabaja como arquitecto de soluciones especializadas en tecnología de Microsoft y sirve como Experto en Materia (SME) para soluciones de contenedores de Windows en la plataforma AWS.

 

 

 

 

Caio Ribeiro Cesar trabaja actualmente como arquitecto de soluciones especializadas en tecnología de Microsoft en la nube de AWS. Comenzó su carrera profesional como administrador de sistemas, que continuó durante más de 14 años en áreas como Seguridad de la Información, Identidad Online y Plataformas de Correo Electrónico Corporativo. Recientemente se convirtió en fan de la informática en la nube de AWS y ayuda a los clientes a aprovechar el poder de la tecnología de Microsoft en AWS.

 

 

Javier Gálvez , trabaja actualmente como arquitecto de soluciones y ha trabajado en tecnología de la información durante más de 22 años, comenzando como administrador de sistemas especializado en tecnologías de Microsoft para grandes instituciones financieras siendo especialista en plataformas de correo e intranets corporativa para luego mas tarde en su carrera pasar a tecnologías de virtualización y soluciones de código abierto como Kubernetes.
En la actualidad, se centra principalmente en el diseño y la entrega de nuevas soluciones hibridas sobre la nube AWS, así como en el desarrollo de actividades técnicas con demostraciones y sesiones interactivas para nuestros clientes.