Blog de Amazon Web Services (AWS)

Acelerando el lanzamiento de Windows Containers con el generador de EC2 Image Builder y la estrategia de almacenamiento en caché de imágenes.

Por Marcio Morales, Principal Solutions Architect en AWS

 

Actualización: El 11 de enero de 2022, AWS anunció la posibilidad de crear instancias de Microsoft Windows Server hasta un 65% más rápido en Amazon Elastic Compute Cloud (EC2). Los clientes pueden marcar cualquier imagen de máquina de Amazon (AMI) que ejecute Microsoft Windows Server para que arranque más rápido. Una vez marcada, cada instancia lanzada desde la AMI se iniciará más rápido automáticamente. Este es un recurso excelente para combinarlo con la AMI propuesta generada en este blog.

 

Los clientes me han dicho a menudo que los contenedores de Windows no se inician rápidamente debido al tamaño de la imagen del contenedor. En parte, esto es cierto, sin embargo, es importante desmitificar “en un contexto general” y cómo implementar la estrategia de almacenamiento en caché para evitar costosas operaciones de disco (proceso de extracción) y acelerar el lanzamiento de contenedores de Windows.

En muchos casos, también escucho la siguiente comparación: Contenedores de Linux contra contenedores de Windows y qué tan rápido es Linux en comparación con Windows. Esto es cierto, pero esta comparación no aporta mucho valor a la discusión, ya que cada plataforma resuelve diferentes problemas. Por ejemplo, un desarrollador no ejecutaría aplicaciones ASP.NET en un contenedor de Linux, ni ejecutaría Python en un contenedor de Windows.

Dejemos la comparación a un lado y centrémonos en mejorar el lanzamiento de Windows Containers.

Antes de ahondar en cómo resolver el problema, entendámoslo primero. Supongamos que ejecuta un clúster de Amazon Elastic Container Service (Amazon ECS) basado en Windows o un clúster de Amazon Elastic Kubernetes Service (Amazon EKS) con grupos de nodos de Windows. En un entorno de contenedores de alta demanda, en el cual el escalado automático de EC2 se activa con frecuencia para añadir más capacidad al clúster, un contenedor puede tardar entre 4 y 8 minutos en estar listo desde el momento en que se activa el escalamiento automático de EC2 hasta el momento en que el contenedor de Windows acepta el tráfico. Esto puede ser una realidad si no utiliza el enfoque correcto para evitar costosas operaciones de Entrada y Salida (I/O).

Desmitificar las imágenes de Windows Container

Dos imágenes base de contenedores forman parte de la AMI de Windows optimizada para ECS/EKS.

mcr.microsoft.com/windows/servercore
mcr.microsoft.com/windows/nanoserver
Bash

Las imágenes construidas ya se han extraído en la AMI de Windows optimizada para ECS/EKS.  Durante una operación de push/pull, solo se cargan o descargan al repositorio las capas que componen la imagen. El siguiente ejemplo muestra una imagen del Amazon Elastic Container Registry (Amazon ECR) llamada iis-dnn-a82378d43adb que solo tiene comprimidos 302,25 MB. Este es el tamaño de la carga/descarga durante las operaciones de push/pull.

Sin embargo, el siguiente resultado de docker image ls muestra que el tamaño de la imagen iis-dnn-a82378d43adb es de 5,73 GB en el disco, pero eso no significa que haya extraído esa cantidad. Lo que ocurrió durante la operación de extracción fue que solo se descargaron y extrajeron los 302,25 MB comprimidos mencionados anteriormente.

REPOSITORY                                                          TAG                 IMAGE ID            CREATED             SIZE
mcr.microsoft.com/windows/servercore                                ltsc2019            152749f71f8f        2 weeks ago         5.27GB
010101011575.dkr.ecr.us-east-1.amazonaws.com/iis-dnn-a82378d43adb   latest              de4f5f1edfe0        3 weeks ago         5.73GB
Bash

La columna de tamaño muestra el tamaño total de 5,73 GB. Detallando:

Imagen base incorporada = 5,27 GB

Capas de aplicación = 302,25 MB comprimidos/extraídos al disco = 460 MB

Tamaño total de la imagen del disco = 5,73 GB

