Creators
9
min de leitura
11 de fevereiro de 2021

Como criar um cluster Kubernetes com Terraform e AWS-EKS

Aécio Pires
Arquiteto de nuvens
É autor em livros sobre Zabbix, Puppet, Jenkins e Kubernetes. Contribui com projetos open source e pratica diariamente a cultura DevOps, utilizando ferramentas que permitem gerenciar a infraestrutura como código.
Mais sobre o autor

Introdução

Neste artigo iremos passar pelas boas práticas de como criar um cluster Kubernetes com Terraform e AWS-EKS, também conhecido por k8s (entenda o motivo aqui), utilizando o Terraform e o serviço EKS (Elastic Kubernetes Service) da AWS. Se você não sabe o que é Kubernetes, consulte o material Descomplicando o Kubernetes.

Se você não sabe o que é Terraform ou EKS, visite as seguintes páginas para obter mais informações:

http://blog.aeciopires.com/conhecendo-o-terraform

https://bit.ly/36iy82t

https://aws.amazon.com/eks.

Como uma forma de retribuir um pouco à comunidade de software livre, a Sensedia mantém um repositório no GitHub, chamado open-tools onde são publicados alguns scripts e ferramentas que utilizamos no dia a dia da operação de nossos serviços. Acreditamos que isso pode ajudar outras pessoas. Alguns dos comandos e código Terraform que vamos ver neste tutorial também estão publicados lá.

 

Pré-requisitos

Neste tutorial será criado um cluster Kubernetes utilizando o EKS 1.17.x. Veja as novidades desta versão nos links a seguir:

https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html

https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-release-announcement/

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.17.md

Atenção: Em cada versão do Kubernetes e do EKS pode haver mudanças significativas na API (Application Programming Interface), tag e outras configurações que podem afetar a compatibilidade das aplicações, manifests, escalabilidade e balanceadores de carga. Então, é bem importante ler as notas da release e testar a nova versão em um ambiente diferente do de produção para se antecipar aos possíveis problemas e evitar indisponibilidade.

Para executar os passos deste tutorial você precisa utilizar alguma distribuição GNU/Linux, pois os comandos não foram testados no MS Windows ou MacOS.

É necessário ter uma conta de acesso à AWS e com as policies AdministratorAccess e PowerUserAccess associadas diretamente a sua conta ou associadas a uma role (grupo de policies) ao qual você possa utilizar. Essas policies contém todas as permissões necessárias para gerenciar recursos da AWS.

É necessário ter instalado o aws-cli versão 1.16.x ou superior. Também é necessário configurar as credenciais de acesso à API da AWS. Instale seguindo os passos deste tutorial:

https://github.com/Sensedia/open-tools/blob/master/tutorials/install_awscli.md

É necessário ter instalado o kubectl versão 1.18.x ou superior. Se você não tem instalado, siga os passos deste tutorial:

https://github.com/Sensedia/open-tools/blob/master/tutorials/install_kubectl.md

É necessário ter instalado o Terraform versão 0.12.x. Instale seguindo os passos deste tutorial:

https://github.com/Sensedia/open-tools/blob/master/tutorials/install_terraform_0-12.md

Neste tutorial será criado uma rede VPC (Virtual Private Cloud) para uso no cluster Kubernetes e também será criado um bucket AWS-S3 e uma tabela no serviço AWS-DynamoDB para armazenarem o terraform state (informações do estado da infraestrutura a ser criada pelo Terraform).

Entendendo o código

Baixe o código fonte com os seguinte comandos:

cd ~

git clone git@github.com:Sensedia/open-tools.git

cd open-tools/terraform/eks

O diretório networking-eks contém o código necessário à criação da infraestrutura de rede requisito a criação do cluster EKS.

