O blog da AWS

Introdução ao AWS App Mesh e Amazon EKS

Por Re Alvarez-Parmar, Container Specialist Solutions Architect na AWS
Bruno Emer, Solutions Architect na AWS

 

Neste blogpost, nós vamos falar sobre o uso de micro serviços executados em containers dentro de um service mesh e trazer um exemplo concreto sobre como começar a utilizar o AWS App Mesh em conjunto com o Amazon EKS.

Cada vez mais, clientes da AWS têm adotado micro serviços afim de criar aplicações que sejam escaláveis e resilientes, reduzindo o tempo de entrada no mercado. Mover uma aplicação monolítica para uma estrutura de micro serviços significa “quebrar” uma única aplicação em em um conjunto menor de serviços, facilitando os processos de desenvolvimento e operações. Você pode utilizar o Amazon Elastic Kubernetes Service (EKS) e o Amazon Elastic Container Service (ECS) para facilitar a execução, atualizações e monitoramento de micro-serviços sendo executados em containers.

Service meshes como o AWS App Mesh lhe auxiliam a conectar serviços, monitorar as comunicações entre suas aplicações e controlar o tráfego de rede. Quando uma aplicação está em execução em um service mesh, proxies são adicionados aos seus serviços, formando assim o “data plane” do mesh. Desta maneira, a lógica de negócio é executada pelos serviços de sua aplicação enquanto o proxy se torna responsável por implementar service discovery, observabilidade, criptografia do tráfego de rede, retries automáticos e traffic shaping. O AWS App Mesh padroniza a comunicação entre seus serviços, oferecendo visibilidade consistente e controles refinados sobre o tráfego de rede de todos os seus micro serviços executados em containers. O App Mesh possui dois componentes: um control plane totalmente gerenciado que configura os proxies e um data plane composto por proxies Envoy, executando como sidecars.

 

Usando o App Mesh com o EKS

O Amazon EKS é um serviço gerenciado que facilita a execução do Kubernetes na AWS, sem a necessidade de operar seu próprio cluster de Kubernetes. Você pode utilizar o App Mesh para implementar um service mesh para aplicações sendo executadas em clusters EKS. O processo de utilização do App Mesh em conjunto com o EKS é facilitado através da utilização do AWS App Mesh Controller para K8s. O App Mesh Controller para K8s é um projeto de código fonte aberto que lhe ajuda a gerenciar os recursos do App Mesh utilizando a própria API do Kubernetes. Ou seja, você consegue configurar os recursos do App Mesh a partir do próprio kubectl, como mostraremos a seguir.

Você pode utilizar o App Mesh para conectar serviços que estão em execução no EKS com serviços sendo executados em ECS, EC2 e até mesmo em seu próprio datacenter utilizando o AWS Outposts. Neste artigo, nós iremos focar na utilização do App Mesh em conjunto com o EKS. Vamos começar então revisando alguns dos recursos do App Mesh que podem melhorar o processo de execução de micro serviços em Kubernetes.

 

Controles de rede

O AWS App Mesh lhe permite controlar o tráfego de rede entre serviços, o que pode ajudá-lo a experimentar novos recursos de sua aplicação. Você pode utilizar esta feature para encaminhar apenas uma porção de seu tráfego para uma nova versão de seu serviço. Note que o Kubernetes não permite que você defina uma divisão das requisições entre múltiplos Deployments. Com o App Mesh, você pode criar regras para distribuir o tráfego entre diferentes versões de seus serviços.

Os controles de tráfego do App Mesh podem também tornar os processos de deployment de novas versões de suas aplicações significamente mais seguras através de canary deployments. Com esta estratégia, você cria um novo deployment do Kubernetes com menos pods e encaminha apenas uma pequena porção de seu tráfego para esta nova versão. Se a nova versão não apresenta nenhum tipo de problema ou erros você pode então, gradativamente, aumentar a quantidade de tráfego até que todas as novas requisições sejam respondidas pela nova versão.

Você pode também utilizar o App mesh para aumentar a resiliencia de suas aplicações através da implementação de políticas de timeout ou configurando retries automáticos nos proxies.

Observabilidade

Observabilidade é uma propriedade de um sistema que determina quão bem o seu estado pode ser inferido através de informações obtidas de fontes externas. No contexto de micro serviços, estas fontes externas são métricas, traces e logs. Métricas mostram o comportamento de um sistema ao longo do tempo. Logs facilitam a solução de problemas fornecendo informações que podem ser a causa de possíveis erros. Traces distribuídos podem nos ajudar a depurar, identificar componentes problemáticos na aplicação fornecendo detalhes para um ponto no tempo específico e entender o fluxo entre os microserviços.