La imagen base ya existe en el disco, lo que da como resultado un disco adicional de 460 MB. La próxima vez que vea esta cantidad de GB, no se preocupe demasiado. Es probable que más del 80% ya esté en el disco como imagen base construida. Si observamos la explicación anterior, el tamaño total de la imagen no es el principal problema del lanzamiento lento de Windows Containers. En cambio, es el tiempo que tarda la operación de “Pull/Extraction” en recibir, extraer y hacer que las capas adicionales estén listas.

Resultados de una estrategia de almacenamiento en caché de imágenes en contenedores

Para acelerar la implementación de Windows Containers, utilizaremos Amazon EC2 Image Builder para extraer las imágenes de los contenedores de un repositorio de Amazon ECR durante el proceso de construcción de la AMI. Las imágenes del contenedor que se van a extraer deben ser las esenciales para toda la solución; por ejemplo, imágenes de aplicaciones y contenedores secundarios, como Fluentd, Fluent Bit o cualquier otra imagen de contenedor necesaria para la solución.

Con este enfoque, todas las operaciones con altos costos de I/O (extracción de archivos) se llevarán a cabo durante la creación de la AMI, en lugar de cuando se lance el contenedor. Como resultado, todas las capas de imagen necesarias se extraerán en la AMI y estarán listas para usarse, lo que acelerará el inicio de un contenedor de Windows y podrá empezar a aceptar tráfico.

La siguiente muestra contiene los resultados de una aplicación ASP.NET que se ejecuta en un pod de Windows alojado en Amazon EKS. El entorno consta de dos grupos de nodos diferentes, uno con una AMI optimizada para EKS personalizada, creado con la solución propuesta en este blog y el segundo grupo de nodos con una AMI básica de Windows optimizada para EKS.En este primer ejemplo, kubectl describe pod genera el momento en que el pod está programado para el nodo hasta que alcanza el estado Started. Como puede ver, el tiempo necesario para hacer el Pull de la imagen fue de 54 segundos (que es el tiempo que Docker dedicó a verificar los metadatos de la imagen que ya estaban presentes).  En este ejemplo, la estrategia de almacenamiento en caché se implementa en Windows Node del cluster. 

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  70s   default-scheduler  Successfully assigned default/iis-dnn-ondemand-deployment-574c8789bd-f986k
 to ip-172-31-42-147.ec2.internal
  Normal  Pulled     *54s*   kubelet            Container image "010101010575.dkr.ecr.us-east-1.amazonaws.com/iis-dnn-a823 78d43adb" already present on machine
  Normal  Created    53s   kubelet            Created container iis-dnn-ondemand
  Normal  Started    16s   kubelet            Started container iis-dnn-ondemand
Bash

En el siguiente ejemplo, el tiempo necesario para hacer el Pull de la imagen es de 6 minutos (es decir, el tiempo en el que Docker identificó que la imagen no estaba presente en el equipo, retiró las capas adicionales de Amazon ECR y la extrajo al disco). La extracción es la operación de mayor costo y la causa principal más común de demoras en Windows Containers.

Al comparar los dos resultados, queda claro que, con la estrategia de imágenes en caché, se puede acelerar hasta 6 veces el tiempo necesario para que el primer pod alcance el estado «Started» y comience a recibir tráfico.

Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  7m16s  default-scheduler  Successfully assigned default/iis-dnn-ondemand-deployment-7f7545cf48-82gx
n to ip-172-31-1-96.ec2.internal
  Normal  Pulling    *7m4s*   kubelet            Pulling image "010101010575.dkr.ecr.us-east-1.amazonaws.com/iis-dnn-a8237 8d43adb"
  Normal  Pulled     64s    kubelet            Successfully pulled image "010101010575.dkr.ecr.us-east-1.amazonaws.com/i is-dnn-a82378d43adb" in *6m0.7576396s*
  Normal  Created    63s    kubelet            Created container iis-dnn-ondemand
  Normal  Started    62s    kubelet            Started container iis-dnn-ondemand
Bash

Creación de una AMI EKS/ECS de Windows personalizada para acelerar el lanzamiento de Windows Containers

En esta entrada de blog, utilizo Amazon EKS como orquestador.  La estrategia de almacenamiento en caché se basa en el nivel de AMI.  Puede utilizar el mismo enfoque para un clúster de Amazon ECS. 

En este blog, realizaremos las siguientes tareas:

  1. Crear un componente EC2 Image Builder personalizado.
  2. Construir el pipeline de la AMI de Windows optimizada para el EKS/ECS personalizados.
  3. Crear un grupo de nodos de EKS mediante la AMI de Windows optimizada para EKS personalizada.
  4. Comprobar los resultados.

