Concrete Logo
Hamburger button

Introdução às ferramentas DevOps para SMs e POs

  • Blog
  • 23 de Novembro de 2016

Não é todo mundo que trabalha com tecnologia que tem o domínio técnico necessário para entender o dia-a-dia do desenvolvedor. Pior ainda se a pessoa tiver que lidar com infraestrutura. Por isso, vamos abordar neste post os conceitos e exemplos de uso sobre a cultura DevOps e algumas ferramentas utilizadas para alcançar uma infraestrutura ágil.

O termo DevOps foi criado por Patrick Debois e descreve uma cultura cujo objetivo é melhorar a dinâmica na relação entre as áreas de infraestrutura e desenvolvimento para agregar valor ao negócio.

Existe um conflito entre essas áreas. Desenvolvimento se preocupa em aumentar o valor do negócio, trabalha com metodologias ágeis, são proativos, evolutivos e querem colocar suas aplicações em produção o mais rápido possível.
A Infra se preocupa em proteger o valor do negócio, trabalha no modelo tradicional de administração, executa operações manuais, é reativa e quer ter certeza que a aplicação está estável o suficiente para entrar em produção sem gerar incidentes. A Infra não conhece o Desenvolvimento e não sabe como mudar para satisfazê-lo, e o Desenvolvimento não conhece a Infra e não entende totalmente sobre o que ela pede. Tudo isso gera ruídos de comunicação e atrapalha o trabalho colaborativo entre as áreas. Foi buscando e discutindo soluções para essas necessidades que surgiu a cultura DevOps.

Nessa cultura existe um papel importante chamado especialista DevOps, que faz a ponte entre as áreas e possui conhecimento em desenvolvimento e infraestrutura ágil, ou seja, na capacidade de permitir alterações nos servidores de maneira rápida.

A implementação da cultura DevOps é um processo complexo e, se pensarmos em grandes empresas, também doloroso, caro e demorado. A resistência às mudanças e falta de entendimento do todo são os principais obstáculos na adoção da cultura DevOps. Dito isso, vamos agora falar sobre como instalar e configurar algumas das ferramentas mais populares utilizadas no Application Lifecycle Management (ALM) e infraestrutura ágil.

Todos os exemplos serão executados no CentOS 7 usando o VirtualBox.

Configurando o Laboratório

A configuração mínima recomendada é um computador com 4 GB de memória RAM e 50 GB de espaço livre em disco.

Instalando o VirtualBox

O VirtualBox é um aplicativo de virtualização que permite criar ambientes que simulam outro computador. Faça o download em https://www.virtualbox.org/wiki/Downloads e instale no seu computador.

  • – Abra o VirtualBox, clique em New e digite CentOS no campo Name.
  • – Em Type selecione Linux, clique em Version Red Hat (64 bit) e clique no botão Continue.
  • – Em Memory Size, configure para 2048 MB, avance para a próxima tela, selecione Create a virtual hard disk now e clique no botão Create.
  • – Selecione o tipo VDI, avance, deixe marcada a opção Dynamically Allocated e na próxima tela configure o tamanho do HD virtual para 30 GB.

Configurando o CentOS

Faça o download do CentOS-7-x86_64-LiveGNOME.iso. Abra o VirtualBox, selecione a máquina virtual CentOS e clique no botão Settings. Na janela que abrir, clique na aba Storage. Selecione onde está escrito Empty, clique no ícone de cd-rom ao lado de Optical Drive e depois em Choose Virtual Optical Disk File para selecionar a iso do CentoOS.

Siga a instalação padrão do CentOS. Caso tenha dúvidas, esse vídeo explica passo a passo como fazer essa instalação.

Terminada a instalação, execute os comandos a seguir um por um terminal.

Epel é um repositório criado pela comunidade do projeto Fedora, que contém softwares 100% livres. DKMS (Dynamic Kernel Module Support) é um programa que permite gerar módulos do kernel do Linux. GCC é um compilador da linguagem C, PIP é um gerenciador de pacotes para Python e OpenJDK é uma versão do Java Open Source. Esses pacotes são dependências necessárias das ferramentas que serão mostradas adiante.

