EKS, EKSCTL e AZs
Tags: aws, eks, kubernetes, eksctl
Published: 2022-07-01 04:16:00

Você vai criar um cluster EKS para estudar. Você sabe que o processo de criação demora por volta de uns 15 min, então executa o comando e vai fazer um café.

Quando você volta, meia hora depois (foi mal, me atrasei olhando o Instagram), você é recebido com a seguinte mensagem:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5gshtr8s0k27n9y9ptf.png)


Mas o que aconteceu?

## Entendendo o problema

A AWS é um provedor bem grande, mas algumas regiões são extremamente disputadas. **us-east-1** é a principal Region da AWS (lembra o que acontece quando ela "cai"?) e muita gente usa; por isso, nem todas as suas **Availability Zones** estão "abertas".

A mensagem de erro está bem clara ali:

> Cannot create cluster 'devsres-lab' because us-east-1e, the targeted availability zone, does not currently have sufficient capacity to support the cluster. Retry and choose from these availability zones: us-east-1a, us-east-1b, us-east-1c, us-east-1d, us-east-1f 

É parecido com [este erro aqui](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/troubleshooting-launch.html#troubleshooting-launch-capacity) que pode acontecer ao tentar subir uma máquina EC2 em certas AZs saturadas. Esse erro acima acontecia bastante aqui em São Paulo com **sa-east-1b** - ela passou "fechada" por um tempo!

## Corrige esse programa aí!

Embora não seja desenvolvido pela própria AWS, **eksctl** é o programa padrão (inclusive listado na documentação oficial) para a criação de clusters EKS na linha de comando.

Por que eles não corrigem esse problema de maneira definitiva então, escolhendo as AZs "livres" em vez de perder meu tempo?

É porque **não tem solução**.

Uma coisa é ter capacidade para criar VMs, outra coisa é capacidade para criar clusters EKS. 

No mesmo dia em que fui contemplado com o erro da imagem acima, eu consegui criar máquinas virtuais do mesmo tamanho (ou maiores!) em **us-east-1e**, a AZ "cheia":

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bsxngeae318fth682otg.png)
 
Existem técnicas para saber se você consegue criar uma VM em uma AZ - a melhor maneira é verificar se há oferta de reserved-instances:

* Há capacidade para **t3.medium**? (como eu sei que sim, serve para validar o comando!)
```
# Ps: código copy/pastable!
$ export TYPE=t3.medium
$ aws ec2 describe-reserved-instances-offerings   \
  --filters 'Name=scope,Values=Availability Zone' \
  --no-include-marketplace --instance-type $TYPE  |
  jq -r '.ReservedInstancesOfferings[].AvailabilityZone' |
  sort | uniq
us-east-1a
us-east-1b
us-east-1c
us-east-1d
us-east-1e
us-east-1f
```

Todas as seis AZs estão aí, confirmando o que já sabemos.

* Há capacidade de **m5.large**?
```
$ export TYPE=m5.large
$ aws ec2 describe-reserved-instances-offerings   \
  --filters 'Name=scope,Values=Availability Zone' \
  --no-include-marketplace --instance-type $TYPE  |
  jq -r '.ReservedInstancesOfferings[].AvailabilityZone' |
  sort | uniq
us-east-1a
us-east-1b
us-east-1c
us-east-1d
us-east-1f
```

Ops, aparentemente **us-east-1e** está fora desse tipo aí!

Mas não há uma maneira **conveniente** de saber se a AZ suporta a criação de clusters EKS ou não. Ou seja, não tem como implementar isso aí no **eksctl** porque a própria AWS não disponibiliza uma API para consultarmos essa informação.

Você literalmente tem que quebrar a cara, levar o erro e "rolar os dados de novo", torcendo para o que o eksctl escolha melhor na próxima vez.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1ebyayk9ic5urujsrqz.png)

...só que não, né! 

## Especificando as AZs

Uma vez que você já sabe quais as AZs problemáticas, você pode especificar as AZs "boas" diretamente para o eksctl:

* Por meio de comandos:
```
$ export CLUSTER=devsres-lab 
$ eksctl create cluster  
--name "$CLUSTER"             \
--vpc-nat-mode Disable        \
--zones us-east-1a,us-east-1b \
--nodegroup-name ng1          \
--instance-types t3.medium    \
--nodes-min 0                 \
--nodes-max 5                 \
--nodes 2
```

* Por meio do arquivo de cluster:
```
$ cat 
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: devsres-lab
  region: us-east-1

# Avaiability zones pode ser:

# Um top level object
availabilityZones:
- us-east-1a
- us-east-1d

# Um atributo do NodeGroup
nodeGroups:
  - name: regular
    instanceType: t3.medium
    desiredCapacity: 2
    volumeSize: 80
    availabilityZones:
    - us-east-1a
    - us-east-1d
...
```

Mas **atenção**: o que resolve o problema da criação do cluster é  especificar a diretiva como **top level object**! Especificar onde o eksctl pode criar NodeGroups ainda deixa ele escolher AZs livremente!

## Uma curiosidade

Tradicionalmente, o **eksctl** cria VPCs em **três** Availability Zones como seu comportamento padrão:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhomtv1tg9kq4b17kf8c.png)

Isso é descrito na documentação [aqui] (https://eksctl.io/usage/vpc-networking/#networking).

Mas de tanto esse erro aborrecer as pessoas, já que não é possível resolver o problema de maneira definitiva, eles optaram por mudar o comportamento padrão do eksctl para **us-east-1** apenas, usando duas AZs em vez de três!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jll43ngf5dduuk5aydy.png)
 
Tem literalmente um **if** no código que testa isso!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e282l3s8ld03say6jucu.png)
 


---

Por hoje é só! 

Qualquer coisa, nos vemos [no Instagram](https://www.instagram.com/marcelo_devsres/) ou [no Twitch](https://www.twitch.tv/marcelo_devsres)!