#1 Cree un componente EC2 Image Builder personalizado

Image Builder utiliza AWS Task Orchestrator and Executor (AWSTOE) para organizar flujos de trabajo complejos, modificar las configuraciones del sistema y probar los sistemas. No se requiere ninguna configuración de servidor adicional para usar Image Builder en la consola de administración de AWS ni para usar los comandos de Image Builder que interactúan con AWSTOE en su lugar.

AWSTOE usa documentos YAML para definir secuencias de comandos que personalizan la imagen. Los documentos pueden incluir fases de construcción, validación y prueba. Para obtener más información sobre los documentos YAML, consulte las definiciones de esquemas y documentos.

1.1 En la sección EC2 Image Builder de EC2 de la consola de administración de AWS, haga clic Componentes y después en Crear Componente.

1.2 Cree un Build type component que sea compatible con Windows.

1.3 En el documento de definición, añada el siguiente contenido y sustituya la URL de Amazon ECR y las URL de la imagen por otras que coincidan con su entorno.

name: DockerPull
description: DockerImageCacheStrategy.
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: Dockerpull
        action: ExecutePowerShell
        inputs:
          commands:
            - (Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin 01010101.dkr.ecr.us-east-1.amazonaws.com
            - docker pull 01010101575.dkr.ecr.us-east-1.amazonaws.com/iis-dnn-a82378d43adb
            - docker pull 01010101575.dkr.ecr.us-east-1.amazonaws.com/fluentd-a729311dbs
Bash

1.4 Haga clic en Crear componente.

#2 Cree la canalización AMI de Windows personalizada optimizada para EKS/ECS.

En este paso, crearemos una canalización de imágenes para crear automáticamente la AMI de Windows personalizada optimizada para EKS/ECS. En la página principal del generador de imágenes de EC2, haga clic en Crear el Pipeline de imágenes.

2.1 Especifique el nombre de la canalización, la descripción y el cronograma de construcción. En mi ejemplo, la canalización se ejecutará automáticamente cada semana para garantizar que las actualizaciones más recientes de Windows estén instaladas en mi imagen. Haz clic en Next.

2.2 Haz clic en Create new recipe. Seleccione el tipo de imagen como Amazon Machine Image (AMI). 

2.3 En la imagen de origen, selecciona Windows y Quick Start (Amazon-managed).

2.4 Este es un paso importante.  Debe seleccionar la imagen de Windows Server que se mostrará como imagen base para los nodos de Windows. En este ejemplo, seleccionaré Windows Server 2004 English Core Base x86. Para Amazon ECS, el EC2 Image Builder ya tiene imágenes con el agente de ECS instalado, lo que no ocurre con EKS. Preparemos Windows Server 2004 para tener los componentes EKS.

2.5 Otra buena opción es seleccionar la opción: Utilice la versión más reciente disponible del sistema operativo, que incluirá todas las actualizaciones de Windows existentes en el momento en que AWS la generó, así como las nuevas funciones de AMI o las mejoras de rendimiento.

2.6 El panel Components es donde adjuntamos el componente que creamos en el paso 1 a la canalización de imágenes, pero primero asegurémonos de añadir componentes principales a esa AMI. En el cuadro de búsqueda, escriba EKS

En el panel siguiente, tienes dos opciones. Deje que el pipeline utilice la versión más reciente de Kubelet y Docker, o configúrela en una versión específica. Algo a tener en cuenta es que la descripción contiene la versión 1.16 de EKS. En el panel Secuence, seleccionamos la versión más reciente del componente disponible, es decir, la versión más reciente publicada por AWS. En el momento de escribir esta entrada de blog, Kubernetes 1.20. Puede obtener más información en la documentación oficial.

2.7 Una buena opción es añadir el componente update-windows para tener las actualizaciones de seguridad más recientes instaladas en la AMI. Busque el componente update-windows. 

2.8 Es hora de añadir el componente de estrategia de almacenamiento en caché que denominamos Docker pull. Cambia la búsqueda a Owned by me y busca Docker pull o el nombre que elijas en el paso 1.

2.9 Acabarás teniendo tres componentes:

  • eks-optimized-ami-windows
  • Windows de actualización
  • Docker Pull

2.10 El perfil de instancia de IAM generado por EC2 Image Builder ya cuenta con la política necesaria para iniciar sesión en Amazon ECR. «En el paso 1.3, utilizamos el siguiente comando para iniciar sesión en el repositorio de Amazon ECR». 

(Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin 01010101575.dkr.ecr.us-east-1.amazonaws.com
Bash

2.11 Siga todos los pasos siguientes necesarios hasta completar la creación del pipeline y la infraestructura.  Distribuya la imagen mediante la configuración de distribución de EC2 Image Builder.

#3 Cree un grupo de nodos de Amazon EKS mediante la AMI de Windows optimizada para EKS personalizada.

Para probar los resultados, puede utilizar su herramienta de implementación favorita para añadir nuevos grupos de nodos mediante la nueva AMI o editar la plantilla de lanzamiento existente adjunta a un grupo de Auto Scaling existente. En este punto, debe iniciar manualmente la canalización de EC2 Image Builder para generar la AMI. 

En esta entrada de blog, utilizaré eksctl para crear un nuevo grupo de nodos de Amazon EKS y especificar la AMI personalizada.

3.1 Ajuste el archivo de configuración eksctl para añadir un nuevo grupo de nodos y especifique la AMI personalizada. Un paso importante es introducir el ID de AMI y la amiFamily. Si no se especifica la amiFamily, el nodo no se unirá al clúster.

apiVersion: eksctl.io/v1alpha5
  kind: ClusterConfig
  
  metadata:
    name: eks-windows
    region: us-east-1
    version: '1.20'  
  availabilityZones: 
      - us-east-1f
      - us-east-1b
  
  nodeGroups:
    - name: windows-ng-sac2004-customami-test
      instanceType: c5.xlarge
      minSize: 1
      ami: ami-0556136c21149e0ac
      amiFamily: WindowsServer2004CoreContainer
.......
YAML

Además, puede permitir que EC2 Image Builder cree una nueva versión de la plantilla de lanzamiento existente que haga referencia a sus imágenes de Amazon Machine (AMI) más recientes y actualice automáticamente su EC2 Auto Scaling. 

Conclusión

En esta entrada de blog, mostré cómo se puede utilizar una estrategia de almacenamiento en caché de imágenes de contenedores para acelerar el lanzamiento de Windows Containers, pero también se puede utilizar el mismo enfoque para acelerar la carga de trabajo de cualquier contenedor, independientemente del sistema operativo, como el sidecar de contenedores, los contenedores de construcción de CI y más.

 

Este artículo fue traducido del Blog da AWS en Inglés.

 


Acerca del autor

Marcio Morales es el arquitecto principal de soluciones en Amazon Web Services.  Marcio es un especialista global dedicado a Windows Containers y ayuda a los clientes de AWS a diseñar, crear, proteger y optimizar las cargas de trabajo de Windows Container en AWS.

 

 

 

 

Revisores

Bruno Lopes es un arquitecto de soluciones sr en el equipo de AWS LATAM. Lleva más de 14 años trabajando con soluciones de TI, y en su cartera cuenta con numerosas experiencias en cargas de trabajo de Microsoft, entornos híbridos y formación técnica para clientes como Technical Trainer y Evangelista. Ahora actúa como arquitecto de soluciones, combinando todas las capacidades para reducir la burocracia en la adopción de las mejores tecnologías a fin de ayudar a los clientes a superar sus desafíos diarios.

 

 

 

 

Thiago Paiva es instructor técnico sénior del equipo de AWS para América. Durante la mayor parte de su carrera, ha trabajado con cargas de trabajo de Microsoft y computación en la nube. Como instructor técnico, lleva más de 3 años en AWS y se dedica al programa AWS TechU, que consiste en ofrecer un aprendizaje basado en un proyecto de 6 meses dirigido por un instructor, seguido de una tarea de aprendizaje de 6 meses en las áreas de: Capacitación técnica, arquitectura de soluciones o consultoría de servicios profesionales para personas que se han graduado recientemente de universidades relacionadas con las TI.

 

 

 

 

Víctor Jiménez es un arquitecto senior de soluciones de socios principales de AWS con sede en México. Cuenta con experiencia de 15 años en cargas de trabajo de Windows Server principalmente en roles de infraestructura, provisionamiento y automatización. Ha adquirido experiencia en los últimos 5 años en tecnologías en la nube. En AWS, lleva a cabo tareas de apoyo con los socios estratégicos para guiar a los clientes en la adopción de su viaje a la nube y modernización aprovechando las herramientas y servicios optimizados para su negocio.