O blog da AWS

Acelerando a velocidade de launch dos Windows Containers com o EC2 Image Builder e a estratégia de cache de imagens.

Por Marcio Morales, Principal Solutions Architect da AWS

 

Atualização: em 11 de janeiro de 2022, a AWS anunciou a capacidade de criar instâncias do Microsoft Windows Server até 65% mais rápido no Amazon Elastic Compute Cloud (EC2). Os clientes podem assinalar qualquer Amazon Machine Image (AMI) executando o Microsoft Windows Server para ser inicializada mais rapidamente. Uma vez assinalada, cada instância executada a partir da AMI será iniciada automaticamente mais rápida. Esse é um excelente recurso a ser combinado com a AMI proposta gerada nesta postagem do blog.

 

Ouvi muitas vezes de clientes que os Windows Containers não são rápidos de iniciar devido ao tamanho da imagem do container. Em parte, isso é verdade, no entanto, é importante desmistificar “a imagem geral” e como implementar a estratégia de cache para evitar operações de alto custo para o disco (processo de extração) e acelerar o launch de Windows Containers.

Em muitos casos, também ouço o seguinte comparativo: Linux Containers versus Windows Containers e quão rápido é o Linux quando comparado com o Windows. Isso é verdade, mas esse comparativo não traz muito valor à discussão, pois cada plataforma soluciona problemas diferentes. Por exemplo, um desenvolvedor não executaria aplicações ASP.NET em um container Linux, nem executaria Python em um container do Windows.

Vamos deixar o comparativo de lado e focar no aprimoramento do launch de Windows Containers.

Antes de nos aprofundarmos em como resolver o problema, vamos entendê-lo primeiro. Digamos que você esteja executando um cluster do Amazon Elastic Container Service (Amazon ECS) baseado no Windows ou um cluster do Amazon Elastic Kubernetes Service (Amazon EKS) com node groups do Windows. Em um ambiente de containers de alta demanda, em que o EC2 Auto Scaling é frequentemente acionado para adicionar mais capacidade ao cluster, pode levar cerca de 4 a 8 minutos para que um container fique pronto desde o momento em que o EC2 Auto Scaling foi acionado até o momento em que o Windows container aceita o tráfego. Isso pode ser uma realidade se não estiver usando a abordagem correta para evitar operações com alto custo de I/O.

Desmistificando as imagens do Windows Container

Duas base images de container fazem parte do ECS/EKS Optimized Windows AMI.

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

In-built based images já foram extraídas no ECS/EKS Optimized Windows AMI. Durante uma operação de push/pull, somente as camadas que compõem sua imagem são upload/download para o repositório. O exemplo a seguir mostra uma imagem do Amazon Elastic Container Registry (Amazon ECR) chamada iis-dnn-a82378d43adb que tem apenas 302,25 MB compactados. Esse é o tamanho do upload/download durante as operações de push/pull.

No entanto, a seguinte saída do docker image ls mostra o tamanho da imagem iis-dnn-a82378d43adb como 5,73 GB no disco, mas isso não significa que ele extraiu essa quantidade. O que aconteceu durante a operação de extração foi que apenas os 302,25 MB compactados mencionados anteriormente foram baixados e extraídos.

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

A coluna de tamanho mostra o tamanho geral de 5,73 GB. Detalhando:

In-built base image = 5,27 GB

Application Layers = 302,25 MB compactadas/Extraída em disco = 460 MB

Tamanho total da imagem em disco = 5,73 GB

A imagem base já existe no disco, resultando na quantidade adicional em disco de 460 MB. Na próxima vez que você ver essa quantidade de GBs, não se preocupe muito. É provável que mais de 80% já estejam em disco como in-built image. Analisando a explicação acima, não é o tamanho geral da imagem o principal problema de lentidão em um launch de Windows Containers. Em vez disso, é o tempo que a operação de Pull/Extraction leva para puxar, extrair e disponibilizar as camadas adicionais.

Resultados de uma estratégia de cache de imagens de container

Para acelerar a implantação de Windows Containers, usaremos o Amazon EC2 Image Builder para extrair imagens de container de um repositório Amazon ECR durante o pipeline de construção da AMI. As imagens do container a serem extraídas devem ser aquelas essenciais para toda a solução; por exemplo, imagens de aplicações e containers secundários, como Fluentd, Fluent Bit ou qualquer outra imagem de container necessária para sua solução.