Git

Criado em 2005 como alternativa para o versionamento do código fonte do kernel do Linux, começou a popularizar em 2008, depois do lançamento do Github, um serviço de web hosting com aspectos de redes sociais. O Github permite a criação de repositórios Git e permite que desenvolvedores possam copiar, contribuir e discutir sobre projetos de software. Em 2011 foi lançado o Gitlab, serviço similar ao Github mas que possui uma versão Open Source que permite ser instalada em servidores privados.

Apenas o Git já é suficiente para configurar um servidor de repositórios. Ferramentas como Gitlab facilitam bastante o trabalho de gerenciar repositórios, mas não são obrigatórias.

Vamos começar a brincadeira instalando o Git:

E uma configuração básica:

Então criamos um repositório chamado curriculum dentro da pasta Documents.

Em seguida entramos na pasta /tmp e fazemos um clone do repositório. O clone é onde de fato as alterações ocorrem, onde trabalhamos, e somente após concluirmos nosso trabalho enviamos as modificações (commit) para o repositório.

Vamos criar um arquivo resume.txt e adicioná-lo ao repositório. Um commit salva as alterações localmente e um push envia para o repositório, tornando a alteração disponível para outras pessoas.

Por padrão, a branch principal recebe o nome de master. Mas é possível criar com outro nome ou mesmo criar várias branches.

Acima criamos um novo branch chamado frontend_developer_position, que contém o arquivo resume.txt alterado. Depois de executar o push ficamos com duas branches (master e frontend_developer_position), cada uma contendo o mesmo arquivo resume.txt mas com conteúdo diferente.

Criamos um repositório local apenas para brincar. Na prática utilizamos alguma ferramenta como Gitlab ou Gitblit ou algum serviço na nuvem como Github ou Bitbucket para gerenciar melhor nossos repositórios e permitir acesso remoto para outras pessoas.

Configurando Gitlab

Para instalar, abra um terminal e digite:

Se tudo der certo o Firefox vai abrir a página do Gitlab que solicita a criação de uma senha. Crie uma senha e faça login utilizando o nome de usuário root.
Após a autenticação é possível importar ou criar repositórios e definir as permissões de acesso. Uma vez criado, será exibida a URL do repositório que vai ser clonado.

Para mais detalhes consulte a documentação em https://docs.gitlab.com/ce/

Git Workflows

Conforme o Git foi popularizando e sendo adotado por grandes empresas, cada organização passou a trabalhar de maneira diferente. Pensando nisso, foram criadas orientações com o propósito de organizar a forma de trabalho e mostrar as possibilidades de se trabalhar com o Git.
Separei alguns textos que explicam e comparam os diferentes workflows existentes.

Interfaces Gráficas para Git

Para quem trabalha com Git no dia-a-dia talvez seja mais produtivo utilizar comandos no terminal. Porém, há quem goste de utilizar interfaces gráficas e para isso existem várias disponíveis na web.

Saiba mais sobre Git

Automação de Testes

Automação de teste é o uso de software específico para controlar a execução do teste de software (o software sendo testado), a comparação dos resultados esperados com os resultados reais e outras funções de controle e relatório de teste. O objetivo dos testes é assegurar a qualidade do projeto, descobrindo problemas ou pontos de melhorias antes de pôr o software em produção.
Existem diversos tipos de testes e abordagens utilizadas. Vamos falar apenas de dois: testes de unidade e testes de interface.

Testes de Unidade

Uma unidade é a menor parte testável de um programa de computador. Dependendo da linguagem de programação, uma unidade é chamada de função, procedure ou método.
Vamos criar um exemplo em Python de um código que poderia ser parte de uma aplicação. Uma validação muito simples de email, apenas para esse exemplo.
Vamos utilizar o terminal para criar o arquivo mail.py. Atenção aos espaços antes da palavra return.

