O blog da AWS

Implementando GitOps no Amazon EKS com FluxCD

Por Davi Garcia, Arquiteto Especialista em Modernização & Containers na AWS

 

Afinal, o que é GitOps? De maneira simples, o GitOps é uma abordagem para implantação contínua de ambientes nativos de nuvem, onde definições de infraestrutura como código são armazenadas em repositórios Git, seguindo a mesmo processo de integração que os códigos de aplicação, e são implantadas através de um processo automatizado fim-a-fim.

Em contraste com uma esteira de Implantação Contínua (CD) tradicional, onde temos um estágio executando intervenção direta no nosso ambiente, com GitOps temos um mecanismo automatizado de detecção de desvios (“drift”) que identifica se o estado desejado armazenado no repositório Git foi alterado e implementa as modificações necessárias de forma autônoma. A abordagem proposta pelo GitOps busca eliminar intervenções diretas na infraestrutura e simplificar o processo de Implantação Contínua em ambientes distribuídos, além de melhorar a governança através das informações de rastreabilidade fornecidas pelo Git.

As características de operação declarativa e a extensibilidade do Kubernetes fazem dele uma excelente plataforma para prática de GitOps. Através de controladores e recursos customizados, construções chamadas de “Kubernetes Operators”, agregam-se novas capacidades de automação ao Kubernetes, que farão o trabalho buscar definições em repositórios externos e executar os laços de reconciliação de estado necessários para implantar as mudanças. Existem diversos projetos open-source que buscam implementar esse mecanismo, como por exemplo FluxCD, ArgoCD e Jenkins X.

Neste artigo vamos explorar como implantar a prática de GitOps em um cluster Kubernetes usando o Amazon Elastic Kubernetes Service (EKS) e a integração entre as ferramentas eksctl e FluxCD.

 

Visão Geral de Componentes e Arquitetura

Arquitetura: Ambiente de Demonstração

A ideia proposta neste blog é de poder provisionar um cluster fim-a-fim, com componentes de infraestrutura complementares e uma aplicação de exemplo, através do mecanismo de GitOps. O diagrama a seguir descreve a arquitetura alto nível do ambiente de prova que será criado no decorrer deste artigo, assim como as interações entre os componentes e atores.

 

Diagrama de arquitetura do ambiente de demonstração.

 

Em resumo, as etapas serão:

  1. As pessoas usuárias ou administradoras determinam as definições necessárias para o ambiente Amazon EKS, e armazenam tais definições em um repositório Git no GitHub.
  2. A partir de um manifesto de declaração de estado, a pessoa administradora cria o ambiente Amazon EKS através da ferramenta eksctl;
  3. Após as etapas de criação e configuração do cluster, a ferramenta eksctl inicializa (“bootstrap”) o FluxCD no ambiente seguindo as definições também contidas no manifesto;
  4. Os componentes do FluxCD são inicializados no Kubernetes, e iniciam o processo de sincronismo das definições contidas no repositório do Git referente ao ambiente (Source Controllers);
  5. O FluxCD inicia os processos de reconciliação de estado (Consumer Controllers), implantando primeiro as definições relacionadas à infraestrutura do ambiente baseadas em Helm Charts (componentes extras da AWS, Kubernetes e terceiros);
  6. Em seguida modificamos o conteúdo no repositório Git, agregando definições da aplicação simples baseada em Kustomize, o podinfo;
  7. O FluxCD identifica mudança no repositório base, e inicia o processo de reconciliação de estado novamente, implantando as definições da aplicação;

Para a demonstração, vamos usar como exemplo os artefatos disponíveis no repositório https://github.com/aws-samples/eks-fluxcd-bootstrap. Esse repositório possui uma estrutura de arquivos e diretórios específica para o caso de uso de GitOps.

