Certa vez, decidi escrever um artigo sobre entrega na forma de contêineres Docker e pacotes deb, mas quando comecei, por algum motivo fui levado de volta aos tempos distantes dos primeiros computadores pessoais e até calculadoras. Em geral, em vez de comparações áridas entre docker e deb, obtivemos essas reflexões sobre o tema da evolução, que apresento para sua consideração.
Qualquer produto, não importa qual seja, deve de alguma forma chegar aos servidores do produto, deve ser configurado e iniciado. É sobre isso que este artigo tratará.
Pensarei em um contexto histórico, “o que vejo é sobre o que canto”, o que vi quando comecei a escrever código e o que observo agora, o que nós mesmos estamos usando no momento e por quê. O artigo não pretende ser um estudo completo, faltam alguns pontos, esta é a minha visão pessoal do que foi e do que é agora.
Então, nos velhos tempos... o primeiro método de entrega que encontrei eram fitas cassete de gravadores. Eu tinha um computador BK-0010.01...
A era das calculadoras
Não, houve um momento ainda anterior, também houve uma calculadora
Então, quando eu tive
A próxima modificação foi uma calculadora
O tamanho do maior programa da calculadora era de 105 passos, e o tamanho da memória permanente no MK-52 era de 512 passos.
A propósito, se há fãs dessas calculadoras que estão lendo este artigo, no processo de redação do artigo encontrei um emulador de calculadora para Android e programas para ele. Avance para o passado!
Uma breve digressão sobre o MK-52 (da Wikipédia)
MK-52 voou para o espaço na espaçonave Soyuz TM-7. Era para ser usado para calcular a trajetória de pouso caso o computador de bordo falhasse.
Desde 52, o MK-1988 com unidade de expansão de memória Elektronika-Astro é fornecido aos navios da Marinha como parte de um kit de computação de navegação.
Os primeiros computadores pessoais
Vamos voltar aos tempos
O armazenamento em uma fita geralmente era na forma de um ou dois arquivos binários, todo o resto estava contido dentro. A confiabilidade era muito baixa, tive que manter 2 a 3 cópias do programa. Os tempos de carregamento também foram decepcionantes e os entusiastas experimentaram diferentes codificações de frequência para superar essas deficiências. Naquela época, eu ainda não estava envolvido no desenvolvimento profissional de software (sem contar programas simples em BASIC), então, infelizmente, não vou contar em detalhes como tudo estava organizado lá dentro. O próprio fato de o computador ter apenas RAM em sua maior parte determinou a simplicidade do esquema de armazenamento de dados.
O surgimento de mídias de armazenamento grandes e confiáveis
Mais tarde, surgiram os disquetes, o processo de cópia foi simplificado e a confiabilidade aumentou.
Mas a situação só muda drasticamente quando armazenamentos locais suficientemente grandes aparecem na forma de HDDs.
O tipo de entrega está mudando fundamentalmente: aparecem programas instaladores que gerenciam o processo de configuração do sistema, bem como a limpeza após a remoção, uma vez que os programas não são apenas lidos na memória, mas já copiados para o armazenamento local, de onde você precisa para ser capaz de limpar coisas desnecessárias, se necessário.
Ao mesmo tempo, a complexidade do software fornecido está a aumentar.
O número de arquivos entregues aumenta de alguns para centenas e milhares, os conflitos entre versões da biblioteca e outras alegrias começam quando programas diferentes usam os mesmos dados.
Naquela época, a existência do Linux ainda não estava aberta para mim; eu vivia no mundo do MS DOS e, mais tarde, do Windows, e escrevia em Borland Pascal e Delphi, às vezes olhando para C++. Muitas pessoas usaram o InstallShield para entregar produtos naquela época.
Era da Internet
Gradualmente, a complexidade dos sistemas de software está se tornando ainda mais complexa; dos aplicativos monolíticos e de desktop há uma transição para sistemas distribuídos, thin clients e microsserviços. Agora você precisa configurar não apenas um programa, mas um conjunto deles, e para que todos funcionem juntos.
O conceito mudou completamente, chegou a Internet, chegou a era dos serviços em nuvem. Até agora, apenas na fase inicial, na forma de sites, ninguém sonhou particularmente com serviços. mas foi um ponto de viragem tanto no desenvolvimento como na entrega de aplicações.
Quanto a mim, notei que naquele momento houve uma mudança nas gerações de desenvolvedores (ou foi apenas no meu ambiente), e houve a sensação de que todos os bons e velhos métodos de entrega foram esquecidos em um momento e tudo começou desde o início início: toda entrega passou a ser feita por scripts de joelho e orgulhosamente chamou de “Entrega Contínua”. Na verdade, começou um período de caos, quando o antigo é esquecido e não utilizado, e o novo simplesmente não existe.
Lembro-me dos tempos em que em nossa empresa onde eu trabalhava (não vou citar o nome), em vez de construir via ant (o maven ainda não era popular ou nem existia), as pessoas simplesmente coletavam jars no IDE e se comprometevam serenamente em SVN. Assim, a implantação consistiu em recuperar o arquivo do SVN e copiá-lo via SSH para a máquina desejada. É tão simples e desajeitado.
Ao mesmo tempo, a entrega de sites simples em PHP era feita de forma bastante primitiva, simplesmente copiando o arquivo corrigido via FTP para a máquina alvo. Às vezes, esse não era o caso - o código era editado ao vivo no servidor do produto e era especialmente chique se houvesse backups em algum lugar.
Pacotes RPM e DEB
Por outro lado, com o desenvolvimento da Internet, os sistemas do tipo UNIX começaram a ganhar cada vez mais popularidade, em particular, foi nessa época que descobri o RedHat Linux 6, aproximadamente em 2000. Naturalmente, também existiam certos meios de entrega de software: segundo a Wikipedia, o RPM como principal gerenciador de pacotes apareceu já em 1995, na versão do RedHat Linux 2.0. E desde então e até hoje, o sistema foi entregue na forma de pacotes RPM e tem existido e se desenvolvido com bastante sucesso.
As distribuições da família Debian seguiram um caminho semelhante e implementaram a entrega na forma de pacotes deb, que permanece inalterada até hoje.
Os gerenciadores de pacotes permitem que você entregue os próprios produtos de software, configure-os durante o processo de instalação, gerencie dependências entre diferentes pacotes, remova produtos e limpe itens desnecessários durante o processo de desinstalação. Aqueles. na maior parte, isso é tudo o que é necessário, e é por isso que duraram várias décadas praticamente inalterados.
A computação em nuvem adicionou instalação aos gerenciadores de pacotes não apenas de mídia física, mas também de repositórios em nuvem, mas fundamentalmente pouco mudou.
É importante notar que atualmente existem alguns movimentos no sentido de se afastar do deb e mudar para pacotes snap, mas falaremos mais sobre isso mais tarde.
Portanto, essa nova geração de desenvolvedores de nuvem, que não conheciam DEB nem RPM, também cresceu lentamente, ganhou experiência, os produtos tornaram-se mais complexos e foram necessários alguns métodos de entrega mais razoáveis do que FTP, scripts bash e trabalhos estudantis semelhantes.
E é aí que entra o Docker, uma espécie de mistura de virtualização, delimitação de recursos e método de entrega. Está na moda e é jovem agora, mas é necessário para tudo? Isso é uma panacéia?
Pelas minhas observações, muitas vezes o Docker é proposto não como uma escolha razoável, mas simplesmente porque, por um lado, é falado na comunidade, e quem o propõe só sabe disso. Por outro lado, na maioria das vezes eles silenciam sobre os bons e velhos sistemas de embalagem - eles existem e fazem seu trabalho silenciosamente e despercebidos. Em tal situação, realmente não há outra escolha - a escolha é óbvia - Docker.
Tentarei compartilhar minha experiência de como implementamos o Docker e o que aconteceu como resultado.
Roteiros auto-escritos
Inicialmente, havia scripts bash que implantavam arquivos jar nas máquinas necessárias. Este processo foi gerenciado por Jenkins. Isso funcionou com sucesso, pois o próprio arquivo jar já é um assembly contendo classes, recursos e até configuração. Se você colocar tudo ao máximo, expandi-lo em um script não é a coisa mais difícil que você precisa
Mas os scripts têm várias desvantagens:
- os scripts geralmente são escritos às pressas e, portanto, são tão primitivos que contêm apenas um cenário ideal. Isso é facilitado pelo fato de o desenvolvedor estar interessado na entrega rápida, e um script normal requer o investimento de uma quantidade razoável de recursos
- como consequência do ponto anterior, os scripts não contêm procedimentos de desinstalação
- nenhum procedimento de atualização estabelecido
- Quando um novo produto aparece, você precisa escrever um novo script
- sem suporte de dependência
Claro, você pode escrever um script sofisticado, mas, como escrevi acima, isso é tempo de desenvolvimento, e não menos importante, e, como sabemos, sempre não há tempo suficiente.
Tudo isto obviamente limita a gama de aplicação deste método de implantação apenas aos sistemas mais simples. Chegou a hora de mudar isso.
Estivador
Em algum momento, middles recém-criados começaram a chegar até nós, fervilhando de ideias e delirando sobre o estivador. Bem, bandeira na mão - vamos lá! Houve duas tentativas. Ambos não tiveram sucesso - digamos, devido a grandes ambições, mas à falta de experiência real. Foi necessário forçá-lo e acabar com ele de qualquer maneira possível? É improvável – a equipe deve evoluir até o nível exigido antes de poder usar as ferramentas apropriadas. Além disso, ao usar imagens Docker prontas, muitas vezes nos deparamos com o fato de que a rede não funcionava corretamente (o que pode ter sido devido à umidade do próprio Docker) ou era difícil expandir os contêineres de outras pessoas.
Que inconvenientes encontramos?
- Problemas de rede no modo bridge
- É inconveniente visualizar os logs em um contêiner (se eles não estiverem armazenados separadamente no sistema de arquivos da máquina host)
- O ElasticSearch ocasionalmente congela estranhamente dentro do contêiner, o motivo não foi determinado, o contêiner é oficial
- É necessário usar um shell dentro de um container - tudo é muito despojado, não há ferramentas usuais
- Grande tamanho de recipientes coletados – caro para armazenar
- Devido ao grande tamanho dos contêineres, é difícil suportar múltiplas versões
- Tempo de construção mais longo, ao contrário de outros métodos (scripts ou pacotes deb)
Por outro lado, por que é pior implantar um serviço Spring na forma de um arquivo jar através do mesmo deb? O isolamento de recursos é realmente necessário? Vale a pena perder ferramentas convenientes do sistema operacional ao colocar um serviço em um contêiner bastante reduzido?
Como a prática tem mostrado, na realidade isso não é necessário, o pacote deb é suficiente em 90% dos casos.
Quando o bom e velho deb falha e quando realmente precisamos do docker?
Para nós, isso foi implantar serviços em python. Muitas bibliotecas necessárias para aprendizado de máquina e não incluídas na distribuição padrão do sistema operacional (e o que havia eram versões erradas), hacks com configurações, a necessidade de versões diferentes para serviços diferentes residentes no mesmo sistema host levaram a isto, que a única forma razoável de entregar esta mistura nuclear era o estivador. A intensidade de trabalho para montar um contêiner docker acabou sendo menor do que a ideia de empacotar tudo em pacotes deb separados com dependências e, de fato, ninguém em sã consciência faria isso.
O segundo ponto onde está planejado o uso do Docker é a implantação de serviços de acordo com o esquema de implantação azul-verde. Mas aqui quero obter um aumento gradual na complexidade: primeiro, os pacotes deb são construídos e, em seguida, um contêiner docker é construído a partir deles.
Pacotes instantâneos
Vamos voltar aos pacotes instantâneos. Eles apareceram oficialmente pela primeira vez no Ubuntu 16.04. Ao contrário dos pacotes deb e rpm usuais, o snap carrega todas as dependências. Por um lado, isso permite evitar conflitos de biblioteca, por outro lado, o pacote resultante é maior. Além disso, isso também pode afetar a segurança do sistema: no caso de entrega instantânea, todas as alterações nas bibliotecas incluídas devem ser monitoradas pelo desenvolvedor que cria o pacote. Em geral, nem tudo é tão simples e a felicidade universal não vem do seu uso. Mas, no entanto, esta é uma alternativa bastante razoável se o mesmo Docker for usado apenas como ferramenta de empacotamento e não para virtualização.
Como resultado, agora usamos pacotes deb e contêineres docker em uma combinação razoável, que, talvez, em alguns casos substituiremos por pacotes snap.
Apenas usuários registrados podem participar da pesquisa.
O que você usa para entrega?
-
Roteiros auto-escritos
-
Copiar manualmente para FTP
-
pacotes deb
-
pacotes rpm
-
pacotes instantâneos
-
Imagens Docker
-
Imagens de máquinas virtuais
-
Clonar todo o HDD
-
boneco
-
ansible
-
Outro
109 usuários votaram. 32 usuários se abstiveram.
Fonte: habr.com