Uma breve história de infraestrutura - Parte 1: Mainframes.
Tags: containers, virtualmachine, mainframe, virtualization
Published: 2023-04-25 12:05:41

> **Disclaimer**: _A intenção do artigo é expor meu entendimento do assunto, não sou especialista. Pelo contrário, estou em fase de estudo, então me avisem se eu me equivocar em alguma explicação. 

Este artigo é um **resumo** do vídeo Entendendo "Devops" para Iniciantes em Programação (Parte 1) | Série "Começando aos 40" do Fabio Akita. [(Link)](https://www.youtube.com/watch?v=bwO8EZf0gLI&list=PLdsnXVqbHDUdjNjfekBoCBfGtJ6kNRef-)

Meu objetivo é entender melhor o caminho que percorremos desde o mainframe até as infraestruturas modernas com Docker e Kubernetes. Nessa parte 1, buscarei traçar uma linha histórica **em alto nível** dos anos 60 até meados de 2010.

## Mainframes

Essa história começa nos anos 60, onde os mainframes reinavam. Eles eram máquinas imensas numa época onde o hardware era muito caro. Não eram tão poderosas, então alguns processos demoravam para executar, como a escrita (_output_) por exemplo. Com diversas pesquisas e estudos aliado ao avanço do poder das máquinas, foi possível particionar o mainframe para rodar mais de uma **kernel** (_componente central de um sistema operacional responsável por ser o elo entre hardware software_) por vez, cada um com seu sistema operacional e acesso a uma parte real dos recursos de I/O. Dessa forma foi possível otimizar melhor os recursos e ganhar produtividade. 

## Primeiras gerações de websites

Avançamos até os anos 90, com o hardware se tornando mais acessível a pequenas empresas, as máquinas se tornando mais poderosas e novas pesquisas e tecnologias surgindo. Nessa época a experiência do Unix foi trazida para o Linux permitindo multiusuário e multitarefa. Foi um cenário favorável para o surgimento de um novo modelo de negócios: empresas começaram a prover sites ao preço de uma assinatura mensal. Esses serviços de hospedagem conseguiam prover dezenas de sites numa mesma máquina, dividindo os recursos e o acesso utilizando o recurso de _Virtual Host_ dos servidores web (mapeando urls para pastas de estáticos ou ativando programas cgi). Assim surgiram as primeiras gerações de websites usando a famosa stack LAMP (Linux, Apache, MySQL e PHP). Mas como é de se esperar, aqui começamos a ter muitos problemas de segurança. (_se quiser aprofundar, veja o vídeo completo_)

## Container vs Virtualização

No início dos anos 2000, algumas pesquisas começaram a dar frutos. Nessa época tivemos tentativas de limitar o que um processo poderia fazer **isolando recursos de uma mesma máquina** com as tecnologias Jail(_FreeBSD_), _LinuxVServer_ e containers de _Solaris_. Na prática essas soluções são baseadas em mentiras que o kernel conta para os processos fazendo-os acreditarem que possuem mais recursos e acessos do que realmente têm. A esse conceito damos o nome de  **containers**. 

Em contrapartida, a **virtualização** apesar de também querer otimizar recursos de uma mesma máquina, possui duas abordagens diferentes:
- **Bare Metal**: Gerencia e compartilha recursos reais da máquina. Por isso os mainframes eram muito eficientes, cada máquina virtual tinha acesso a recursos reais de I/O.
- **Hosted**: Um programa especial chamado _Hypervisor_ que executa em um sistema operacional(SO) hospedeiro simula uma máquina virtual (recursos) executando um SO convidado. Consequentemente gera um peso grande de execução. Exemplo: VirtualBox 

Com essa definição podemos entender a grande diferença entre virtualização e containers. Containers faziam processos **executarem de forma restrita num mesmo sistema operacional**. Já a virtualização, **permite que um processo rode como se fosse numa máquina real ao virtualizar uma máquina inteira** com um SO até mesmo diferente do SO original da máquina real. Essa virtualização é chamada de completa. 

Apesar da vantagem da virtualização de conseguir executar um Linux numa máquina Windows por exemplo, isso era um processo muito lento e pesado pois o _Hypervisor_ precisava "mentir sozinho" quando os processos precisavam fazer _system calls_. (Chamadas a instruções do kernel) Como evolução, surgiu a **paravirtualização** onde agora o SO também consegue mentir para os processos, tornando o desempenho do SO convidado melhor diminuindo a dependência do _Hypervisor_.  
Visando ainda mais performance, a AMD e Intel começaram a  trazer instruções de máquina específicas para virtualizações, tornando o desempenho quase de uma máquina real. 

## O início da infraestrutura como código

Esses avanços na virtualização se tornaram muito importantes para empresas que tinham que gerir _datacenters_. Pois poderiam de forma performática dividir os recursos das máquinas para diversos clientes diferentes. Mas configurar diversos servidores, com máquinas virtuais, redes e aplicações era uma tarefa bem trabalhosa. A tecnologia _VPS(Virtual Private Server)_ da Microsoft aliviou esse problema. Ela conseguia automatizar a criação de máquinas virtuais usando imagens de SO (snapshots) tornando possível subir uma máquina nova em minutos. Mas isso ainda não resolvia o problema das empresas que precisavam gerir uma infraestrutura bem mais complexa. 

Diante do quão trabalhoso era prover uma infraestrutura do zero "na mão", em 1993 já começavam a surgir ferramentas para automatização desse processo como a _CFEngine_ (em 1998 a _CFEngine3_). Com essa ferramenta era possível escrever "receitas" de configuração (linguagem declarativa) que instalava várias máquinas da mesma forma com apenas um comando. Em 2005, tivemos o _Puppet_ escrito em _Ruby_ e em 2009 o _Chef_ também escrito em _Ruby_. Essas ferramentas deram início a infraestrutura como código, sendo possível criar e compartilhar receitas em repositórios bem semelhante ao _Git/Github_ usufruindo assim da colaboração da comunidade OpenSource. 
Essas ferramentas funcionavam em uma arquitetura cliente e servidor. Onde cada cliente possui um processo agente que fica escutando um servidor para instalar e configurar o que for requisitado. Consequentemente era preciso configurar o agente e o servidor, o que poderia ser trabalhoso demais para uma única máquina.

Anos depois tivemos ferramentas _agentless_ como **Capistrano** e **Ansible** que são mais simples de configurar para uma única máquina, em relação as outras ferramentas citadas anteriormente. O que torna mais simples é ter apenas o servidor usando conexão **ssh** como túnel para executar arquivos em máquinas remotas.
Cada ferramenta tem seu propósito, a grosso modo, sendo as _agentless_ mais voltadas para casos de uso mais simples (desenvolvedores) e as baseadas em _agent_ mais voltadas a infraestruturas mais complexas.

Mas será que essas ferramentas só servem para automatizar? Pelo contrário, além de agilizar a criação e configuração, essas ferramentas são essenciais para **manter** uma infraestrutura atualizada e segura. Também ajudam a destruir e reconstruir rapidamente máquinas que foram atacadas por exemplo. Tentar fazer essas tarefas "na mão", comando a comando torna o processo além de trabalhoso e improdutivo, também muito passível de erro por esquecimento de algum comando, além de difícil replicação. 
 
## Surgimento e expansão das **Big Techs**

Do meio para o final dos anos 2000, temos o surgimento e a expansão de grandes _Tech Startups_ trazendo serviços e produtos que faziam as pessoas ficarem mais tempos conectadas na internet de um jeito nunca visto antes. Muitas tecnologias surgiram e evoluíram para conseguirem apoiar a escala dessas empresas. Na parte 2 do vídeo vamos entender como a evolução dessas tecnologias culminaram no Docker e Kubernetes que temos hoje. 

Continua...