Configurando Ingress Controller no AWS EKS (Elastic Kubernetes Service)

Quando trabalhamos com Kubernetes gerenciados por grandes clouds como a AWS, e precisamos expor diversas aplicações corremos o risco de gerar um custo alto, se não utilizarmos a ferramenta da melhor forma.

Imagine você ter alguns microsserviços em um namespace de um cluster de EKS (Elastic Kubernetes Service) e para cada serviço que você está expondo ter que criar um Load Balancer da AWS para conseguir acessar esse serviço externamente. Esse tipo de solução acaba ficando caro, já que ter vários Load balancers eleva muito o custo para manter sua aplicação.

A solução é simples, criar um Load balancer que envia as requisições para dentro do cluster e o direcionamento para o serviço de destino é feito pelo Ingress Controller.

Essas é a solução que vamos abordar a seguir, nesse tipo de solução cada namespace dentro do nosso cluster de Kubernetes vai ter um Load Balancer da AWS responsável, esse tipo de solução é perfeita para quando você possui um cluster de EKS e equipes diferentes executando aplicações diferentes dentro do mesmo cluster.

Para esse tutorial, vamos partir do princípio que você já possui o cluster de EKS criado, iremos abordar somente a configuração do Ingress.

Requisitos para configurar Ingress Controller

  • Um cluster de EKS (Elastic Kubernetes Service) “Serviço de Kubernetes gerenciado pela AWS”.
  • eksctl (CLI): Ferramenta de linha de comando usada para criar e gerenciar cluster de Kubernetes da AWS
  • awscli: Ferramenta de linha de comando para criar e gerenciar recursos na AWS Cloud
  • awscli devidamente configurado com usuário ou uma role que tenha acesso ao cluster e acesso ao console.

Passo 1: Criar um provedor de OIDC

Como primeiro passo precisamos criar um provedor OIDC para o nosso cluster, podemos fazer isso através do terminal com o comandos abaixo:

cluster_name=app-prod
oidc_id=$(aws eks describe-cluster --profile p --region us-east-2 --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
Terminal
aws iam list-open-id-connect-providers --profile p | grep $oidc_id
Terminal

Caso nenhum dos comandos acima retorne algum resultado utilize esse comando:

eksctl utils associate-iam-oidc-provider --profile p --region us-east-2 --cluster $cluster_name --approve
Terminal

Lembre-se de ajustar o parâmetro de region para a região do seu cluster.

Passo 2: Instalação do eksctl

Como demonstrado nos requisitos precisamos do eksctl para gerenciar o nosso cluster, sua instalação é bem simples, basta executarmos os comandos abaixo:

# for ARM systems, set ARCH to: `arm64`, `armv6` or `armv7`
ARCH=amd64
PLATFORM=$(uname -s)_$ARCH

curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz

sudo mv /tmp/eksctl /usr/local/bin
Terminal

Passo 3: Tags obrigatórias

Vamos precisar inserir tags nas subnets que o nosso cluster utiliza, adicione a tag em todas as subnets:

kubernetes.io/cluster/my-cluster = shared
Terminal

E aqui cabe uma decisão se você quer que o Load Balancer que aponta para o Ingress do seu cluster fique público vamos precisar adicionar a tag abaixo em todas as subnets públicas:

kubernetes.io/role/elb = 1
Terminal

Caso a proposta é que o Load balancer só seja acessado de dentro da nossa VPN, de modo privado, vamos adicionar a tag abaixo em todas as subnets privadas.

kubernetes.io/role/internal-elb = 1
Terminal

Passo 4: AWS LoadBalancer Controller

Para prosseguirmos vamos fazer a instalação do AWS LoadBalancer Controller, essa ferramenta é um controlador do Kubernetes que integra com os serviços de balanceamento de cargas da AWS, ele quem vai permitir a integração de serviços como ELB (Elastic Load Balancer), NLB (Network Load Balancer) e ALB (Application Load Balancer) ao nosso cluster.

Baixe a política com as permissões necessárias:

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/install/iam_policy.json
Terminal

Vamos criar a política através do AWS IAM

aws iam create-policy --profile p --region us-east-2 \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json
Terminal

E agora vamos criar um Service Account para o AWS LoadBalancer Controller, executando o comando abaixo:

eksctl create iamserviceaccount --profile p --region us-east-2 \
  --cluster=app-prod \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::XXXXXXXXXXX:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve
Terminal

Vamos precisar instalar também o CertManager, essa parte é simples basta executar o comando:

kubectl apply \
    --validate=false \
    -f https://github.com/jetstack/cert-manager/releases/download/v1.12.3/cert-manager.yaml
Terminal

Agora sim vamos baixar o instalador do AWS LoadBalancer Controller, podemos usar o comando curl para fazer o download:

kubectl apply \
    --validate=false \
    -f https://github.com/jetstack/cert-manager/releases/download/v1.12.3/cert-manager.yaml
Terminal

No manifesto YAML que baixamos precisamos comentar o trecho descrito abaixo, para que o nosso Service Account que já foi configurado não seja substituído

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/name: aws-load-balancer-controller
  name: aws-load-balancer-controller
  namespace: kube-system
---
v2_5_4_full.yaml

Para facilitar construímos um comando de terminal que remove esse trecho específico, então basta executar o comando abaixo:

sed -i.bak -e '596,604d' ./v2_5_4_full.yaml
Terminal

Precisamos também substituir o nome do du cluster do manifesto para o nome do nosso cluster, você pode fazer isso editando o próprio arquivo manifesto e substituindo “your-cluster-name” da linha 863, ou executando o comando abaixo, substituindo “my-cluster” pelo nome do seu cluster.

sed -i.bak -e 's|your-cluster-name|my-cluster|' ./v2_5_4_full.yaml
Terminal

Depois de ter feitos essas alterações vamos aplicar o manifesto:

kubectl apply -f v2_5_4_full.yaml
Terminal

Passo 5: IngressClass  e IngressClassParams

Vamos precisar de mais dois recursos no nosso cluster, o IngressClass e o IngressClassParams ambos irão nos ajudar a padronizar a forma de definir classes para os nossos recursos Ingress, para fazer o download de ambos podemos usar o curl:

curl -Lo v2_5_4_ingclass.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.5.4/v2_5_4_ingclass.yaml
Terminal

E agora só aplicá-los

kubectl apply -f v2_5_4_ingclass.yaml
Terminal

Passo 6: Instalação do Kubectx e Kubens (Opcional)

A instalação dessas duas ferramentas é opcional, mas elas ajudam para quem trabalha com múltiplos namespaces e múltiplos clusters.

  • Kubectx: Ferrramenta para facilitar a gestão de múltiplos contextos dentro do nosso cluster.
  • Kubens: Ferramenta que facilita a troca entre namespaces dentro do nosso cluster.

Para instalar ambas as ferramentas podemos utilizar o comando abaixo:

#!/bin/bash
git clone https://github.com/ahmetb/kubectx /opt/kubectx
ln -s /opt/kubectx/kubens /usr/local/bin/kubens
Terminal

Pronto nosso Ingress está configurado, agora toda vez que você criar um recurso de Service do tipo NodePort ele será apontado para um AWS Load Balancer, expondo o nosso serviço interno do Kubernetes para o nosso balanceador de carga da AWS.

Lembrando que sempre que for utilizado um recurso dentro de um namespace ele utilizará o mesmo balanceador de carga, caso você crie recursos em mais namespaces serão necessários mais balanceadores, no caso um por namespace.

Links uteis

Felipe Lima Silva
Felipe Lima Silva

Especialista DevOps Engineer com ampla experiência em automações, infraestrutura, cloud, segurança e SDLC

Artigos: 1