Creators
9
min de lectura
11 de febrero de 2021

Cómo crear un cluster Kubernetes con Terraform y AWS-EKS

Aécio Pires
Arquitecto de la nube
Es autor de libros sobre Zabbix, Puppet, Jenkins y Kubernetes. Contribuye con proyectos de código abierto y practica diariamente la cultura DevOps, utilizando herramientas que permiten gestionar la infraestructura como el código.
Más sobre el autor

Introducción

En este artículo pasaremos por las buenas prácticas de cómo crear un cluster Kubernetes con Terraform y AWS-EKS, también conocido por k8s (entienda el motivo aquí), utilizando Terraform y el servicio EKS (Elastic Kubernetes Service) de AWS. Si usted no sabe qué es Kubernetes, consulte el material Simplificando Kubernetes.

Si usted no sabe qué es Terraform o EKS, visite las siguientes páginas para obtener más informaciones:

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

https://bit.ly/36iy82t

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

Como una forma de retribuirle un poco a la comunidad de software libre, Sensedia mantiene un repositorio en GitHub, llamado open-tools donde son publicados algunos scripts y herramientas que utilizamos en el día a día de la operación de nuestros servicios. Creemos que esto puede ayudar a otras personas. Algunos de los comandos y código Terraform que vamos a ver en este tutorial también están publicados allá.

 

Prerrequisitos

En este tutorial será creado un cluster Kubernetes utilizando EKS 1.17.x. Vea las novedades de esta versión en los enlaces a continuación:

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

Atención: En cada versión de Kubernetes y de EKS puede haber cambios significativos en la API (Application Programming Interface), tag y otras configuraciones que pueden afectar la compatibilidad de las aplicaciones, manifests, escalabilidad y balanceadores de carga. Entonces, es muy importante leer las notas de la reléase y probar la nueva versión en un ambiente diferente del de producción para anticiparse a los posibles problemas y evitar indisponibilidad.

Para ejecutar los pasos de este tutorial usted debe utilizar alguna distribución GNU/Linux, pues los comandos no fueron probados en MS Windows o MacOS.

Es necesario tener una cuenta de acceso a AWS y con las policies AdministratorAccess y PowerUserAccess asociadas directamente a su cuenta o asociadas a una role (grupo de policies) al cual usted pueda utilizar. Estas policies contienen todos los permisos necesarios para gestionar recursos de AWS.

Es necesario haber instalado aws-cli versión 1.16.x o superior. También es necesario configurar las credenciales de acceso a la API de AWS. Instale siguiendo los pasos de este tutorial:

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

Es necesario haber instalado kubectl versión 1.18.x o superior. Si usted no lo ha instalado, siga los pasos de este tutorial:

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

Es necesario haber instalado terraform versión 0.12.x. Instale siguiendo los pasos de este tutorial:

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

En este tutorial será creado una red VPC (Virtual Private Cloud) para uso en el cluster Kubernetes y también será creado un bucket AWS-S3 y una tabla en el servicio AWS-DynamoDB para almacenar el terraform state (informaciones del estado de la infraestructura a ser creada por Terraform).

Entendiendo el código

Baje el código fuente con los siguientes comandos:

cd ~

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

cd open-tools/terraform/eks

El directorio networking-eks contiene el código necesario para la creación de la infraestructura de red requisito la creación del cluster EKS.

El nombre de cada archivo es muy intuitivo y el código dentro de cada uno describe la funcionalidad o recursos a ser creados por Terraform. Ejemplo: El archivo vpc.tf, contiene las instrucciones para gestionar el recurso VPC y subnets de AWS. El archivo policies.tf, crea las policies necesarias en el servicio AWS-IAM.

El destaque queda por cuenta del archivo testing.tfvars que contiene los valores de algunos parámetros importantes que pueden ser personalizados de acuerdo con su necesidad o preferencia. El archivo outputs.tf contiene el tramo de código que exhibirá algunas informaciones sobre los recursos administrados por Terraform. Estas informaciones serán utilizadas para personalizar el archivo mycluster-eks/testing.tfvars.

El archivo README.md contiene las instrucciones y comandos a ser ejecutados para crear la infraestructura de red.

Ya el directorio mycluster-eks contiene el código necesario para la creación del cluster EKS.