O nome de cada arquivo é bem intuitivo e o código dentro de cada um descreve a funcionalidade ou recursos a serem criados pelo Terraform. Exemplo: O arquivo vpc.tf, contém as instruções para gerenciar o recurso VPC e subnets da AWS. O arquivo policies.tf, cria as policies necessárias no serviço AWS-IAM.

O destaque fica por conta do arquivo testing.tfvars que contém os valores de alguns parâmetros importantes que podem ser customizados de acordo com a sua necessidade ou preferência. O arquivo outputs.tf contém o trecho de código que exibirá algumas informações sobre os recursos gerenciados pelo Terraform. Essas informações serão utilizadas para customizar o arquivo mycluster-eks/testing.tfvars.

O arquivo README.md contém as instruções e comandos a serem executados para criar a infraestrutura de rede.

Já o diretório mycluster-eks contém o código necessário à criação do cluster EKS.

O nome de cada arquivo também é intuitivo e o código dentro de cada um descreve a funcionalidade ou recursos a serem criados pelo Terraform. Exemplo: O arquivo eks.tf, contém as instruções para gerenciar o cluster.

O destaque também fica por conta do arquivo testing.tfvars e backend.tf que contém os valores de alguns parâmetros importantes que podem ser customizados de acordo com a sua necessidade.

O arquivo README.md contém as instruções e comandos a serem executados para criar o cluster.

Antes de executar os comandos da seção a seguir, abra cada arquivo e tente entender o que cada um faz. Consulte a documentação do Terraform e da AWS para entender melhor o que é cada recurso e para que serve.

Criando a VPC, o Bucket S3 e a tabela no DynamoDB

No arquivo open-tools/terraform/eks/networking-eks/testing.tfvars podemos ver o parâmetro region, que indica que a infraestrutura será criada na região Virginia (us-east-1), utilizando o profile default (que é o mesmo nome que está no arquivo ~/.aws/credentials e que deve conter a access key e secret key cadastradas para acessar a API da AWS).

Se não existir, crie um par de chaves assimétrico público-privada com o seguinte comando:

sudo ssh-keygen -t rsa -b 2048 -v -f /home/aws-testing.pem

Não informe uma senha durante a criação do par de chaves, apenas aperte ENTER. A chave pública será criada no seguinte caminho: /home/aws-testing.pem.pub e será cadastrada na AWS com o nome aws-testing. Essa chave pública será associada às instâncias EC2 durante a criação do cluster e dessa forma você poderá futuramente acessá-las via SSH utilizando a chave privada que está em /home/aws-testing.pem.

Estas informações foram cadastradas no arquivo open-tools/terraform/eks/networking-eks/testing.tfvars nos parâmetros aws_public_key_path e aws_key_name.

Outra informação importante a ser customizada neste mesmo arquivo é o parâmetro address_allowed, que contém o endereço IP público e máscara de rede que pode acessar a rede na qual será criado o cluster. Por padrão, o acesso externo é bloqueado.

O nome do bucket S3 que armazenará o terraform state está sendo definido no parâmetro bucket_name. O nome dos buckets na AWS é global e não pode haver outro bucket com o mesmo nome, mesmo em contas diferentes. É provável que você se depare com um erro durante a execução do Terraform dizendo que o bucket já existe e não será criado. A solução é definir outro nome. Esta informação será utilizada mais adiante para customizar a configuração do código que irá criar o cluster.

O nome da tabela no DynamoDB que será utilizado em conjunto com o bucket S3 serve para evitar que mais de uma pessoa altere o terraform state simultaneamente, está sendo definido no parâmetro dynamodb_table_name. Esta informação também será utilizada mais adiante para customizar a configuração do código que irá criar o cluster.

Crie a infraestrutura de rede (VPC, subnets, security group, route table, NAT Gateway, Internet Gateway), policies, bucket e tabela no DynamoDB com os seguintes comandos:

cd ~/ferramentas/terra-forma/eks/networking-eks

init terraformas

terraformar validar

espaço de trabalho terraforma novo teste