O código acima é uma função que recebe um email e retorna verdadeiro ou falso se houver um ‘@’. A maneira de testar manual seria executar o código e digitar um email qualquer. Mas para automatizar, escrevemos um código que faz esse teste.
Crie o arquivo mail_test.py:

Para rodar o teste, execute:

E o resultado deve ser parecido com isso:

Testes de Interface Gráfica

Verifica se a navegabilidade e se os objetivos da interface funcionam como especificados.
Esse tipo de teste costuma ser feito manualmente por equipes de testes ou Quality Assurance (QA). Quando automatizado, é comum utilizar ferramentas como o Selenium Webdriver que possui suporte à diversas linguagens de programação.

Precisamos primeiro fazer o download do driver para o Firefox e instalar o Selenium antes de escrever o teste.

O teste abaixo vai abrir uma janela do Firefox, acessar a página inicial do Google e verificar o atributo title do logotipo.

Para executar o teste:

Resultado:

Sonatype Nexus

Nexus é um gerenciador de repositório de artefatos. Em desenvolvimento, quase sempre a aplicação possui dependências de outros softwares ou componentes para efetuar algum trabalho. Por exemplo, se uma aplicação possui integração com o Facebook então ela depende de componentes fornecidos pelo próprio Facebook para permitir esse tipo de integração. Esses componentes são também chamados de artefatos ou bibliotecas, e ficam disponíveis na internet  de vários sites diferentes.

Nem sempre podemos confiar que o componente utilizado e a versão desse componente vai estar disponível em sites de terceiros com o passar do tempo. Por isso é importante manter um repositório privado dentro da empresa para garantir a disponibilidade desses componentes.

Mesmo as aplicações desenvolvidas dentro de uma empresa podem ser disponibilizadas no Nexus, assim elas são facilmente distribuídas para todos os interessados.

Inicialmente foi desenvolvido para armazenar dependências de projetos Java (arquivos .jar) mas hoje possui suporte a outros formatos como Docker, NPM, Bower, PyPI e Ruby Gems.

Vamos fazer o download, descompactar e executar o Nexus:

Abra a interface web do Nexus pelo browser:

No menu superior do lado direito existe um botão escrito Sign in. Clique nele e utilize como username admin e password admin123.
Depois de autenticado vá para a tela de gerenciamento de repositórios https://localhost:8081/#admin/repository/repositories. Clique no botão Create Repository e escolha um repositório do tipo raw (hosted). Informe o nome do repositório como my-app-example, selecione o Storage default e desmarque o checkbox de validação em Strict Content Type Validation.

Atualmente o Nexus 3 suporta os seguintes tipos de repositórios:

  • Proxy: é um repositório ligado a um repositório remoto, ou seja, se um artefato não existe localmente, a solicitação é encaminhada a um repositório remoto. O download do artefato é feito e ele é armazenado localmente. As próximas solicitações para o mesmo artefato serão atendidas localmente, funcionando de forma parecida com um serviço de cache, evitando consultar novamente o repositório remoto.
  • Hosted: o próprio Nexus armazena os artefatos e possui autoridade para modificar informações sobre eles.
  • Group: permite combinar outros repositórios como um único repositório. Com isso, os usuários podem acessar o repositório por uma única URL, e o administrador pode configurar outros repositórios em máquinas diferentes.

Vamos criar uma aplicação, gerar um artefato e armazenar no Nexus:

Com isso o artefato fica disponível para outros usuários em https://localhost:8081/#browse/browse/components:my-app-example.

Saiba mais sobre o Nexus 3 em https://www.sonatype.org/nexus/category/nexus-3/

Integração Contínua com Jenkins

Integração Contínua é uma prática de desenvolvimento de software na qual os membros de um time integram seu trabalho frequentemente. Neste post aqui você pode aprender um pouco mais sobre como funciona. Cada integração é verificada por um build automatizado para detectar erros o mais rápido possível. A atividade de build consiste basicamente em obter o código fonte da aplicação, executar testes automatizados e gerar um pacote no formato necessário para fazer o deploy.