El nombre de cada archivo también es intuitivo y el código dentro de cada uno describe la funcionalidad o recursos a ser creados por Terraform. Ejemplo: El archivo eks.tf, contiene las instrucciones para gestionar el cluster.

El destaque también queda por cuenta del archivo testing.tfvars y backend.tf que contiene los valores de algunos parámetros importantes que pueden ser personalizados de acuerdo con su necesidad.

El archivo README.md contiene las instrucciones y comandos a ser ejecutados para crear el cluster.

Antes de ejecutar los comandos de la sección siguiente, abra cada archivo e intente entender lo que hace cada uno. Consulte la documentación de Terraform y de AWS para entender mejor qué es cada recurso y para qué sirve.

Creando la VPC, el Bucket S3 y la tabla en DynamoDB

En el archivo open-tools/terraform/eks/networking-eks/testing.tfvars podemos ver el parámetro region, que indica que la infraestructura será creada en la región Virginia (us-east-1), utilizando el profile default (que es el mismo nombre que está en el archivo ~/.aws/credentials y que debe contener la access key y secret key registradas para acceder a la API de AWS).

Si no existe, cree un par de claves asimétrico público-privada con el siguiente comando:

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

No informe una contraseña durante la creación del par de claves, solamente apriete ENTER. La clave pública será creada en el siguiente camino: /home/aws-testing.pem.pub y será registrada en AWS con el nombre aws-testing. Esta clave pública será asociada a las instancias EC2 durante la creación del cluster y de esta forma usted podrá en el futuro accederlas vía SSH utilizando la clave privada que está en /home/aws-testing.pem.

Estas informaciones fueron registradas en el archivo open-tools/terraform/eks/networking-eks/testing.tfvars en los parámetros aws_public_key_path y aws_key_name.

Otra información importante para personalizar en este mismo archivo es el parámetro address_allowed, que contiene la dirección IP pública y máscara de red que puede acceder a la red en la cual será creado el cluster. Por defecto, el acceso externo es bloqueado.

El nombre del bucket S3 que almacenará el terraform state está siendo definido en el parámetro bucket_name. El nombre de los buckets en AWS es global y no puede haber otro bucket con el mismo nombre, incluso en cuentas diferentes. Es probable que usted se depare con un error durante la ejecución de Terraform diciendo que el bucket ya existe y no será creado. La solución es definir otro nombre. Esta información será utilizada más adelante para personalizar la configuración del código que creará el cluster.

El nombre de la tabla en DynamoDB que será utilizado en conjunto con el bucket S3 sirve para evitar que más de una persona modifique el terraform state simultáneamente, está siendo definido en el parámetro dynamodb_table_name. Esta información también será utilizada más adelante para personalizar la configuración del código que creará el cluster.

Cree la infraestructura de red (VPC, subnets, security group, route table, NAT Gateway, Internet Gateway), policies, bucket y tabla en DynamoDB con los siguientes comandos:

cd ~/open-tools/terraform/eks/networking-eks

terraform init

terraform validate

terraform workspace new testing

terraform workspace list

terraform workspace select testing

terraform plan -var-file testing.tfvars

terraform apply -var-file testing.tfvars

La creación de la infraestructura de red puede demorar 5 minutos o más.

Visualice las informaciones de la infraestructura creada con los siguientes comandos:

terraform output

Las siguientes informaciones serán utilizadas en la sección siguiente para configurar algunos parámetros en el archivo open-tools/terraform/eks/mycluster-eks/testing.tfvars

bucket_id

nombre_clave

grupo_seguridad

subnet_private1

subnet_public1

vpc1

Creando el cluster EKS

Edite el archivo open-tools/terraform/eks/mycluster-eks/backend.tf. Con base en las informaciones utilizadas en la sección anterior, modifique los siguientes parámetros:

bucket: informe el nombre bucket creado anteriormente. Ejemplo: “my-terraform-remote-state-01“;

dynamodb_table: informe el nombre de la tabla creada en DynamoDB. Ejemplo: “my-terraform-state-lock-dynamo“;

region: informe el nombre de la región AWS utilizada para crear el cluster, debe ser la misma en la cual fue creada la infraestructura de red. Ejemplo: “us-east-1“;