lista de espaços de trabalho em terraformas

espaço de trabalho em terraformas selecione os testes

plano terraformas -var-file testing.tfvars

terraform aplica-se -var-file testing.tfvars

A criação da infraestrutura de rede pode demorar 5 minutos ou mais.

Visualize as informações da infraestrutura criada com os seguintes comandos:

saída terraformas

As seguintes informações serão utilizadas na seção seguinte para configurar alguns parâmetros no arquivo open-tools/terraform/eks/mycluster-eks/testing.tfvars

balde_id

nome_chave

grupo_de_segurança

subnet_private1

subnet_public1

vpc1

Criando o cluster EKS

Edite o arquivo open-tools/terraform/eks/mycluster-eks/backend.tf. Com base na informações utilizadas na seção anterior, altere os seguintes parâmetros:

bucket: informe o nome bucket criado anteriormente. Exemplo: “my-terraform-remote-state-01“;

dynamodb_table: informe o nome da tabela criada no DynamoDB. Exemplo: " my-terraform-state-lock-dynamo";

region: informe o nome da região AWS utilizada para criar o cluster, deve ser a mesma na qual foi criada a infraestrutura de rede. Exemplo: “us-east-1“;

profile: informe o nome do perfil AWS com as credenciais de acesso a API configuradas no arquivo ~/.aws/credentials. Deve ser o mesmo utilizado para criar a infraestrutura de rede. Exemplo: “default“.

Edite o arquivo open-tools/terraform/eks/mycluster-eks/testing.tfvars. Com base na informações utilizadas na seção anterior, altere os seguintes parâmetros:

profile: informe o nome do perfil AWS com as credenciais de acesso a API configuradas no arquivo ~/.aws/credentials. Deve ser o mesmo utilizado para criar a infraestrutura de rede. Exemplo: “default“.

region: informe o nome da região AWS utilizada para criar o cluster, deve ser a mesma na qual foi criada a infraestrutura de rede. Exemplo: “us-east-1“;

address_allowed: o endereço IP público e máscara de rede que pode acessar a rede na qual será criado o cluster. Exemplo: "“201.82.34.213/32”.

subnets: deve conter a lista com os IDs da subnet_private1 e subnet_public_1, mostrados no fim da seção anterior. Exemplo: ["subnet-06dd40e8124e67325", "subnet-098580d73a131193c"];

vpc_id: deve conter o ID da vpc1 mostrada no fim da seção anterior. Exemplo: "vpc-068004d30dd97a13b";

cluster_name: contém o nome do cluster. O nome informado aqui deve ser o mesmo no fim das tags “k8s.io/cluster-autoscaler/mycluster-eks-testing” e “kubernetes.io/cluster/mycluster-eks-testing”, do contrário não será possível habilitar o autoscaling do cluster. Exemplo: “mycluster-eks-testing”;

cluster_version: contém a versão do EKS a ser utilizada no cluster. Exemplo: “1.17”;

override_instance_types: lista com os tipos de instância EC2 a serem usados no cluster. Exemplo: ["t3.micro", "t3a.micro"];

on_demand_percentage_above_base_capacity: percentual de instâncias on demand a serem utilizadas no cluster. O percentual restante será de instâncias spot (mais baratas, porém efêmeras). Exemplo: 50;

asg_min_size: quantidade mínima de instâncias no cluster. Exemplo: 2;

asg_max_size: quantidade máxima de instâncias no cluster. Exemplo: 20;

asg_desired_capacity: quantidade deseja de instâncias no cluster. Exemplo: 2;

root_volume_size: tamanho em GB do disco a ser utilizado em cada instância. Exemplo: 20;

aws_key_name: nome da chave pública cadastrada na seção anterior a ser utilizada pelas instâncias EC2 do cluster. Exemplo: “aws-testing”;