Você pode mensurar a saúde de sua aplicação configurando o App Mesh para gerar métricas como total de solicitações, criar logs de acesso e traces. À medida que o tráfego de seus serviços passa pela camada de proxies, o Envoy irá inspecionar o tráfego e gerar estatísticas, criar logs de acesso e adicionar cabeçalhos HTTP às solicitações de saída, que podem ser utilizados para gerar traces. Métricas e traces podem ser encaminhados para serviços de agregação como o Prometheus e o daemon X-Ray, podendo ser consumidos para a análise do comportamento do sistema. Uma vez que o App Mesh usa o Envoy, ele também é compatível com uma ampla variedade de parceiros AWS e ferramentas de código fonte aberto para monitoramento de micro serviços.

Criptografia em trânsito

Micro serviços comunicam-se uns com os outros através da rede, o que significa que dados confidenciais podem estar sendo encaminhados pela mesma. Muitos clientes querem criptografar o tráfego de rede entre serviços. O app Mesh pode lhe ajudar com isto, ele pode criptografar o  tráfego entre serviços utilizando um certificado TLS, e você não precisa lidar com negociações e término de TLS no código de sua aplicação.

Você pode utilizar seus próprios certificados para criptografar o tráfego de rede ou pode usar o AWS Certificate Manager (ACM). Caso escolha a segunda opção, o ACM renovará automaticamente certificados que estão perto do fim de sua validade, e o App Mesh irá distribuir automaticamente os certificados renovados.

 

Conceitos do App Mesh

Para usar o App Mesh, você precisará criar um Mesh. Um mesh funciona como um limite lógico no qual todos os micro serviços irão residir. Você pode pensar neste conceito como um “bairro” que compreende seus micro serviços:

 

 

 

 

O próximo componente da lista é o Virtual Service. Os Virtual Services atuam como ponteiros virtuais para suas aplicações e são representados pelos nomes que suas aplicações utilizam para se conectar aos endpoints definidos em seu mesh. Em uma arquitetura de microserviços, cada micro serviço será representado por um Virtual Service e possuirá um virtualServiceName. Note que um Virtual Service do App Mesh não é o mesmo de um service do Kubernetes.

Um Virtual Service representa uma aplicação, mas uma determinada aplicação pode possuir diferentes versões. Por exemplo: uma aplicação específica pode possuir duas versões diferentes: uma interna e uma voltada para o público (pública). Cada versão de uma determinada aplicação é representada por um Virtual Node. Conforme mostrado na imagem acima, um Virtual Service pode possuir um ou mais Virtual Nodes. Se um Virtual Service possuir múltiplos Virtual Nodes, você definirá como o tráfego é roteado entre vários Virtual Nodes utilizando um Virtual Router.

Os Virtual Routers são responsáveis pelo roteamento do tráfego com base em regras específicas; estas regras são chamadas de Virtual Routes. Um Virtual Router precisa possuir pelo menos uma Virtual Route. A lógica de roteamento pode ser baseada em diferentes critérios tais como cabeçalhos HTTP, URL Paths, ou serviços gRPC e métodos utilizados. Você também pode utilizar Virtual Routers para implementar lógicas de retry e tratativas de erros.

 

App Mesh com EKS em Ação

Neste tutorial, você irá criar componentes do AWS App Mesh e realizar o deployment dos mesmos utilizando uma aplicação de exemplo chamada Yelb. Depois de colocar o Yelb em um mesh, você irá criar uma nova versão do application server Yelb e utilizará uma Virtual Route do App Mesh para direcionar o tráfego entre as duas versões do aplicativo.

O Yelb permite que os usuários votem em um conjunto de alternativas como restaurantes e atualiza dinamicamente gráficos de pizza com base nos votos. Além disso, o Yelb mantém o controle do número de visualizações de página e demonstra o hostname da instância yelb-appserver servindo a solicitação de API após uma votação ou uma atualização de página. Os componentes Yelb incluem:

  • Um frontend chamado yelb-ui, responsável por entregar o código JS para o browser.
  • Um application server chamado yelb-appserver, uma aplicação Sinatra que lê e grava em um servidor de cache (redis-server) e um banco de dados Postgres (yelb-db).
  • O Redis armazena o número de visualizações de página e o banco de dados Postgres armazena os votos.