profile: informe el nombre del perfil AWS con las credenciales de acceso a API configuradas en el archivo ~/.aws/credentials. Debe ser el mismo utilizado para crear la infraestructura de red. Ejemplo: “default“.

Edite el archivo open-tools/terraform/eks/mycluster-eks/testing.tfvars. Con base en las informaciones utilizadas en la sección anterior, modifique los siguientes parámetros:

profile: informe el nombre del perfil AWS con las credenciales de acceso a API configuradas en el archivo ~/.aws/credentials. Debe ser el mismo utilizado para crear la infraestructura de red. Ejemplo: “default“.

region: informe el nombre de la región AWS utilizada para crear el cluster, debe ser la misma en la cual fue creada la infraestructura de red. Ejemplo: “us-east-1“;

address_allowed: la dirección IP pública y máscara de red que puede acceder a la red en la cual será creado el cluster. Ejemplo: “201.82.34.213/32”.

subnets: debe contener la lista con los IDs de la subnet_private1 y subnet_public_1, mostrados al final de la sección anterior. Ejemplo: ["subnet-06dd40e8124e67325", "subnet-098580d73a131193c"];

vpc_id: debe contener el ID de la vpc1 mostrada al final de la sección anterior. Ejemplo: “vpc-068004d30dd97a13b”;

cluster_name: contiene el nombre del cluster. El nombre informado aquí debe ser el mismo al final de las tags “k8s.io/cluster-autoscaler/mycluster-eks-testing” y “kubernetes.io/cluster/mycluster-eks-testing”, de lo contrario no será posible habilitar el autoscaling del cluster. Ejemplo: “mycluster-eks-testing”;

cluster_version: contiene la versión del EKS a ser utilizada en el cluster. Ejemplo: “1.17”;

override_instance_types: lista con los tipos de instancia EC2 a ser utilizadas en el cluster. Ejemplo: [“t3.micro”, “t3a.micro”];

on_demand_percentage_above_base_capacity: porcentual de instancias on demand a ser utilizadas en el cluster. El porcentual restante será de instancias spot (más baratas, sin embargo, efímeras). Ejemplo: 50;

asg_min_size: cantidad mínima de instancias en el cluster. Ejemplo: 2;

asg_max_size: cantidad máxima de instancias en el cluster. Ejemplo: 20;

asg_desired_capacity: cantidad desea de instancias en el cluster. Ejemplo: 2;

root_volume_size: tamaño en GB del disco a ser utilizado en cada instancia. Ejemplo: 20;

aws_key_name: nombre de la clave pública registrada en la sección anterior a ser utilizada por las instancias EC2 del cluster. Ejemplo: “aws-testing”;

worker_additional_security_group_ids: lista conteniendo el ID del security group creado en la sección anterior que será asociado al cluster. Ejemplo: ["sg-0bc21eaa5b3a26146"];

Obtenga el ID de su cuenta en AWS con el siguiente comando:

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

Donde:

PROFILE_NAME_AWS: es el nombre del perfil AWS definido en la configuración del archivo ~/.aws/credentials

Edite nuevamente el archivo open-tools/terraform/eks/mycluster-eks/testing.tfvars.

Y modifique todas las ocurrencias del ID 255686512659 por el ID de su cuenta. Modifique también la ocurrencia de la role adsoft por el nombre de la role registrada en su cuenta (si la hubiere) y modifique la ocurrencia del usuario aeciopires por su nombre de usuario en AWS. Esto es muy importante porque los usuarios y roles informados en los parámetros map_roles y map_users serán los únicos admins del cluster EKS.

Finalmente, cree el cluster EKS con los siguientes comandos:

cd ~/open-tools/terraform/eks/mycluster-eks

terraform init

terraform validate

terraform workspace new testing

terraform workspace list

terraform workspace select testing

terraform plan -var-file testing.tfvars

terraform apply -var-file testing.tfvars

Obs: La creación del cluster puede demorar 15 minutos o más.

Visualice las informaciones del cluster creado con los siguientes comandos:

terraform output

terraform show


Accediendo al cluster EKS

Ejecute el siguiente comando para tener acceso al cluster.

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

Donde:

REGION_NAME: es el nombre de la región en la cual el cluster fue creado.

