DevOps na prática entrega de software confiável e automatizada
Danilo SatoDevOps na Prática
Prefácio
Jez Humble
Pouco depois que me formei na universidade em 1999, eu fui contratado por uma start-up em Londres. Meu chefe, Jonny LeRoy, ensinou-me a prática de implantação contínua: quando terminávamos uma nova funcionalidade, fazíamos alguns testes manuais rápidos na nossa estação de trabalho e, em seguida, copiávamos os scripts ASP relevantes por FTP para o servidor de produção – uma prática que eu não recomendaria hoje, mas que teve a vantagem de nos permitir mostrar novas ideias para nossos usuários muito rapidamente.
Em 2004, quando entrei na ThoughtWorks, meu trabalho era ajudar empresas a entregar software e eu fiquei chocado ao descobrir que prazos de meses ou mesmo anos eram comuns. Felizmente, tive a sorte de trabalhar com várias pessoas inteligentes em nossa indústria que estavam explorando formas de melhorar estes resultados, ao mesmo tempo aumentando a qualidade e melhorando a nossa capacidade de servir nossos usuários. As práticas que desenvolvemos também tornaram a vida melhor para as pessoas com quem estávamos trabalhando (por exemplo, não precisávamos mais fazer deploys fora do horário comercial) – uma indicação importante de que você está fazendo algo certo. Em 2010, Dave Farley e eu publicamos Entrega Contínua, onde descrevemos os princípios e práticas que tornam possível entregar pequenas alterações incrementais, de forma rápida, barata e com baixo risco.
No entanto, o nosso livro omite os detalhes práticos do que você realmente precisa para começar a criar uma pipeline de entrega, como pôr em prática sistemas de monitoramento e infraestrutura como código, além dos outros passos práticos importantes necessários para implementar entrega contínua. Por isso estou muito contente que o Danilo escreveu o livro que está em suas mãos, que eu acho ser uma contribuição importante e valiosa para a nossa área. O Danilo está profundamente envolvido em ajudar organizações a implementar as práticas de entrega contínua há vários anos e tem ampla experiência, e eu tenho certeza de que você vai achar o seu livro prático e informativo. Desejo-lhe tudo de melhor na sua jornada.
Sobre o livro
Entregar software em produção é um processo que tem se tornado cada vez mais difícil no departamento de TI de diversas empresas. Ciclos longos de teste e divisões entre as equipes de desenvolvimento e de operações são alguns dos fatores que contribuem para este problema. Mesmo equipes ágeis que produzem software entregável ao final de cada iteração sofrem para chegar em produção quando encontram estas barreiras.
DevOps é um movimento cultural e profissional que está tentando quebrar essas barreiras. Com o foco em automação, colaboração, compartilhamento de ferramentas e de conhecimento, DevOps está mostrando que desenvolvedores e engenheiros de sistema têm muito o que aprender uns com os outros.
Neste livro, mostramos como implementar práticas de DevOps e Entrega Contínua para aumentar a frequência de deploys na sua empresa, ao mesmo tempo aumentando a estabilidade e robustez do sistema em produção. Você vai aprender como automatizar o build e deploy de uma aplicação web, como automatizar o gerenciamento da infraestrutura, como monitorar o sistema em produção, como evoluir a arquitetura e migrá-la para a nuvem, além de conhecer diversas ferramentas que você pode aplicar no seu trabalho.
Agradecimentos
Ao meu pai, Marcos, por ser sempre um exemplo a seguir e por ir além tentando acompanhar os exemplos de código mesmo sem nenhum conhecimento no assunto. À minha mãe, Solange, e minha irmã, Carolina, pelo incentivo e por corrigirem diversos erros de digitação e português nas versões preliminares do livro.
À minha parceira e melhor amiga, Jenny, pelo carinho e apoio durante as diversas horas que passei trabalhando no livro.
Ao meu editor, Paulo Silveira, pela oportunidade, pela confiança e por saber como dar um puxão de orelha ou um incentivo na hora certa para que o livro se tornasse uma realidade. À minha revisora e amiga, Vivian Matsui, por corrigir todos os meus erros de português.
Aos meus revisores técnicos: Hugo Corbucci, Daniel Cordeiro e Carlos Vilella. Obrigado por me ajudarem a encontrar formas melhores de explicar conceitos difíceis, pela opinião sobre os termos difíceis de traduzir, por questionarem minhas decisões técnicas e por me ajudarem a melhorar o conteúdo do livro.
Aos colegas Prasanna Pendse, Emily Rosengren, Eldon Almeida e outros membros do grupo "Blogger's Bloc" na ThoughtWorks, por me incentivarem a escrever mais e pelo feedback nos capítulos iniciais, mesmo não entendendo a língua portuguesa.
Aos meus inúmeros outros colegas de trabalho da ThoughtWorks, em especial Rolf Russell, Brandon Byars e Jez Humble, que ouviram minhas ideias sobre o livro e me ajudaram a escolher a melhor forma de abordar cada assunto, capítulo por capítulo.
Por fim, a todos que contribuíram de forma direta ou indireta na escrita deste livro.
Muito obrigado!
Sobre o autor
Danilo Sato começou a programar ainda criança, quando muitas pessoas ainda não tinham computador em casa. Em 2000 entrou no curso de bacharelado em Ciência da Computação da Universidade de São Paulo, começando sua carreira como administrador da Rede Linux do IME-USP durante 2 anos. Ainda na graduação começou a estagiar como desenvolvedor Java/J2EE e teve seu primeiro contato com Métodos Ágeis na disciplina de Programação Extrema (XP).
Iniciou o mestrado na USP logo após a graduação e, orientado pelo Professor Alfredo Goldman, defendeu em Agosto de 2007 a dissertação "Uso Eficaz de Métricas em Métodos Ágeis de Desenvolvimento de Software" *.
Durante sua carreira, Danilo atuou como consultor, desenvolvedor, administrador de sistemas, analista, engenheiro de sistemas, professor, arquiteto e coach, tornando-se consultor líder da ThoughtWorks em 2008, onde trabalhou em projetos Ruby, Python e Java no Brasil, EUA e no Reino Unido. Atualmente tem ajudado clientes a adotar práticas de DevOps e Entrega Contínua para reduzir o tempo entre a concepção de uma ideia e sua implementação com código rodando em produção.
Além da carreira profissional, Danilo também tem experiência como palestrante em conferências nacionais e internacionais, apresentando palestras e workshops na: XP 2007/2009/2010, Agile 2008/2009, Ágiles 2008, Conexão Java 2007, Falando em Agile 2008, Rio On Rails 2007, PyCon Brasil 2007, RejectConf SP 2007, Rails Summit Latin America 2008, Agile Brazil 2011/2012/2013, QCon SP 2011/2013, RubyConf Brasil 2012/2013, além de ser o fundador do Coding Dojo @ São Paulo e organizador da Agile Brazil 2010, 2011 e 2012.
Sumário
- 1 - Introdução
- 1.1 - Abordagem tradicional
- 1.2 - Uma abordagem alternativa: DevOps e entrega contínua
- 1.3 - Sobre o livro
- 2 - Tudo começa em produção
- 2.1 - Nossa aplicação de exemplo: a loja virtual
- 2.2 - Instalando o ambiente de produção
- 2.3 - Configurando dependências nos servidores de produção
- 2.4 - Build e deploy da aplicação
- 3 - Monitoramento
- 3.1 - Instalando o servidor de monitoramento
- 3.2 - Monitorando outros servidores
- 3.3 - Explorando os comandos de verificação do Nagios
- 3.4 - Adicionando verificações mais específicas
- 3.5 - Recebendo alertas
- 3.6 - Um problema atinge produção, e agora?
- 4 - Infraestrutura como código
- 4.1 - Provisionamento, configuração ou deploy?
- 4.2 - Ferramentas de gerenciamento de configuração
- 4.3 - Introdução ao Puppet: recursos, provedores, manifestos e dependências
- 4.4 - Reinstalando o servidor de banco de dados
- 4.5 - Reinstalando o servidor web
- 4.6 - Fazendo deploy da aplicação
- 5 - Puppet além do básico
- 5.1 - Classes e tipos definidos
- 5.2 - Empacotamento e distribuição usando módulos
- 5.3 - Refatorando o código Puppet do servidor web
- 5.4 - Separação de responsabilidades: infraestrutura vs. aplicação
- 5.5 - Puppet forge: reutilizando módulos da comunidade
- 5.6 - Conclusão
- 6 - Integração contínua
- 6.1 - Práticas de engenharia ágil
- 6.2 - Começando pelo básico: controle de versões
- 6.3 - Automatizando o build do projeto
- 6.4 - Testes automatizados: diminuindo risco e aumentando a confiança
- 6.5 - O que é integração contínua?
- 6.6 - Provisionando um servidor de integração contínua
- 6.7 - Configurando o build da loja virtual
- 6.8 - Infraestrutura como código para o servidor de integração contínua
- 7 - Pipeline de entrega
- 7.1 - Afinidade com a infraestrutura: usando pacotes nativos
- 7.2 - Integração contínua do código de infraestrutura
- 7.3 - Pipeline de entrega
- 7.4 - Próximos Passos
- 8 - Tópicos avançados
- 8.1 - Fazendo deploy na nuvem
- 8.2 - DevOps além das ferramentas
- 8.3 - Sistemas avançados de monitoramento
- 8.4 - Pipelines de entrega complexas
- 8.5 - Gerenciando mudanças no banco de dados
- 8.6 - Orquestração de deploy
- 8.7 - Gerenciando configurações por ambiente
- 8.8 - Evolução arquitetural
- 8.9 - Segurança
- 8.10 - Conclusão
Introdução
Com o avanço da tecnologia, software tem se tornado parte fundamental do dia a dia de muitas empresas. Ao planejar suas férias em família – agendando quarto em hotéis, comprando passagens de avião, realizando transações financeiras, enviando SMS ou compartilhando as fotos da viagem – você interage com diversos sistemas de software. Quando um desses sistemas está fora do ar, o problema não é apenas da empresa que está perdendo negócios, mas também dos usuários que não conseguem realizar suas tarefas. Por esse motivo é importante investir na qualidade e estabilidade do software desde o momento em que a primeira linha de código é escrita até o momento em que ele está rodando em produção.
1.1 - Abordagem tradicional
Metodologias de desenvolvimento de software evoluíram, porém o processo de transformar ideias em código ainda envolve diversas atividades como: levantamento de requisitos, design, arquitetura, implementação e teste. Os Métodos Ágeis de desenvolvimento de software surgiram no final da década de 90 propondo uma nova abordagem para organizar tais atividades. Ao invés de realizá-las em fases distintas – modelo conhecido como processo em cascata – elas acontecem em paralelo o tempo todo, em iterações curtas. Ao final de cada iteração, o software se torna mais e mais útil, com novas funcionalidades e menos bugs, e o time decide junto com o cliente qual a próxima fatia a ser desenvolvida.
Assim que o cliente decide que o software está pronto para ir ao ar e o código é colocado em produção, os verdadeiros usuários começam a usar o sistema. Nesse momento, diversas outras preocupações se tornam relevantes: suporte, monitoramento, segurança, disponibilidade, desempenho, usabilidade, dentre outras. Quando o software está em produção, a prioridade é mantê-lo rodando de forma estável. Em casos de falha ou desastres, o time precisa estar preparado para reagir de forma proativa e resolver o problema rapidamente.
Devido à natureza dessas atividades, muitos departamentos de TI possuem uma divisão clara de responsabilidades entre o time de desenvolvimento e o time de operações. Enquanto o time de desenvolvimento é responsável por criar novos produtos e aplicações, adicionar funcionalidades ou corrigir bugs, o time de operações é responsável por cuidar desses produtos e aplicações em produção. O time de desenvolvimento é incentivado a introduzir mudanças, enquanto o time de operações preza pela estabilidade.
À primeira vista, esta divisão de responsabilidades parece fazer sentido. Cada equipe possui objetivos e formas de trabalho diferentes. Enquanto o time de desenvolvimento trabalha em iterações, o time de operações precisa reagir instantaneamente quando algo dá errado. Além disso, as ferramentas e o conhecimento necessário para trabalhar nessas equipes são diferentes. O time de desenvolvimento evolui o sistema introduzindo mudanças. Por outro lado, o time de operações evita mudanças, pois elas trazem um certo risco à estabilidade do sistema. Cria-se então um conflito de interesse entre essas duas equipes.
Uma vez que o conflito existe, a forma mais comum de gerenciar essa relação é através da criação de processos que definem o modo de trabalho e as responsabilidades de cada equipe. De tempos em tempos, a equipe de desenvolvimento empacota o software que precisa ir para produção, escreve documentação explicando como configurar o sistema, como realizar a instalação em produção e repassa a responsabilidade para o time de operações. É comum o uso de sistemas de controle de tickets para gerenciar a comunicação entre as equipes assim como a definição de acordos de nível de serviço (service-level agreements ou SLAs) para garantir que os tickets sejam processados e respondidos em um tempo adequado.
Essa passagem de bastão – também conhecida em inglês pelo termo hand-off – cria um gargalo no processo de levar código do desenvolvimento e teste para produção. É comum chamar esse processo de deploy em ambiente de produção. Em português é até possível ouvir o neologismo deploiar, ou então o termo correto em português, que seria "implantar".
Com o passar do tempo, o processo tende a se tornar mais e mais burocrático, fazendo com que a frequência de deploys diminua. Com isso, o número de mudanças introduzidas em cada deploy tende a acumular, aumentando também o risco de cada deploy e criando o ciclo vicioso mostrado na figura *.
Esse ciclo vicioso não só diminui a habilidade da empresa de responder rapidamente a mudanças no negócio, como também impacta etapas anteriores do processo de desenvolvimento. A separação entre os times de desenvolvimento e de operações, o hand-off de código existente entre eles e a cerimônia envolvida no processo de deploy acabam criando o problema conhecido como "a Última Milha" *.
A última milha se refere à fase final do processo de desenvolvimento que acontece após o software atender todos os requisitos funcionais mas antes de ser implantado em produção. Ela envolve várias atividades para verificar se o que vai ser entregue é estável ou não, como: testes de integração, testes de sistema, testes de desempenho, testes de segurança, homologação com usuários (também conhecido como User Acceptance Tests ou UAT), testes de usabilidade, ensaios de deploy, migração de dados etc.
É fácil ignorar a última milha quando a equipe está produzindo e demonstrando funcionalidades novas a cada uma ou duas semanas. Porém, são poucas as equipes que de fato fazem deploy em produção ao final de cada iteração. Do ponto de vista do negócio, a empresa só terá retorno no investimento quando o software estiver realmente rodando em produção. O problema da última milha só é visível quando se toma uma visão holística do processo. Para resolvê–lo é preciso olhar além das barreiras impostas entre as diferentes equipes envolvidas: seja a equipe de negócios, a equipe de desenvolvimento ou a equipe de operações.
1.2 - Uma abordagem alternativa: DevOps e entrega contínua
Muitas empresas de sucesso na internet – como Google, Amazon, Netflix, Flickr, GitHub e Facebook – perceberam que a tecnologia pode ser usada a seu favor e que o atraso no deploy para produção significa atrasar sua habilidade de competir e se adaptar a mudanças no mercado. É comum que elas realizem dezenas ou até centenas de deploys por dia!
Essa linha de pensamento que tenta diminuir o tempo entre a criação de uma ideia e sua implementação em produção é também conhecida como "Entrega Contínua" * e está revolucionando o processo de desenvolvimento e entrega de software. Alguns autores preferem utilizar o termo em inglês, continuous delivery.
Quando o processo de deploy deixa de ser uma cerimônia e passa a se tornar algo corriqueiro, o ciclo vicioso da figura * se inverte completamente. O aumento da frequência de deploys faz com que a quantidade de mudanças em cada deploy diminua, reduzindo também o risco associado com aquele deploy. Esse benefício não é algo intuitivo, porém quando algo dá errado é muito mais fácil descobrir o que aconteceu, pois a quantidade de fatores que podem ter causado o problema é menor.
No entanto, a diminuição do risco não implica na remoção completa dos processos criados entre as equipes de desenvolvimento e de operações. O segredo que permite a inversão do ciclo é a automatização desse processo, conforme mostra a figura *. Automatizar o processo de deploy permite que ele seja executado a qualquer momento de forma confiável, removendo o risco de um erro humano causar problemas.
Investir em automatização não é uma ideia nova, muitas equipes já escrevem testes automatizados como parte do processo de desenvolvimento de software. Práticas como o desenvolvimento dirigido a testes (Test-Driven Development ou TDD) * ou a integração contínua * – que será discutida em mais detalhes no capítulo * – são comuns e amplamente aceitas na comunidade de desenvolvimento. Esse foco em automação de testes, juntamente com a criação de equipes multidisciplinares, ajudou a quebrar a barreira existente entre desenvolvedores, testadores e analistas de negócio, criando uma cultura de colaboração entre pessoas com habilidades complementares trabalhando como parte da mesma equipe.
Inspirado no sucesso dos métodos ágeis, um novo movimento surgiu para levar a mesma linha de raciocínio para o próximo nível: o movimento DevOps. Seu objetivo é criar uma cultura de colaboração entre as equipes de desenvolvimento e de operações que permite aumentar o fluxo de trabalho completado – maior frequência de deploys – ao mesmo tempo aumentando a estabilidade e robustez do ambiente de produção.
Além de uma mudança cultural, o movimento DevOps enfoca bastante nas práticas de automação das diversas atividades necessárias para atacar a última milha e entregar código de qualidade em produção, como: compilação do código, testes automatizados, empacotamento, criação de ambientes para teste ou produção, configuração da infraestrutura, migração de dados, monitoramento, agregamento de logs e métricas, auditoria, segurança, desempenho, deploy, entre outros.
Empresas que aplicaram essas práticas de DevOps com sucesso não enxergam mais o departamento de TI como um gargalo mas sim como um agente de capacitação do negócio. Elas conseguem se adaptar a mudanças no mercado rapidamente e realizar diversos deploys por dia de forma segura. Algumas delas inclusive fazem com que um novo desenvolvedor realize um deploy para produção no seu primeiro dia de trabalho!
Este livro irá apresentar, através de exemplos reais, as principais práticas de DevOps e Entrega Contínua para permitir que você replique o mesmo sucesso na sua empresa. O objetivo principal do livro é aproximar as comunidades de desenvolvimento e de operações. Desenvolvedores conhecerão um pouco mais sobre as preocupações e práticas envolvidas para operar e manter sistemas estáveis em produção, enquanto engenheiros e administradores de sistema irão aprender como introduzir mudanças de forma segura e incremental através de automação.
1.3 - Sobre o livro
O principal objetivo do livro é mostrar na prática como aplicar os conceitos e técnicas de DevOps e Entrega Contínua. Por esse motivo, tivemos que escolher quais tecnologias e ferramentas utilizar. Nossa preferência foi usar linguagens e ferramentas de código livre e priorizamos aquelas que são bastante usadas na indústria.
Você vai precisar usar as ferramentas escolhidas para acompanhar os exemplos de código. Porém, sempre que apresentarmos uma nova ferramenta, vamos discutir um pouco sobre as outras alternativas, para que você possa pesquisar qual opção faz mais sentido no seu contexto.
Você não precisa de nenhum conhecimento prévio específico para acompanhar os exemplos. Se você tiver experiência no ecossistema Java ou Ruby, será um bônus. Nosso ambiente de produção vai rodar em UNIX (Linux, para ser mais específico), portanto um pouco de conhecimento no uso da linha de comando pode ajudar mas não é obrigatório *. De toda forma, você vai ser capaz de rodar todos os exemplos na sua própria máquina, independente se está rodando Linux, Mac ou Windows.
Público alvo
Este livro é voltado para desenvolvedores, engenheiros de sistema, administradores de sistema, arquitetos, gerentes e qualquer pessoa com conhecimentos técnicos que tenha interesse em aprender mais sobre as práticas de DevOps e Entrega Contínua.
Estrutura dos capítulos
O livro foi escrito para ser lido do início ao fim de forma sequencial. Dependendo da sua experiência com o assunto abordado em cada capítulo, você pode preferir avançar ou seguir em uma ordem diferente.
No capítulo * apresentamos a aplicação de exemplo que será usada no restante do livro e as tecnologias usadas para construí-la. Como o foco do livro não é no desenvolvimento da aplicação em si, usamos uma aplicação não trivial escrita em Java e usando diversas bibliotecas bem comuns no ecossistema Java. Ao final do capítulo, a aplicação vai estar rodando em produção.
Com um ambiente de produção no ar, no capítulo * vamos vestir o chapéu do time de operações e configurar um servidor de monitoramento para detectar falhas e enviar notificações sempre que algum problema for encontrado. Ao final do capítulo, seremos notificados de que um dos servidores caiu.
No capítulo * vamos reconstruir o servidor problemático, dessa vez de forma automatizada, tratando a infraestrutura como código. O capítulo * é uma continuação do assunto, abordando tópicos mais avançados e refatorando o código para torná-lo mais modular, legível e extensível.
Após vestir o chapéu do time de operações, iremos voltar nossa atenção para o desenvolvimento de software. O capítulo * discute práticas de engenharia ágil que ajudam a escrever código de qualidade. Vamos aprender sobre os diversos tipos de testes automatizados e subir um novo servidor dedicado para fazer integração contínua do código da nossa aplicação.
Apresentamos o conceito da pipeline de entrega no capítulo *. Colocamos o código de infraestrutura na integração contínua e implementamos um processo automatizado para instalar a versão mais nova da aplicação em produção com o simples clique de um botão.
No capítulo * migramos o ambiente de produção para a nuvem. Por fim, discutimos tópicos mais avançados, com ponteiros para recursos onde você pode pesquisar e aprender mais sobre os assuntos que ficaram de fora do escopo deste livro.
Convenções de código
Nos exemplos de código, vamos usar reticências …
para omitir as partes não importantes. Quando o código já existe, vamos repetir as linhas ao redor da área que precisa ser alterada para dar um pouco de contexto sobre a modificação.
Quando a linha é muito comprida e não couber na página, vamos usar uma barra invertida \
para indicar que a próxima linha no livro é a continuação da linha anterior. Você pode simplesmente ignorar a barra invertida e continuar digitando na mesma linha.
Nos exemplos na linha de comando, além da barra invertida, usaremos um sinal de maior >
na próxima linha para indicar que ela ainda é parte do mesmo comando. Isto é para distinguir o comando que precisa ser digitado da saída que o comando produz quando for executado. Ao executar os comandos, você pode simplesmente digitar tudo na mesma linha, ignorando a \
e o >
.
Mais recursos
Criamos um fórum de discussão no Google Groups onde você pode enviar perguntas, sugestões ou feedback direto para o autor. Para se inscrever, acesse a URL:
https://groups.google.com/d/forum/livro-devops-na-pratica
Todos os exemplos de código do livro também estão disponíveis no GitHub do autor, nas URLs:
Dados do produto
- Número de páginas:
- 284
- ISBN:
- 978-85-66250-40-4
- Data publicação:
- 10/2013