Jenkins :: Escalando Jenkins Slaves do AWS Fargate / ECS

Share:


This is a PoC. 

O Objetivo desse post é fazer a sintese de uma PoC que eu desenvolvi por curiosidade tentando resolver um problema que eu tive há um tempo, e que por falta de tempo precisou ser desenvolvido de uma outra forma. Simplesmente fiquei com essa ideia na cabeça e como não consegui aplicá-la dentro de um ambiente empresarial, decidi fazer por mim mesmo como objetivo de estudo. Eu amo fazer isso. É basicamente uma forma de escalar Jenkins Slaves diretamente como Tasks no Amazon ECS utilizando ou não o Fargate. Esse método de build é uma solução simples pra escalar ambientes de Continuous Integration de vários projetos em paralelo de uma forma bem barata.



Arquitetura



A arquitetura desse projeto segue basicamente a mesma linha de raciocínio de qualquer cluster de Jenkins padrão, porém ao invés dos slaves serem provisionados manualmente, ou por meio de um Auto Scale Group, Gerenciador de Configurações, ele será provisionado como uma Task em um cluster de ECS sob demanda.

O que será necessário? 

  • Um Cluster de ECS já montado. Já embarquei um exemplo pra você fazer um setup de um cluster de teste usando Terraform
  • Um Jenkins Master rodando em uma EC2 separada. 
  • Tanto sua instância de Jenkins Master quanto a suas tasks necessitam ter acesso simultâneos nas portas 8080 e 50000 um do outro. 
  • O plugin Amazon EC2 Container Service Plugin instalado no seu Jenkins
  • Uma Access Key ou Secret Key com algumas permissões necessárias pro Jenkins gerenciar tasks no ECS. É recomendado que você gerencie isso por roles. Mas como esse post é apenas um exemplo prático, iremos utilizar as chaves de acesso a AWS na configuração do Jenkins. 
  • As permissões básicas pro Jenkins gerenciar tasks no ECS é a seguinte:


Considerações

  • Esse exemplo também já tem um quickstart básico de um Jenkins já com todos os plugins instalados. 
  • Você pode utilizar o seu Jenkins master com um Load Balancer na frante pra conseguir autorizar o acesso externo ao mesmo. Caso esteja com uma instância fixa, será necessário utilizar o IP interno do Jenkins master em algumas operações. 
  • Fazendo uso de um Load Balancer a solução fica mais escalável, porém neste exemplo iremos utilizar apenas o IP interno da instância. 


* Opcional: Configurando o Cluster do Exemplo 

Esse PoC, como já comentado, possui o bootstrap de um cluster de teste pra exemplificar. Você pode utilizá-lo também pra esse lab. Aplicando esse projeto, algumas informações úteis pra configuração futura do Jenkins será exibida. Guarde essas infos!

git clone https://github.com/msfidelis/jenkins-ecs-slaves.git
cd jenkins-ecs-slaves/
terraform init 
terraform apply





* Opcional: Setup rápido do Jenkins. 

Agora suba uma EC2 qualquer dentro da VPC criada no projeto, e anexe o security group gerado nessa também. Deixei essa parte pra você fazer manualmente.

Instalando o Docker

curl -sSL https://get.docker.io | sh
apt install docker-compose -y

Clone o projeto novamente

git clone https://github.com/msfidelis/jenkins-ecs-slaves.git
cd jenkins-ecs-slaves/
docker-compose up


Agora acesse: 

https://ip.do.servidor:8080/

Nesse projeto tem uma Dockerfile que já está preparada pra configurar o Jenkins pro lab e instalar alguns dos plugins necessários. Note que a autenticação está desabilitada. Não use em produção, é apenas pra um entendimento rápido.



Configurando o Plugin do ECS no Jenkins

Nossa parte de configurações do próprio ECS já terminou. Agora vamos configurar a autorização e configuração do Jenkins master para o provisionamento dos slaves no Amazon ECS. 


Configurando um Cloud Service

Vamos configurar uma source de Cloud utilizando o EC2 Container Service Plugin.

  • Vamos em Manage Jenkins > Configure System > Cloud > Add new cloud
  • Se o plugin estiver instalado certinho, selecione a opção Amazon EC2 Container Service Cloud
  • Coloque um nome para seu Cloud Source, no exemplo: jenkins-build-ecs




Configurando as credenciais de acesso


  • Na opção Amazon ECS Credentials, clique em Add caso estiver utilizando o método de autenticação por Access Keys ou Secret Keys.
  • Selecione AWS Credentials, informe um id de identificação e coloque suas keys.