Usando essa abordagem, todas as operações com alto custo de I/O (extração de arquivos) acontecerão na criação da compilação da AMI, ao invés de acontecer no launch do container. Como resultado, todas as camadas de imagem necessárias serão extraídas na AMI e estarão prontas para serem usadas, acelerando a inicialização de um Windows Container e podendo começar a aceitar o tráfego.

A saída abaixo contém os resultados de um aplicação ASP.NET executada em um pod do Windows hospedado pelo Amazon EKS. O ambiente é composto por dois Node Groups diferentes, um com uma AMI básica do EKS Optimized Windows e o segundo Node Group com uma AMI otimizada EKS personalizada, criada usando a solução proposta neste blog.

Neste primeiro exemplo, o kubectl describe pod gera o momento em que o pod é programado para o nó até atingir o status “Iniciado”. Como você pode ver, o tempo necessário para “puxar” (pull) a imagem foi de 54 segundos (que é o tempo que o Docker gastou verificando os metadados da imagem já presentes). Neste exemplo, a estratégia de cache é implementada no Windows Node.

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

No próximo exemplo, o tempo necessário para o pull da imagem é de 6 minutos (ou seja, o tempo em que o Docker identificou que a imagem não estava presente na máquina, retirou as camadas adicionais do Amazon ECR e a extraiu para o disco). A extração é a operação com custo mais alto e a causa raiz mais comum de atrasos nos launch de Windows Containers.

Comparando os dois resultados, fica claro que, usando a estratégia de imagem em cache, você pode acelerar em até 6 vezes o tempo necessário para que o primeiro pod alcance o status “Iniciado” e comece a receber tráfego.

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

Construindo um EKS/ECS Windows AMI personalizado para acelerar o launch de  Windows Containers

Como vamos conseguir isso?

Pré-requisitos e premissas:

Nesta postagem do blog, estou usando o Amazon EKS como orquestrador. A estratégia de cache é construída no nível da AMI. Você pode usar a mesma abordagem para um cluster do Amazon ECS.

Neste blog, faremos as seguintes tarefas:

  1. Criar um componente personalizado do EC2 Image Builder.
  2. Criar o pipeline personalizado EKS/ECS Optimized Windows AMI.
  3. Criar um EKS Node Group usando o EKS Optimized Windows AMI personalizado.
  4. Verificar os resultados.

1. Crie um componente personalizado do EC2 Image Builder

O Image Builder usa o AWS Task Orchestrator and Executor (AWSTOE) para orquestrar workflows complexos, modificar configurações do sistema e testar seus sistemas. Não é necessária nenhuma configuração adicional de servidor para usar o Image Builder no AWS Management Console ou usar comandos do Image Builder que interagem com o AWSTOE em seu lugar.

O AWSTOE usa documentos YAML para definir os scripts que personalizam sua imagem. Os documentos podem incluir fases de construção, validação e teste. Para obter mais informações sobre documentos YAML, consulte o schema e as definições do documento.

1.1 Na seção EC2 Image Builder do AWS Management Console, clique em Componentes e depois em Criar componente.

1.2 Crie um componente do tipo Build que seja compatível com o Windows.

1.3 No documento de definição, adicione o conteúdo a seguir e substitua o URL do Amazon ECR e as URLs das imagens pelos que correspondem ao seu ambiente.

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 Clique em Criar componente.

2. Crie o pipeline personalizado de AMI do Windows otimizado para EKS/ECS.

Nesta etapa, criaremos um pipeline de imagens para criar automaticamente a AMI personalizada do Windows otimizada para EKS/ECS. Na página principal do EC2 Image Builder, clique em Criar pipeline de imagem.

2.1 Especifique o nome, a descrição e o build schedule do pipeline. No meu exemplo, o pipeline será executado automaticamente toda semana para garantir que as atualizações mais recentes do Windows sejam instaladas na minha imagem. Clique em Avançar.

2.2 Clique em Criar nova receita. Selecione o tipo de imagem como Amazon Machine Image (AMI).

2.3 Na imagem de origem, selecione Windows e Quick Start (gerenciado pela Amazon).

2.4 Este é um passo importante. Você deve selecionar a imagem do Windows Server que será exibida como imagem base para seus Windows Nodes. Neste exemplo, selecionarei Windows Server 2004 English Core Base x86. Para o Amazon ECS, o EC2 Image Builder já tem imagens com o agente ECS instalado, o que não é o caso do EKS. Vamos preparar o Windows Server 2004 para ter os componentes EKS.

2.5 Outra ótima opção é selecionar a opção: Use a versão mais recente disponível do sistema operacional, que incluirá todas as atualizações do Windows no momento em que a AWS o gerou, bem como todos os novos recursos da AMI ou melhorias de desempenho.