O Jenkins é uma ferramenta poderosa para integração contínua. Surgiu como uma variante (fork) da ferramenta Hudson, após alguns desenvolvedores da empresa Sun Microsystem, detentora do sistema, se desentenderem com a Oracle, empresa que adquiriu a Sun em 2010.

Possui uma comunidade muito ativa, é bem extensível com plugins e seu uso vai além da integração contínua, sendo utilizado por muitos administradores de redes como ferramenta para agendamento de tarefas, por exemplo.

Faça o download e execute o Jenkins na porta 8888 para evitar conflitos com o GitLab:

Ao acessar o Jenkins pela primeira vez, será solicitada a senha de administrador gerada automaticamente por ele e armazenada dentro de um arquivo no servidor. Para visualizar essa senha:

Copie essa senha no Jenkins. Clique em Select plugins to install. Desmarque todos os plugins selecionados e selecione apenas o plugin Pipeline. Aguarde enquanto o Jenkins faz o download do plugin Pipeline Suite e suas dependências.
Após o download, pule a etapa de criar usuários e clique em Continue as admin.

Criando um Job

Jobs são tarefas executáveis, controladas e gerenciadas pelo Jenkins. Um build é o resultado da execução de um job.
Tipos de jobs:

  • Freestyle Project: o tipo clássico, simples e genérico que suporta diferentes tecnologias.
  • Pipeline: permite separar o processo de build em estágios e exibe o resultado visualmente em forma de pipeline. Utiliza a linguagem de programação Groovy.
  • Multibranch Pipeline: similar ao Pipeline, porém detecta qual branch no repositório de arquivos (Git) possui um arquivo chamado Jenkinsfile que contém o código Groovy.

Pipeline

Vamos criar um job do tipo Pipeline e demonstrar como seria um pipeline simples de integração contínua.
Clique em Create new jobs, insira o nome Hello, selecione o tipo Pipeline e clique em Ok. Em seguida você será redirecionado para a tela de configuração do job. Dependendo dos plugins instalados, as opções de configuração aumentam.
Na seção Pipeline, insira o código abaixo no campo de texto chamado Script e salve as alterações:

O script acima possui 3 estágios. O primeiro faz um clone do repositório criado anteriormente, o segundo cria um pacote .tar.gz com o conteúdo do repositório (o nome do pacote é composto pelo nome do job e o número do build) e o terceiro envia esse pacote para o Nexus dentro de um repositório criado por nós anteriormente.
Clique em Build Now para executar o build e ver o resultado.

Freestyle Project

Crie um novo job clicando em New Item, insira um nome e selecione o tipo Freestyle Project. Em seguida, na seção Build, clique no botão Add build step e selecione Execute shell. Adicione o script abaixo no campo de texto chamado Command:

A principal diferença entre os 2 tipos de job é que um Freestyle Project possui apenas 1 estágio.
Saiba mais sobre a terminologia do Jenkins em https://wiki.jenkins-ci.org/display/JENKINS/Terminology.

Docker Containers

Para entender melhor o que é Docker antes é preciso entender algumas coisas sobre o kernel (núcleo) do Linux.
A partir da versão 2.6 do kernel foram adicionadas três grandes funcionalidades: cgroups (control groups), Namespaces e seccomp-bpf (secure computing mode).
O cgroups limita o uso de recursos da máquina. Por exemplo, ele permite limitar um grupo de processos para utilizar somente 100 MB de memória.
Namespaces permite que grupos de processos sejam separados de modo que um grupo não afete os recursos de outro grupo.
Seccomp-bpf permite filtrar quais chamadas aos sistema (system calls) um processo pode executar. Por exemplo, negar acesso aos recursos de rede.
Resumindo, cgroups limita, Namespaces isola e Seccomp-bpf libera ou bloqueia acesso aos recursos de hardware (cpu, memória, disco…).