worker_additional_security_group_ids: lista contendo o ID do security group criado na seção anterior que será associado ao cluster. Exemplo: ["sg-0bc21eaa5b3a26146"];

Obtenha o ID de sua conta AWS com o seguinte comando:

aws sts get-caller-identity -query Account -output text -profile PROFILE_NAME_AWS

Onde:

PROFILE_NAME_AWS: é o nome do perfil AWS definido na configuração do arquivo ~/.aws/credentials

Edite novamente o arquivo open-tools/terraform/eks/mycluster-eks/testing.tfvars.

E altere todas as ocorrências do ID 255686512659 pelo ID da sua conta. Altere também a ocorrência da role adsoft pelo nome da role cadastrada na sua conta (se houver) e altere a ocorrência do usuário aeciopires pelo seu nome de usuário na AWS. Isto é muito importante porque os usuários e roles informados nos parâmetros map_roles e map_users serão os únicos admins do cluster EKS.

Finalmente, crie o cluster EKS com os seguintes comandos:

cd ~/ferramentas/terra-forma/eks/mycluster-eks

init terraformas

terraformar validar

espaço de trabalho terraforma novo teste

lista de espaços de trabalho em terraformas

espaço de trabalho em terraformas selecione os testes

plano terraformas -var-file testing.tfvars

terraform aplica-se -var-file testing.tfvars

Obs: A criação do cluster pode demorar 15 minutos ou mais.

Visualize as informações do cluster criado com os seguintes comandos:

saída terraformas

show terraform


Acessando o cluster EKS

Execute o seguinte comando para ter acesso ao cluster.

aws eks -region REGION_NAME update-kubeconfig -nome CLUSTER_NAME -profile PROFILE_NAME_AWS

Onde:

REGION_NAME: é o nome da região na qual o cluster foi criado.

CLUSTER_NAME: é o nome do cluster criado.

PROFILE_NAME_AWS: é o nome do perfil AWS definido na configuração do arquivo ~/.aws/credentials.

Exemplo:

aws eks -region us-east-1 update-kubeconfig -name mycluster -profile default

Para testar o acesso, visualize o status dos pods com o seguinte comando.

kubectl get pods - todos os espaços de nomes

 

Troubleshooting no EKS

As informações sobre como fazer troubleshooting no EKS estão disponíveis nos links a seguir:

https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting.html

https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting_iam.html

https://aws.amazon.com/pt/premiumsupport/knowledge-center/eks-api-server-unauthorized-error

https://aws.amazon .com/premiumsupport/knowledge-center, seção Amazon Elastic Container Service for Kubernetes (Amazon EKS)

 

Visualizando o preço

As informações sobre o preço do uso do EKS, depende da região da AWS na qual o cluster está sendo criado, do tipo de instância EC2 que está sendo utilizado nos nodes workers, se está ou não utilizando instâncias spot, on-demand, se está utilizando instâncias reservadas, o tamanho e tipo do disco utilizado em cada nodes worker, se está sendo ou não utilizando uma VPC e NAT Gateway compartilhados com outros serviços, do data transfer entre as redes externas envolvidas, e ainda se está ou não utilizando algum Load Balancer da AWS para permitir o acesso externo às aplicações, o preço do Load Balancer também varia de acordo com o tipo, podendo ser: classic (ELB), application (ALB) ou network (NLB). Além disso a AWS cobra uma taxa de US$ 0.10 por hora para cada cluster EKS.

Obtenha mais informações sobre o preço do serviço AWS-EKS nos links a seguir:

https://aws.amazon.com/eks/preços

https://aws.amazon.com/pt/ec2/pricing/on-demand

https://aws.amazon.com/eks/faqs

Para ajudar a obter uma estimativa de preço, a AWS fornece uma calculadora de preços: https://calculator.aws.

Veja um exemplo do custo mensal e anual da infraestrutura usada neste tutorial na região Virginia (us-east-1):