CLUSTER_NAME: es el nombre del cluster creado.

PROFILE_NAME_AWS: es el nombre del perfil AWS definido en la configuración del archivo ~/.aws/credentials.

Ejemplo:

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

Para probar el acceso, visualice el status de los pods con el siguiente comando.

kubectl get pods -all-namespaces

 

Troubleshooting en EKS

Las informaciones sobre cómo hacer troubleshooting en EKS están disponibles en los enlaces a continuación:

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-apiserver-unauthorized-error

https://aws.amazon.com/premiumsupport/knowledge-center, sección Amazon Elastic Container Service for Kubernetes (Amazon EKS)

 

Visualizando el Precio

Las informaciones sobre el precio del uso de EKS, depende de la región de AWS en la cual el cluster está siendo creado, del tipo de instancia EC2 que está siendo utilizado en los nodes workers, si está o no utilizando instancias spot, on-demand, si está utilizando instancias reservadas, el tamaño y tipo del disco utilizado en cada nodes worker, si está siendo o no utilizando una VPC y NAT Gateway compartidos con otros servicios, del data transfer entre las redes externas involucradas, y además si está o no utilizando algún Load Balancer de AWS para permitir el acceso externo a las aplicaciones, el precio del Load Balancer también varía de acuerdo con el tipo, pudiendo ser: classic (ELB), application (ALB) o network (NLB). Además de esto AWS cobra una tasa de US$ 0.10 por hora para cada cluster EKS.

Obtenga más informaciones sobre el precio del servicio AWS-EKS en los enlaces a continuación:

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

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

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

Para ayudar a obtener una estimativa de precio, AWS suministra una calculadora de precios: https://calculator.aws.

Vea un ejemplo del costo mensual y anual de la infraestructura usada en este tutorial en la región Virginia (us-east-1):

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

 

Documentación

La documentación completa de los recursos utilizados en este tutorial está disponible en los enlaces a continuación. Utilice estas informaciones para profundizar el aprendizaje en el día a día.

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/userguide

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

 

Retirando el cluster EKS

Ejecute los siguientes comandos para retirar el cluster EKS:

cd ~/open-tools/terraform/eks/mycluster-eks

terraform workspace select testing

terraform destroy -var-file testing.tfvars

La remoción del cluster puede demorar 5 minutos o más.

Retirando la VPC y los buckets S3

Ejecute los siguientes comandos para retirar la infraestructura de red creada:

cd ~/open-tools/terraform/eks/networking-eks

terraform workspace select testing

terraform destroy -var-file testing.tfvars

La remoción de la infraestructura de red puede demorar 5 minutos o más.

Si al final de la remoción de los recursos, usted visualiza el siguiente error, acceda a la consola web de AWS y, enseguida, acceda a la URL: https://s3.comsole.aws.amazon.com/s3/. Localice el nombre del bucket y marque el checkbox al lado izquierdo del nombre. Enseguida, haga clic en el botón empty. Siga las instrucciones para vaciar el bucket.

Error: error deleting S3 Bucket …

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

Después de esto, edite el archivo open-tools/terraform/eks/networkin-eks/bucket.tf y modifique los siguientes parámetros:

Antes:

  versionado {

 enabled = true

   }

   ciclo de vida {

   prevent_destroy = true

  }

Después:

 force_destroy = true

  versionado {

 enabled = false

  }

  ciclo de vida {

  prevent_destroy = false

  }

Nuevamente ejecute los siguientes comandos para retirar el bucket:

terraform destroy -var-file testing.tfvars

Esto es necesario porque el bucket almacena el terraform state y en una situación normal en el ambiente de producción no es esperado que el bucket sea retirado para evitar perder el rastreo de los cambios en el ambiente usando Terraform.

Consideraciones Finales

En este tutorial aprendimos a crear de cero un cluster kubernetes utilizando Terraform para gestionar toda la infraestructura de red y el servicio AWS-EKS.

En los próximos tutoriales presentaremos el uso de otras tecnologías involucrando el EKS para realizar el monitoreo de métricas, deploy y observabilidad de aplicaciones.

Referencias


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/knowledge-center  


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


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


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


https://calculator.aws


¡Gracias por leer!