Esta é a arquitetura do Yelb:

 

 

 

OBS: A configuração do Yelb usa armazenamento efêmero para todos os containers. A execução de bancos de dados dessa maneira só é feita para fins de demonstração neste blog post.

 

Para executar este laboratório, você precisará possuir um ambiente com algumas ferramentas. Nós utilizamos uma instância do AWS Cloud9 para executar este tutorial e, se você quiser criar uma instância do Cloud9 em sua conta, siga as etapas no Workshop do EKS do capítulo Create a Workspace  até Update IAM Settings for your Workspace.

1. Configurar a infra-estrutura

Para executar este tutorial, você precisa instalar algumas ferramentas específicas:

Comece clonando o repositório do GitHub:

git clone https://github.com/aws/aws-app-mesh-examples.git
cd aws-app-mesh-examples/walkthroughs/eks-getting-started/

Se você estiver usando uma instância do Cloud9, execute os seguintes comandos para instalar as ferramentas necessárias mencionadas acima:

./cloud9-startup.sh && source ~/.bash_profile > /dev/null

Você irá utilizar um CloudFormation template para criar uma VPC que inclui um security group e dois repositórios ECR. O script baseline.sh implementa o CloudFormation stack e cria a infraestrutura base com uma VPC, subnets públicas e privadas e uma IAM policy. Então, para começar as coisas, execute o seguinte comando:

./baseline.sh

O script acima leva cerca de cinco minutos para ser concluído.

 

2. Criar o cluster EKS

Para criar o cluster EKS, execute o seguinte comando que levará cerca de 15 minutos para ser concluído:

./infrastructure/create_eks.sh

Após criar o seu cluster EKS, você pode testar a conectividade com o cluster através do seguinte comando:

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   14m

3. Deploy da aplicação

Para realizar o deployment do Yelb execute o seguinte comando:

kubectl apply -f infrastructure/yelb_initial_deployment.yaml

Para obter a URL do balanceador de carga para realizar testes em seu navegador, use o seguinte comando:

$ kubectl get service yelb-ui -n yelb
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP                                                               PORT(S)        AGE
yelb-ui   LoadBalancer   172.20.19.116   a96f5309de3csdc19847045bfbd34bd4-XXXXXXXXXX.us-west-2.elb.amazonaws.com   80:30467/TCP   3m33s

Observe que a URL do Load Balancer público está disponível no campo EXTERNAL-IP. Talvez seja necessário aguardar alguns minutos para a propagação de DNS. Quando abrir a URL em um navegador de sua preferência, o resultado deve ser o seguinte:

 

4. Adicionar o Yelb em um Mesh

Para começar a criar os recursos do App Mesh e adicionar o Yelb em um service mesh, a primeira coisa que você precisa fazer é instalar o AWS App Mesh Controller. Este controller permite que você configure recursos App Mesh utilizando  kubectl. Todos os recursos utilizados pelo App Mesh podem ser também criados através da console do serviço, porém, neste tutorial, utilizaremos o kubectl. A arquitetura abaixo ilustra o estado desejado da aplicação Yelb após a conclusão deste capítulo:

 

 

 

 

Você irá utilizar o Helm para instalar o App Mesh Controller. O Helm é um projeto de código aberto que facilita a definição, instalação e atualização de aplicações em um cluster de Kubernetes. O primeiro passo, consiste na adição do repositório do Amazon EKS ao Helm:

helm repo add eks https://aws.github.io/eks-charts

Em seguida, você deverá criar um namespace para o App Mesh Controller, responsável pelos recursos customizados:

kubectl create ns appmesh-system

Agora, instale o App Mesh Controller:

helm upgrade -i appmesh-controller eks/appmesh-controller \
    --namespace appmesh-system

Para confirmar se o App Mesh Controller está em execução, liste os pods no namespace appmesh-system:

$ kubectl get pods -n appmesh-system
NAME                                  READY   STATUS    RESTARTS   AGE
appmesh-controller-66b749c78b-67n68   1/1     Running   0          6s

Nós realizamos o deployment do yelb no namespace yelb e usamos o mesmo nome para o mesh. Agora, você precisará adicionar dois labels ao namespace yelb: mesh e appmesh.k8s.aws/sidecarInjectorWebhook. Estes labels instruem o controlador a injetar e configurar os Envoy proxies nos pods:

kubectl label namespace yelb mesh=yelb 
kubectl label namespace yelb appmesh.k8s.aws/sidecarInjectorWebhook=enabled