https://calculator.aws/#/estimate?id=de2c57ee696545b1fc9c6248533652724e208e5c

 

Documentação

A documentação completa dos recursos utilizados neste tutorial estão disponíveis nos links a seguir. Utilize estas informações para aprofundar o aprendizado no dia a dia.

Terraform: https://www.terraform.io/docs

Provider AWS: https://www.terraform.io/docs/providers/aws

Módulo Terraform para EKS: https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/13.0.0

AWS-VPC: https://docs.aws.amazon.com/vpc/latest/guia do usuário

AWS-S3: https://docs.aws.amazon.com/AmazonS3/latest/gsg

AWS-DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide

AWS-EKS: https://docs.aws.amazon.com/eks/latest/userguide

 

Removendo o cluster EKS

Execute os seguintes comandos para remover o cluster EKS:

cd ~/ferramentas/terra-forma/eks/mycluster-eks

espaço de trabalho em terraformas selecione os testes

terraformar destruir -var-file testing.tfvars

A remoção do cluster pode demorar 5 minutos ou mais.

Removendo a VPC e os buckets S3

Execute os seguintes comandos para remover a infraestrutura de rede criada:

cd ~/ferramentas/terra-forma/eks/networking-eks

espaço de trabalho em terraformas selecione os testes

terraformar destruir -var-file testing.tfvars

A remoção da infraestrutura de rede pode demorar 5 minutos ou mais.

Se ao final da remoção dos recursos, você visualizar o seguinte erro, acesse o console web da AWS e, em seguida, acesse a URL: https://s3.console.aws.amazon.com/s3/. Localize o nome do bucket e marque o checkbox ao lado esquerdo do nome. Em seguida, clique no botão empty. Siga as instruções para esvaziar o bucket.

Error: error deleting S3 Bucket …

BucketNotEmpty: The bucket you tried to delete is not empty. You must delete all versions in the bucket.

Depois disso, edite o arquivo open-tools/terraform/eks/networkin-eks/bucket.tf e altere o seguintes parâmetros:

Antes:

  versão {

 enabled = true

   }

   ciclo de vida {

   prevent_destroy = true

  }

Depois:

 force_destroy = true

  versão {

 enabled = false

  }

  ciclo de vida {

  prevent_destroy = false

  }

Novamente execute os seguintes comandos para remover o bucket:

terraformar destruir -var-file testing.tfvars

Isto é necessário porque o bucket armazena o terraform state e em uma situação normal no ambiente de produção não é esperado que o bucket seja removido para evitar perder o rastreio das mudanças no ambiente usando o Terraform.

Considerações finais

Neste tutorial aprendemos a criar um cluster kubernetes do zero utilizando o Terraform para gerenciar toda a infraestrutura de rede e o serviço AWS-EKS.

Nos próximos tutoriais apresentaremos o uso de outras tecnologias envolvendo o EKS para realizar o monitoramento de métricas, deploy e observabilidade de aplicações.

Referências


https://kubernetes.io 


https://bit.ly/3p9xVXZ 


https://www.terraform.io 


https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html


https://github.com/badtuxx/DescomplicandoKubernetes


http://blog.aeciopires.com/conhecendo-o-terraform


https://bit.ly/36iy82t 


https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html


https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-release-announcement/


https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.17.md


https://github.com/Sensedia/open-tools 


https://aws.amazon.com/eks


https://aws.amazon.com/vpc


https://aws.amazon.com/s3


https://aws.amazon.com/pt/dynamodb


http://blog.aeciopires.com/primeiros-passos-com-docker


https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting.html


https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting_iam.html


https://amzn.to/356ge3m 


https://aws.amazon .com/premiumsupport/ centro de conhecimento  


https://aws.amazon.com/eks/preços


https://aws.amazon.com/pt/ec2/pricing/on-demand


https://aws.amazon.com/eks/faqs 


https://calculator.aws


Obrigado pela leitura!