Para testar o uso do Namespaces, execute os comandos:

Repare que ao usar o comando ps aux não conseguimos visualizar outros processos. Isso comprova que executamos o bash de forma isolada dos outros processos da máquina.
Trabalhar com cgroups e Seccomp-bpf exige mais comandos, então não vamos abordar por aqui.

Mas o que são containers? Em algum momento alguém pensou: “Legal, vou construir uns scripts para utilizar esses recursos e vou poder rodar softwares isolados um do outro e com recursos limitados, de forma segura, simples, leve e rápida”. Algumas pessoas pensaram nisso também. Eles criaram uma coisa chamada “Docker containers” que utiliza essas features. E assim nasceu o Docker, uma camada de alto nível que fornece uma API (uma forma de integração com outros sistemas) para utilizar esses recursos do kernel. É claro que o Docker possui muito mais recursos hoje em dia, mas muito do que o Docker é capaz utiliza os recursos primitivos do kernel do Linux.

Container vs Imagem

Uma imagem Docker NÃO É uma imagem ISO, daquelas utilizadas para gravar em CD/DVD. No contexto do Docker, uma imagem é um sistema de arquivos que nunca muda e um container é uma execução da imagem. Confuso? Sim. É difícil explicar com palavras. Mas vamos demonstrar adiante.
Uma informação mais detalhada pode ser encontrada neste link aquiEste post do Wesley também é bem legal sobre o assunto, e eu já escrevi sobre isso aqui.

Instalando e utilizando o Docker

Abra um terminal e execute:

Vamos criar um container de um servidor web a partir da imagem nginx fornecido pelo repositório público de imagens do Docker chamado de Docker Hub.

O Nginx é um servidor web que roda na porta 80. A imagem nginx:alpine possui o servidor Nginx instalado e configurado, baseado em outra imagem que utiliza como base o Alpine Linux, distribuição enxuta específica para trabalhar com o Docker.
O comando acima cria um container e mapeia a porta local 8000 para a porta 80 do container. Com isso é possível acessar a URL https://localhost:8000 e ver o Nginx funcionando. Fácil assim, sem precisar instalar e configurar nenhum servidor no CentOS. É possível criar de maneira leve e rápida outros containers:

Com isso foram criados 5 containers rodando Nginx, acessíveis via https://localhost:8001, https://localhost:8002, https://localhost:8003, https://localhost:8004 e https://localhost:8005.

Não é possível alterar uma imagem, apenas um container. Um container pode ser criado e apagado a qualquer momento, não é capaz de persistir dados. A maneira de alterar um container e persistir essa alteração é somente criando outra imagem. Por exemplo, se desejar alterar a porta padrão do Nginx para 90, é necessário criar um container, entrar nele, alterar o arquivo de configuração do Nginx e criar uma nova imagem a partir desse container.

Entramos dentro do container. Agora podemos alterar o arquivo de configuração na linha 2 de listen 80 para listen 90.

Para a mudança surtir efeito, precisamos criar uma nova imagem e depois executar um outro container usando nossa nova imagem.

Abra o Firefox em https://localhost:9000 para confirmar que está funcionando.

Dockerfile

Algumas vezes a configuração de uma imagem pode ser complexa. Instalar dependências, criar uma estrutura de diretórios, modificar arquivos de configuração… e nesse caso é uma boa prática criar um arquivo que especifica como fazer esse trabalho. É isso que o Dockerfile faz.

Com esse Dockerfile podemos criar uma imagem com Nginx e personalizar a página inicial.
Para criar uma imagem utilizando esse arquivo:

Conclusão

O ecossistema DevOps é muito amplo e abrangente e não cabe em apenas um texto. A intenção aqui é passar um conhecimento básico para pessoas não técnicas que tomam decisões técnicas em ambientes caóticos corporativos. Se ficou alguma dúvida ou tem algo a dizer, aproveite os campos abaixo! Até a próxima.

Trabalha com DevOps e quer fazer parte de um time incrível? Clique aqui.