* Agora voltando a configuração do Cloud, selecione as credenciais. Selecione a região na qual se encontra seu cluster, e em seguida selecione o cluster em questão. Se você utilizou o bootstrap de exemplo, o nome do cluster deve estar configurado como jenkins-ecs-build.



Configurando o ECS agent templates

Agora vamos fazer a configuração dos templates dos Slaves que irão extender as capacidades de build do nosso Jenkins.

Na opção ECS agent templates, clique em Add.

Configurações Básicas


Aqui é o coração da configuração, e também o primeiro passo. Caso você tenha aplicado o cluster de exemplo, essas informações foram exibidas no final da operação de configuração do Terraform.

Caso você queira configurar suas tasks para rodarem no Fargate, será necessário respeitar alguns padrões de CPU e Memória para lançar suas tasks. Você pode encontrar tudo neste link.



Vamos lá, um por um:

  • Label: jenkins-ecs-build
  • Template Name: jenkins-ecs-build
  • Docker Image: jenkins/jnlp-slave
  • Launch type: EC2 ou Fargate - No teste faremos Fargate
  • Network mode: awsvpc
  • Soft Memory Reservation: 512
  • CPU units: 256
  • Subnets: subnet-xxxxxxxx, subnet-yyyyyyyyy
  • Security Groups: sg-xxxxxxxxxxxx
  • Assign Public Ip: checked



Configurações Adicionais

* Ainda na edição do Templates, clique em Advanced.




Privileged Container & User

* Builds no Fargate não suportam --privileged. No caso o checkbox privileged.

* Você pode especificar o usuário no qual o container do agente do Jenkins irá rodar. Por padrão o container padrão de slave, no caso o jenkins/jnlp-slave, utiliza o usuário jenkins. Você pode setar um root ai caso precise instalar / configurar alguma coisa.




Logging Driver

Por motivos de debug, você pode enviar o output das tasks pra algum outro centralizador de logs.
Por padrão o AWS Fargate só suporta o awslogs, que envia os logs para o Cloudwatch
Para configurar o awslogs no Jenkins, você vai precisar adicionar alguns parâmetros (Add).

Exemplo de configuração:

  • awslogs-group:  jenkins-ecs-build-logs
  • awslogs-region: us-east-1
  • awslogs-stream-prefix: jenkins-ecs-build-agent


Importante!!!

Sérá necessário adicionar uma a variável de ambiente JENKINS_URL no template de agente. Você deverá se atentar a dois casos: 

* Se você estiver utilizando um ALB ou ELB antes das suas instâncias de Jenkins, você adiciona a URL do balance aqui. 
* Caso estiver utilizando uma instância apenas diretamente, será necessário adicionar o IP Interno da instância aqui 





Criando um build de teste

Esse passo será necessário só pra validar se está tudo "Ok"

  • Crie um Job novo do Jenkins estilo "Freestyle"




  • Dentro das configurações gerais, selecione Restrict where this project can be run, e coloque a Label do template que criamos no passo anterior, no caso jenkins-ecs-build.


  • Dessa forma iremos dizer que esse build deve ser rodado no ECS com as configurações prévias que acabamos de realizar.




  • Salve e rode!

A cada teste iniciado dentro do Jenkins, uma nova task com um container do agente do Jenkins Slave será criado, se conectará com o master, irá realizar as etapas de build e depois morrerá. Esse é o ciclo de vida esperado dessa PoC. 1 teste, 1 container.






Criando um projeto de Pipeline (Jenkinsfile)

Agora vamos trazer a PoC pra um universo mais próximo da realidade. Vamos criar nossa Pipeline as a Code subindo um Jenkinsfile e especificando os builds que devem ser iniciados como slaves no Fargate. Pro exemplo, iremos utilizar a seguinte Jenkinsfile que builda um projeto café com leite, roda uma série de testes unitários e fim.


  • Crie um projeto Estilo Pipeline



  • Adicione a seguinte Jenkinsfile ao projeto






  • Vamos rodar os testes!




  • Testando builds em paralelo cacetando um monte de builds no botão






Espero ter ajudado!

Foi legal transformar meu roadmap de roteiro de estudos em coisas válidas e aplicáveis no dia a dia. Espero que você consigam adaptar esse case pra N cenários. Se fizeram alguma coisa legal, mandem pra mim no Twitter, Email ou qualquer que seja. Eu vou gostar bastante de ver!

Segue o link do projeto de exemplo no Github


:)


Nenhum comentário