2.6 O painel Componentes é onde anexamos o componente que criamos na etapa 1 ao pipeline de imagens, mas primeiro vamos nos certificar de que estamos adicionando componentes principais a essa AMI. Na caixa de pesquisa, digite EKS.

No painel seguinte, você tem duas opções. Deixe o pipeline usar a versão mais recente do Kubelet e do Docker ou defina-a para uma versão específica. Algo a ser observado é que a descrição tem a versão 1.16 do EKS. No painel Sequence, selecionamos a versão mais recente do componente disponível, ou seja, a versão mais recente lançada pela AWS. Na época desta postagem no blog, Kubernetes 1.20. Você pode aprender mais na documentação oficial.

2.7 Uma boa opção é adicionar o componente update-windows para ter as atualizações de segurança mais recentes instaladas na AMI. Pesquise o componente update-windows.

2.8 É hora de adicionar o componente de estratégia de cache que chamamos de Docker pull. Altere a pesquisa para Owned by me e pesquise por Docker pull ou pelo nome que você escolher durante a etapa 1.

2.9 Você acabará tendo três componentes:

  • eks-optimized-ami-windows
  • update-windows
  • docker pull

2.10 O perfil da instância do IAM gerado pelo EC2 Image Builder já tem a política necessária para fazer login no Amazon ECR. “Na etapa 1.3, usamos o seguinte comando para fazer login no repositório Amazon ECR.”

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

2.11 Siga todas as próximas etapas necessárias até que a criação do pipeline e da infraestrutura seja concluída. Distribua a imagem usando as configurações de distribuição do EC2 Image Builder.

3. Crie um Node Groups do Amazon EKS usando o EKS Optimized Windows AMI personalizado.

Para testar os resultados, você pode usar sua ferramenta de implantação favorita para adicionar um novo Node Groups usando a nova AMI ou editar o Launch Template existente anexado a um grupo existente do Auto Scaling. Nesse ponto, você deve iniciar manualmente o pipeline do EC2 Image Builder para gerar a AMI.

Nesta postagem do blog, usarei eksctl para criar um novo Node Group do Amazon EKS e especificar a AMI personalizada.

3.1 Ajuste seu arquivo de configuração eksctl para adicionar um novo Node Group e especificar a AMI personalizada. Uma etapa importante é informar o ID da AMI e a família AMI. Não especificar a AmiFamily fará com que o nó não se junte ao cluster.

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

Além disso, você pode permitir que o EC2 Image Builder crie uma nova versão do Launch Template existente que faça referência às suas Amazon Machine Images (AMIs) mais recentes e atualize automaticamente seu EC2 Auto Scaling.

Conclusão

Nesta postagem do blog, mostrei como você pode usar uma estratégia de cache de imagem de container afim de acelerar o launch de Windows Containers, mas você também pode usar a mesma abordagem para acelerar a carga de trabalho de qualquer container, independente do sistema operacional, como o sidecar de containers, containers de construção de CI e muito mais.

 

Este artigo foi traduzido do Blog da AWS em Inglês.

 


Sobre o autor

Marcio Morales é Principal Solutions Architect da Amazon Web Services. Marcio é um SME global para Windows Containers e ajuda os clientes da AWS a projetar, criar, proteger e otimizar cargas de trabalho de Windows Containers na AWS.

 

 

 

 

Revisores

Bruno Lopes é Senior Solutions Architect no time da AWS LATAM. Trabalha com soluções de TI há mais de 14 anos, tendo em seu portfólio inúmeras experiências em workloads Microsoft, ambientes híbridos e capacitação técnica de clientes como Technical Trainer e Evangelista. Agora atua como um Arquiteto de Soluções, unindo todas as capacidades para desburocratizar a adoção das melhores tecnologias afim de ajudar os clientes em seus desafios diários.

 

 

 

 

Thiago Paiva é Senior Technical Instructor no time da AWS Americas. Na maior parte de sua carreira tem atuado com workloads Microsoft e cloud computing. Como Technical Instructor, já está há mais de 3 anos na AWS se dedicando ao programa AWS TechU que consiste em oferecer aprendizado baseado em um projeto de 6 meses com instrutor, seguido por uma atribuição de aprendizado de 6 meses nas áreas de: Treinamento Técnico, Arquitetura de Soluções ou Consultoria de Serviços Profissionais para indivíduos recém formados em  universidade relacionadas com TI.