Vamos entender o propósito da estrutura e arquivos:

  1. helpers/eksctl-config.yaml: Este é o arquivo de configuração do cluster Amazon EKS que usaremos na demonstração. Ele define não só as configurações de infraestrutura, mas também contém os parâmetros a serem usados no processo de inicialização (“bootstrap”) do FluxCD.
  2. clusters/sandbox/infrastructure.yaml: Este arquivo é uma definição do tipo Kustomization para o cluster de demonstração, que instrui o FluxCD a implantar todos os manifestos definidos no diretório infrastructure/ através do Kustomize.
  3. infrastructure/kustomization.yaml: Este arquivo é uma definição Kustomize (Kubernetes nativo), que define como as outras definições nos diretórios filhos serão consumidas.
  4. infrastructure/sources/*.yaml: Estes arquivos definem as fontes (“sources”) dos componentes que serão implantados a partir de diversos repositórios de Helm Charts, usando objetos do tipo HelmRepository (FluxCD).
  5. infrastructure/kube-addons/*.yaml: Estes arquivos definem releases de Helm Charts para os componentes add-ons da comunidade Kubernetes (Cluster-Autoscaler e Metrics-Server), via HelmRelease (FluxCD).
  6. infrastructure/aws-addons/*.yaml: Estes arquivos definem releases de Helm Charts para os componentes add-ons da AWS (Container Insights e Load Balancer Controller), via HelmRelease (FluxCD).
  7. infrastructure/other-addons/*.yaml: Estes arquivos definem releases de Helm Charts para os componentes de terceiros (Calico), via HelmRelease (FluxCD).

Esta estrutura de arquivos e diretórios não é obrigatória, mas simplifica a gestão do repositório quando temos mais de um cluster usando GitOps e consumindo repositórios compartilhados.

Componente: Amazon Elastic Kubernetes Service (EKS)

O Amazon Elastic Kubernetes Service (Amazon EKS) oferece a flexibilidade de iniciar, executar e escalar cargas de trabalho em containers com Kubernetes na AWS. O Amazon EKS ajuda você a fornecer clusters altamente disponíveis e seguros, além de automatiza tarefas importantes, como patches, provisionamento de nós e atualizações.

O Amazon EKS executa o Kubernetes upstream e possui certificado de conformidade pela Cloud Native Computing Foundation (CNCF), garantindo uma experiência previsível para pessoas com experiência prévia com Kubernetes. Essa certificação fornece uma garantia que qualquer aplicação padrão para o Kubernetes pode ser facilmente implantada no Amazon EKS.

Mais informações no site do serviço, https://docs.aws.amazon.com/pt_br/eks.

Componente: Amazon EKS CLI – eksctl

O eksctl é uma ferramenta simples de linha de comando (CLI) para criar e gerenciar clusters de Amazon Elastic Kubernetes Service (EKS). Esta ferramenta é escrita em Go, e utiliza do AWS CloudFormation como camada de Infraestrutura-como-Código (IaC).

Esta ferramenta pode ser usada de duas formas, imperativa e declarativa. Na forma declarativa definimos as características do cluster em um arquivo de configuração no formato YAML, que será usado como argumento para a ferramenta

 

Exemplo de um arquivo de configuração do eksctl e comandos em um terminal Bash.

 

Além do cluster Amazon EKS em si, o eksctl vai provisionar a infraestrutura necessária para suportar o cluster, incluindo construções do Amazon VPC e Amazon IAM. Usaremos desta capacidade na nossa demonstração.

Mais informações no site do projeto, https://eksctl.io.

Componente: Helm e Kustomize

A operação declarativa do Kubernetes envolve a manipulação de arquivos YAML, que declaram os estados desejados dos seus objetos, também chamado de manifestos. À medida que as complexidades das aplicações aumentam, o esforço para gerar e operacionalizar os manifestos manualmente rapidamente se tornam um gargalo. Duas ferramentas surgiram para endereçar esse desafio:

  • Helm: Análoga ao YUM ou APT do mundo Linux, esta ferramenta se propõe a ser um “gerenciador de pacotes” de aplicações no Kubernetes. Os manifestos Kubernetes necessários para uma aplicação são empacotados em um Chart, que pode ser distribuído e reaproveitado em ambientes diferentes. Os Helm Chart podem ser armazenados em repositórios, e podem ser parametrizados através de valores passados durante sua instalação (“releases”).
  • Kustomize: Integrada ao cliente de linha de comando do Kubernetes (“kubectl”), esta ferramenta provê um mecanismo de gestão de configuração para os manifestos sem se utilizar de “templates”. O Kustomize utiliza de um arquivo de configuração chamado “kustomization.yaml” para definir como os manifestos bases vão ser consumidos, e se alguma modificação precisa ser aplicada (“overlays”) para montar o manifesto final.

Mais informações nos sites dos projetos, https://helm.sh e https://kustomize.io.

Componente: Controlador GitOps – FluxCD

O FluxCD, ou somente Flux, é uma ferramenta para manter clusters Kubernetes em sincronia com fontes de configuração (como repositórios Git) e automatizar atualizações de configuração quando há uma nova versão a ser implantada. A versão 2 desta ferramenta foi desenvolvida do zero para usar o sistema de extensão da API do Kubernetes e se integrar com restante do ecossistema do Kubernetes.

Esta ferramenta é composta por diversos componentes que estendem e interagem com a API do Kubernetes. As configurações são manipuladas através de definições customizadas de recursos (“Custom Resource Definitions”, ou CRDs). Ela contém além dos componentes implantados no cluster Kubernetes, uma ferramenta de linha de comando (CLI).

Figura 3 – Diagrama de arquitetura dos componentes do FluxCD (v2).

Neste artigo vamos usar 2 tipos de componentes:

  • Source Controller: Provê interface para obtenção de artefatos a partir de repositórios externos. Estas fontes são configuráveis através dos CRDs: GitRepository, HelmRepository e Bucket.
  • Consumer Controllers: Proveem interface para implantação contínua de artefatos (reconciliação de estado), usando Kustomize ou Helm, a partir das fontes conhecidas. Estes reconciliadores são configuráveis através dos CRDs: Kustomization e HelmRelease.

Mais informações no site do projeto, https://fluxcd.io.

Mãos na Massa!

Pré-requisitos

Para poder executar os passos descritos neste artigo, você precisará atender os seguintes pré-requisitos:

Demonstração

Neste artigo os passos serão executados a partir de um ambiente Amazon Linux 2, porém você também pode reproduzir todos os passos em qualquer ambiente que disponha de um terminal (“Shell”), incluindo ambientes Apple Mac OSX e Microsoft Windows com WSL2.

Além disso, o AWS CLI deve estar configurado permissão para provisionar os recursos necessários para o cluster Amazon EKS. Como esse provisionamento será realizado pelo eksctl, recomendamos confirmar que se o usuário/role configurado com o AWS CLI possui as permissões mínimas.

Preparação

  1. Precisamos instalar as ferramentas de linha de comando (CLI) eksctl, flux e kubectl, que serão usadas nas etapas seguintes de demonstração.
mkdir -p $HOME/.local/bin

curl -fsSL https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz |\
     tar xz -C /tmp
mv /tmp/eksctl $HOME/.local/bin
chmod +x $HOME/.local/bin/eksctl

curl -fsSL https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl \
     -o /tmp/kubectl
mv /tmp/kubectl $HOME/.local/bin
chmod +x $HOME/.local/bin/kubectl

curl -sLo /tmp/flux-install.sh https://fluxcd.io/install.sh
chmod 700 /tmp/flux-install.sh
/tmp/flux-install.sh $HOME/.local/bin/ &> /dev/null
  1. Vamos fazer uma cópia (“fork”) do repositório https://github.com/aws-samples/eks-fluxcd-bootstrap, usando sua conta do GitHub onde criamos o Personal Access Token.

 

Localização do botão de “fork” no repositório do GitHub.

 

  1. Agora precisamos criar um Personal Access Token no GitHub, associado à conta usada para criar a cópia (“fork”) do repositório. Este token será usado pelo eksctl no processo de inicialização (“bootstrap”) do FluxCD para se autenticar nas APIs do GitHub e, portanto, precisará somente das permissões do escopo “repo”. O token pode ser criado clicando neste link automatizado e depois em “Generate Token”. Não esqueça de copiar o token no final do processo!

 

Escopo de permissões na criação de um Personal Access Token.

 

  1. E então vamos configurar variáveis de ambientes para o nosso usuário de Personal Access Token do GitHub que criamos no passo 1, e clonar o nosso repositório e criar a “branch” usada na demonstração. Você pode usar o Personal Access Token que criamos para autenticar no seu repositório.
export GITHUB_TOKEN=<YOUR GH TOKEN>
export GITHUB_USER=<YOUR GH USERNAME>

git clone https://github.com/$GITHUB_USER/eks-fluxcd-bootstrap
cd eks-fluxcd-bootstrap/

git checkout -b demo
git push -u origin demo


Implantação da Infraestrutura

  1. Antes de implantarmos o nosso cluster de Amazon EKS, edite o arquivo de configuração helpers/eksctl-config.yaml. Na sessão gitops, modifique o nome de usuário do GitHub onde a cópia (“fork”) do repositório de exemplo foi criada.
  2. Depois, vamos usar o eksctl para criar o cluster a partir do arquivo de configuração helpers/eksctl-config.yaml. O processo de criação fim-a-fim pode levar por volta de 35 minutos.

eksctl create cluster -f helpers/eksctl-config.yaml

  1. Após a instalação, o nosso cluster estará operacional e com diversos componentes complementares já implantados através do FluxCD.

kubectl get pods --all-namespaces

Esse processo de implantação pelo FluxCD pode levar alguns poucos minutos. Quando completo, a saída deverá ser como a imagem abaixo:

 

Exemplo de saída do comando kubectl.

 

  1. Como todas as extensões do FluxCD são objetos válidos do Kubernetes, você pode listar todas as definições de GitRepository, HelmRepository, Kustomization e HelmRelease.

kubectl get gitrepository,kustomization,helmrepository,helmrelease --all-namespaces

  1. Uma outra opção seria verificar através da ferramenta do próprio FluxCD, o flux instalado no passo 4 da sessão anterior, que fornece algumas informações complementares de forma automática.

flux get all --all-namespaces

A saída deverá ser como a imagem abaixo:

 

Exemplo de saída do comando flux.

 

Implantação da Aplicação

Agora que implantamos os componentes de infraestrutura, vamos exercitar a capacidade de reconciliação de estado do GitOps e implantar a nossa aplicação de exemplo. Para tal, vamos adicionar ao nosso repositório base os manifestos de definições da aplicação. Vamos usar do flux CLI para nos ajudar com a criação das definições YAML.

  1. Primeiro vamos criar a definição de Kustomization que vai indicar onde que as definições da aplicação estarão. A ideia é análoga ao arquivo clusters/sandbox/infrastructure.yaml.
flux create kustomization application --source=GitRepository/flux-system \
                                      --path=./application \
                                      --prune \
                                      --export > clusters/sandbox/application.yaml
  1. Depois vamos criar a origem das definições, através de um GitRepository, e da implantação, através de um Kustomization. Usaremos um repositório externo para demonstrar a capacidade de ter várias fontes em uso ao mesmo tempo.
mkdir application

flux create source git podinfo --url=https://github.com/stefanprodan/podinfo \
                               --tag="6.0.0" \
                               --export > application/podinfo-source.yaml

flux create kustomization podinfo --source=GitRepository/podinfo \
                                      --path=./kustomize \
                                      --prune \
                                      --export > application/podinfo-deployment.yaml
  1. Se você olhar a definição da aplicação de exemplo, ela não expõe publicamente nenhum endpoint para acesso. Vamos usar do recurso do Kustomize (Kubernetes) através do objeto Kustomization (FluxCD) para aplicar um patch na definição original e usar o tipo LoadBalancer ao invés de ClusterIP para o Service podinfo.
cat <<EOF >> application/podinfo-deployment.yaml
  patchesJson6902:
  - target:
      version: v1
      kind: Service
      name: podinfo
    patch:
    - op: add
      path: /spec/type
      value: LoadBalancer
EOF

No final teremos os seguintes arquivos:

 

 

  1. Depois de criar os arquivos, vamos enviar as mudanças para a nossa cópia (“fork”) do repositório de demonstração. No processo de inicialização (“bootstrap”), o FluxCD faz duas modificações no na branch “demo”, então precisamos puxar essas modificações antes de incluir as novas.
git pull
git add clusters/sandbox/application.yaml application/
git commit -m 'feat: add application manifests'
git push origin demo

Nesse ponto, precisamos esperar 2 minutos para o FluxCD identificar a mudança nas definições armazenadas no Git, e realizar a reconciliação de estado para implantar nossa aplicação. Se você não quiser esperar, podemos forçar esse processo.

flux reconcile source git flux-system
flux resume kustomization flux-system
  1. Podemos validar se a implantação dos componentes da aplicação aconteceu como esperado.
flux get sources git podinfo
flux get kustomizations podinfo
kubectl get all -n default

 

  1. Para acessar a aplicação, você pode abrir o navegador na URL External-IP do servisse/podinfo, na porta 9898. A URL final deve ser http://<external-ip url>:9898, e deve apresentar a imagem abaixo.

kubectl get svc podinfo -o jsonpath="{'http://'}{.status.loadBalancer.ingress[0].hostname}{':9898\n'}"

Limpeza

  1. Para remover o ambiente Amazon EKS, podemos destruir os recursos através do eksctl.

eksctl delete cluster -f helpers/eksctl-config.yaml

  1. Opcionalmente, você pode apagar a ramificação (“branch”) da sua cópia do repositório de demonstração, ou o repositório por inteiro.
git checkout main
git push --delete origin demo
git branch -D demo
  1. O GitHub Personal Access Token usado na demonstração vai expirar automaticamente (de acordo com o período que você configurou). Dado que essa credencial foi criada exclusivamente para essa demonstração, recomendamos a remoção.

Conclusão

A abordagem de GitOps permite escalar a prática de Implantação Contínua em ambientes distribuídos de containers, agregando transparência e rastreabilidade no processo de gestão de mudança através do Git. Além disso, a capacidade de identificação e remediação de desvios de configuração (“drift”) simplifica a recuperação do ambiente em cenários de problemas operacionais.

Neste artigo, analisamos uma forma de implantar a prática de GitOps em ambiente Kubernetes com Amazon Elastic Kubernetes Service (EKS) através do projeto open-source FluxCD. Você também pôde ver na prática como realizar a implantação fim-a-fim de um cluster, incluindo componentes de infraestrutura e de aplicação, de diferentes tipos e repositórios.

 


Sobre o autor

Davi Garcia é Arquiteto Especialista de Soluções, focado em Modernização de Aplicações na AWS, e ajuda clientes de diversos segmentos na América Latina. Possui larga experiência em plataforma de containers e automação de infraestrutura. Ele gosta de contribuir com projetos open-source, se divertir em família com jogos de tabuleiros e velejar.

 

 

 

Explore mais conteúdos sobre Computação na página de Sessions On Demand.

Acesse >