Ótimo! Agora estamos em posição de criar o mesh, usando:

# Cria o manifesto com a configuração do mesh:
$ cat <<"EOF" > /tmp/eks-scripts/yelb-mesh.yml
apiVersion: appmesh.k8s.aws/v1beta2
kind: Mesh
metadata:
  name: yelb
spec:
  namespaceSelector:
    matchLabels:
      mesh: yelb
EOF


# Cria o Mesh com a configuração acima:
$ kubectl apply -f /tmp/eks-scripts/yelb-mesh.yml

OBSERVAÇÃO: O parâmetro namespaceSelector corresponde aos namespaces Kubernetes com o label mesh e o valor yelb.

 

Se desejar, você também pode utilizar o console da AWS para verificar se o mesh foi criado corretamente:

 

 

Depois de criar o mesh, você deve criar todos os componentes do App Mesh para cada componente Yelb. Você irá utilizar os arquivos YAML no diretório infrastructure/appmesh_template para criar os Virtual Nodes, Virtual Routers, Routes e Virtual Services. Aplique essas configurações usando os seguintes comandos:

kubectl apply -f infrastructure/appmesh_templates/appmesh-yelb-redis.yaml
kubectl apply -f infrastructure/appmesh_templates/appmesh-yelb-db.yaml
kubectl apply -f infrastructure/appmesh_templates/appmesh-yelb-appserver.yaml
kubectl apply -f infrastructure/appmesh_templates/appmesh-yelb-ui.yaml

O App Mesh Controller está configurado para injetar sidecar containers Envoy, mas ainda não o fez. Isso ocorre porque os sidecars só são injetados quando um pod é criado ou alterado. Desta maneira, exclua os pods existentes usando kubectl -n yelb delete pods –all. Isso fará com que a criação de novos pods com os Envoy sidecars ocorra. Para validar se o controlador funcionou bem, verifique o número de contêineres em execução em cada pod:

$ kubectl -n yelb get pods
NAME                              READY   STATUS    RESTARTS   AGE
redis-server-7dc845588-qbxv2      2/2     Running   0          48s
yelb-appserver-7d644fbf76-d642g   2/2     Running   0          48s
yelb-db-76bdb465fc-857fm          2/2     Running   0          48s
yelb-ui-859595cdb8-j2cqj          2/2     Running   0          48s

 

Nota: em um ambiente produtivo você não precisa deletar os pods existentes. Alterações tais como a adição de um novo Label nos pods já existente farão com o que os Envoy proxies sejam injetados. Neste tutorial, nós utilizamos o processo de deleção dos pods afim de manter as instruções mais simplificadas.

 

Observe que cada pod neste namespace agora possui dois containers. Vamos dar uma olhada mais de perto usando:

# Obter dados de um único pod:
$ YELB_POD=$(kubectl -n yelb get pod \
                     --no-headers=true \
                     --output name \|
                     awk -F "/" '{print $2}' \|
                     head -n 1)

# Descrever o pod:
$ kubectl -n yelb describe pod $YELB_POD
...
envoy:
    Container ID:   docker://1dbf736bfb6e89a1f4c9a567dbbfeeca26a0d846eda14f667ba128d4b5b36233
    Image:          840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.3.0-prod
    Image ID:       docker-pullable://840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy@sha256:f7ba6f019430c43f4fbadf3035e0a7c1555362a56a79d2d84280b2967595eeaf
    Port:           9901/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 13 May 2020 18:19:12 +0000
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:     10m
      memory:  32Mi
    Environment:
      APPMESH_VIRTUAL_NODE_NAME:  mesh/yelb/virtualNode/redis-server-virtual-node
      APPMESH_PREVIEW:            0
      ENVOY_LOG_LEVEL:            info
      AWS_REGION:                 us-west-2
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-tj7xx (ro)
...

Agora você pode voltar para a interface web do Yelb e certificar-se de que você pode acessá-la. Note que a contagem de votos estará zerada, uma vez que deletamos os pods no passo anterior.

 

5. Encaminhamento de tráfego para uma nova versão

Agora que o Yelb está em um mesh, vá em frente e crie uma nova versão do yelb-appserver. Nós vamos utilizar o App Mesh para encaminhar o tráfego de rede para esta nova versão da aplicação. Para isto, cria uma nova imagem de container com o código atualizado e realize o push para um repositório ECR utilizando o seguinte comando:

./build-appserver-v2.sh

