Os scripts do **gitlab-ci** escritos pelo desenvolvedor precisam de uma máquina para interpretá-los e executá-los, e pra isso existem os **Runners**.
Os **Runners** são aplicações que interpretam e executam as pipelines do **gitlab-ci**.<br>
Eles são instalados em uma máquina externa a do **GitLab**, e configurados na página do projeto para se encarregarem de executar os scripts de CI/CD do mesmo.
Sempre que a execução do CI/CD do projeto em questão for engatilhada (seja por conta de uma mudança nova, ou de uma abertura de PR), o **GitLab** irá buscar por qualquer um dos **Runners** que estão configurados no projeto e disponíveis, e irá utilizá-lo para interpretar o arquivo **gitlab-ci.yml** e executá-lo.
Um Runner possui uma série de atributos, que são definidos em sua configuração, sendo os principais deles:
### Descrição
Uma descrição simples do Runner, indicando informações gerais como qual a máquina em que ele está rodando, qual o sistema operacional, e qual a sua finalidade, para fins de documentação.
### Tags
Um runner pode ter uma série de tags, que são identificadores extras do runner, e podem ser referenciados no **gitlab-ci.yml** para especificar quais runners devem rodar certos jobs.
Para exemplificar, digamos que o desenvolvedor tenha um Runner instalado em uma máquina linux, e outro instalado em uma máquina windows.<br>
Ele poderia indetificar estes runners com as task `linux` e `windows`, respectivamente.<br>
E então, no **gitlab-ci.yml**, poderia especificar qual runner usar nos jobs desta forma:
```yml
test on linux:
tags:
-linux
stage:test
script:
-test application...
test on windows:
tags:
-windows
stage:test
script:
-test application...
```
O valor `tags` do job fará com que o **GitLab** busque um Runner que tenha aquela tag específica para lidar com aquele job.
Caso não tenha nenhum Runner disponível com a tag, o job falhará.
### Executor
Os executores são a parte principal dos Runners, eles definirão de que maneira as pipelines serão executadas.
Cada Runner possui apenas um executor, e o gitlab-ci possui uma série de [executores possíveis](https://docs.gitlab.com/runner/executors/), mas existem dois executores principais básicos:
#### Shell
O executor **shell** vai rodar os comandos dos jobs da pipeline na própria máquina aonde o Runner está instalado.
Este executor é preferido quando o Runner está instalado na mesma máquina aonde o servidor será lançado.
Digamos, por exemplo, que temos um job que sobe um servidor de testes.<br>
Poderíamos instalar um Runner na própria máquina deste servidor, e no **gitlab-ci.yml** colocar toda a lógica para subí-lo.
Como o executor **shell** roda os comandos na própria máquina, ao final da pipeline, o servidor estará rodando!
> :warning: **AVISO:** A grande maioria dos nossos Runners específicos do gitlab-ci são instalados nas máquinas de testes do laboratório, que ficam na SeTIC<br>
Por isso, visto que este executor fará comandos diretamente na máquina, este executor só poderá ser utilizado com a autorização e monitoramento do administrador do laboratório!
#### Docker
O executor **docker** vai rodar os comandos dos jobs da pipeline em um **contâiner docker**.
A imagem que o Runner utilizará deverá ser especificada no próprio arquivo **gitlab-ci.yml**, no valor `image`, <br>
este valor poderá ser colocado tanto na raiz do arquivo, para definir qual a imagem a ser utilizada para toda a pipeline, ou dentro de um job, para definir qual imagem aquele job específico deverá utilizar.<br>
Ex.:
```yml
image:python
stages:
-test
test on ruby image:
image:ruby
stage:test
script:
-test application...
```
O Runner do gitlab irá pegar o valor especificado, e buscá-lo no **docker-hub**.<br>
O [docker-hub](https://www.google.com/search?client=safari&rls=en&q=docker+hub&ie=UTF-8&oe=UTF-8) é um repositório para guardar imagens docker de todos os tipos, e é tido como o local padrão para persistência e busca de imagens públicas e privadas.
Este executor é o mais indicado na maioria dos casos, visto que da liberdade ao desenvolvedor de usar quaisquer tecnologias que preferir, mas ele tem um porém:<br>
Após a pipeline acabar, o contêiner docker será completamente apagado. Ou seja, qualquer ação que foi feita nele será removida completamente.
Isso faz com que esse executor seja dificilmente utilizado em scripts de deploy, ou em situações aonde a persistência dos comandos executados seja importante.