Em seguida, crie um novo Virtual Node que representará esta nova versão da aplicação:

kubectl apply -f infrastructure/appmesh_templates/appmesh-yelb-appserver-v2.yaml

Além disso, precisamos realizar um novo deployment usando o manifesto gerado por build-appserver-v2.sh:

kubectl apply -f infrastructure/yelb_appserver_v2_deployment.yaml

Você deverá conseguir ver uma nova versão do yelb-appserver em execução listando os pods no namespace yelb:

$ kubectl get pods -n yelb

NAME                                 READY   STATUS    RESTARTS   AGE
redis-server-7dc845588-vfdld         2/2     Running   0          107m
yelb-appserver-7d644fbf76-2gmmc      2/2     Running   0          107m
*yelb-appserver-v2-658d6647d6-9t8x5  2/2     Running   0          21s
*yelb-db-76bdb465fc-fltjj            2/2     Running   0          107m
yelb-ui-68455b649b-677fb             2/2     Running   0          107m

Agora, configure a Virtual Route para que 50% do tráfego seja enviado para a versão v2 e 50% para a atual.

Note que quando lidando com ambientes produtivos, a mudança de tráfego normalmente ocorre em proporções menores (10%, 20%, 30%…).

O diagrama de arquitetura abaixo mostra o ambiente com duas versões do yelb-appserver  em execução ao mesmo tempo:

 

 

Para alterar a configuração da Virtual Route, execute o seguinte comando:

kubectl apply -f ./infrastructure/appmesh_templates/appmesh-virtual-router-appserver-v1-v2.yaml

Depois de modificar a Virtual Route, posso recarregar a página do Yelb algumas vezes e ver que alguns dos meus requests estão sendo atendidos pela versão antiga do yelb-appserver enquanto outros pela nova versão. Você pode identificar a versão olhando para o campo App Server, onde a versão antiga trará o nome do host do container yelb-appserver e a nova versão mostrará ApplicationVersion2.

Finalmente, vamos alterar a Virtual Route para que todo o tráfego seja roteado para a versão mais recente do yelb-appserver :

kubectl apply -f infrastructure/appmesh_templates/appmesh-virtual-router-appserver-v2.yaml

Você pode notar que depois de alterar a Virtual Route novamente, o deployment yelb-appserver-v2 é responsável por responder todos os requests:

 

 

6. Limpando

Para limpar todos os recursos criados durante a execução deste tutorial, execute o script de limpeza com o seguinte comando:

./infrastructure/cleanup.sh

Observe que, se você seguiu essas etapas usando uma instância do Cloud9, você deverá também consultar as etapas de limpeza para a instância do Cloud9 conforme descrito no Workshop do EKS.

 

Próximas etapas e conclusão

Você achará o Weave Flagger útil se estiver interessado em automatizar canary deployments. O Flagger permite que você promova canary deployments usando o AWS App Mesh automaticamente. Ele usa métricas do Prometheus para determinar o sucesso ou falha do canary deployment e usa os controles de roteamento do App Mesh para mudar automaticamente o tráfego entre a implantação atual e o canary.

Além disso, alguns links úteis se você quiser mergulhar mais fundo no tópico:

Neste post, analisamos os fundamentos do App Mesh e mostramos como colocar um aplicativo Kubernetes existente em um mesh usando o App Mesh Controller para K8s. Você também aprendeu como utilizar diferentes técnicas de deployments usando Virtual Routes para dividir o tráfego entre duas versões de uma aplicação. No próximo blog, vamos mostrar-lhe como você pode usar App Mesh Virtual Gateways para fornecer conectividade dentro e fora do mesh.

Você pode acompanhar o roadmap do serviço através do App Mesh roadmap e experimentar novos recursos usando o App Mesh preview channel. Por último, mas não menos importante: confira appmeshworkshop.com para aprender mais sobre o App Mesh de forma prática e junte-se a nós na comunidade App Mesh Slack para compartilhar experiências e discutir com a equipe e seus colegas.

 

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

 


Sobre os tradutores

Bruno Emer é Arquiteto de Soluções Especialista em Containers, localizado em São Paulo, Brasil. Quando ele não está trabalhando com clientes ou escrevendo conteúdos, ele gosta de viajar e ouvir música, principalmente samba e R&B.

 

 

 

 

Adriana Asano atua dentro da área de arquitetura e soluções da AWS, sua posição visa o aprendizado do cliente dentro da nuvem e o seu melhor desenvolvimento dentro desta jornada.