A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros

Em algum momento, decidi escrever um artigo sobre a entrega em contêineres Docker e pacotes deb, mas quando comecei, acabei sendo levado a tempos distantes dos primeiros computadores pessoais e até mesmo calculadoras. No geral, em vez de comparações secas entre Docker e deb, surgiram estas reflexões sobre a evolução, que agora apresento para o seu julgamento.

Qualquer produto, independente do que seja, precisa de alguma forma chegar aos servidores de produção, ser configurado e iniciado. É sobre isso que este artigo tratará.

Refletirei dentro de um contexto histórico, "o que vejo — disso canto", sobre o que observei quando comecei a programar e o que vejo agora, o que usamos atualmente e por quê. O artigo não tem pretensão de ser uma pesquisa completa, alguns pontos foram deixados de lado, é minha visão pessoal do que foi e do que é hoje.

Então, nos bons velhos tempos… a forma mais primitiva de entrega que conheci foram as fitas de cassete dos gravadores. Eu tinha um computador BK-0010.01...

A era das calculadoras

Não, havia um momento ainda mais anterior, havia uma calculadora MK-61 e MK-52.

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros Então, quando eu tinha MK-61, a forma de transferir um programa era uma folha de papel quadriculado, onde estava escrita a programação, que quando necessário, era inserida manualmente na calculadora. Se quisesse jogar (sim, até mesmo nessa calculadora pré-histórica havia jogos) — você se sentava e digitava o programa na calculadora. Naturalmente, ao desligar a calculadora, o programa desaparecia. Além dos códigos que eram anotados à mão, os programas eram publicados nas revistas "Rádio" e "Técnica da Juventude", e também impressos em livros da época.

A próxima modificação foi a calculadora MK-52, que já tinha algum tipo de memória não volátil. Agora, não era mais necessário digitar manualmente o jogo ou programa, bastava realizar alguns movimentos mágicos nos botões e ele carregava automaticamente.

O tamanho do maior programa na calculadora era de 105 passos, enquanto a memória permanente do MK-52 era de 512 passos.

A propósito, se houver fãs dessas calculadoras que estão lendo este artigo — durante a escrita, encontrei um emulador da calculadora para Android, e programas para ele. Vamos em frente, ao passado!

Uma pequena digressão sobre o MK-52 (da Wikipédia)

O MK-52 voou ao espaço na nave 'Soyuz TM-7'. Ele foi destinado a ser usado para calcular a trajetória de pouso, caso o computador de bordo falhasse.

O MK-52 com o bloco de expansão de memória 'Eletrônica-Astro' foi fornecido às naves da Marinha a partir de 1988 como parte do conjunto de cálculo de navegação.

Os primeiros computadores pessoais

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros Vamos voltar aos tempos BK-0010. É claro que a memória também aumentou, e inserir código a partir de papel tornou-se inviável (embora eu tenha feito isso no início, pois não havia outro meio de armazenamento). O principal meio de armazenamento e fornecimento de software passou a ser fitas cassete para gravadores.





A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outrosO armazenamento em fita geralmente consistia em um ou dois arquivos binários, o restante estava contido internamente. A confiabilidade era muito baixa, e era preciso manter 2-3 cópias do programa. O tempo de carregamento também não era satisfatório, e entusiastas experimentavam diferentes codificações de frequência para superar essas limitações. Naquela época, eu ainda não estava envolvido no desenvolvimento profissional de software (exceto por programas simples em BASIC), então, infelizmente, não posso explicar em detalhes como tudo funcionava internamente. O fato de que o computador possuía apenas RAM em sua maior parte determinava a simplicidade do esquema de armazenamento de dados.

Aparecimento de suportes confiáveis e grandes de informações

Mais tarde, os disquetes surgem, simplificando o processo de cópia e aumentando a confiabilidade.
Mas a situação muda radicalmente apenas quando surgem grandes armazenamentos locais na forma de HDD.

Muda fundamentalmente o tipo de fornecimento: surgem programas instaladores que gerenciam o processo de configuração do sistema, bem como a limpeza após a remoção, pois os programas não são apenas lidos na memória, mas já copiados para o armazenamento local, do qual é preciso saber como limpar o desnecessário quando necessário.

Paralelamente, aumenta a complexidade do software fornecido.
O número de arquivos no fornecimento aumenta de uma unidade para centenas e milhares, surgem conflitos de versões de bibliotecas e outras alegrias quando diferentes programas usam os mesmos dados.

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros Naquela época, eu ainda não conhecia a existência do Linux; vivia em um mundo MS DOS e, depois, Windows, programando em Borland Pascal e Delphi, às vezes olhando para o C++. Para a entrega de produtos, muitas pessoas usavam InstallShield. ru.wikipedia.org/wiki/InstallShield, que resolvia com sucesso todas as tarefas de implantação e configuração de software.




A era da internet

Gradualmente, a complexidade dos sistemas de software aumentou, passando de monólitos e aplicativos de desktop para sistemas distribuídos, clientes leves e microserviços. Agora, é necessário configurar não apenas um programa, mas um conjunto deles, garantindo que todos funcionem bem juntos.

A concepção mudou completamente; a Internet chegou e a era dos serviços em nuvem começou. Ainda estava apenas em sua fase inicial, na forma de sites, e ninguém sonhava realmente com serviços. Mas esse foi um ponto de virada na indústria, tanto no desenvolvimento quanto na entrega de aplicativos.

Para mim, ficou claro que nesse momento houve uma mudança de gerações de desenvolvedores (ou isso aconteceu apenas no meu círculo), e parecia que todos os antigos e bons métodos de entrega haviam sido esquecidos de repente, e tudo começou do começo: toda a entrega passou a ser feita através de scripts improvisados, e isso foi chamado orgulhosamente de "entrega contínua". De fato, começou um período de desordem, onde o antigo foi esquecido e não utilizado, e o novo simplesmente não existia.

Lembro-me de tempos em que, na empresa onde trabalhava (não vou nomear), em vez de fazer a build com ant (maven ainda não era popular ou não existia), as pessoas simplesmente criavam o jar na IDE e o enviavam tranquilamente para o SVN. Assim, a implantação consistia em pegar o arquivo do SVN e copiá-lo via SSH para a máquina certa. Simples e rudimentar.

Na mesma época, a entrega de sites simples em PHP era feita de maneira extremamente primitiva, simplesmente copiando o arquivo corrigido via FTP para a máquina de destino. Às vezes, nem isso; o código era corrigido em tempo real no servidor de produção, e era um grande benefício se houvesse backups em algum lugar.


Pacotes RPM e DEB

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outrosPor outro lado, com o desenvolvimento da internet, sistemas semelhantes ao UNIX começaram a ganhar popularidade, em particular, foi nesse período que descobri o RedHat Linux 6, por volta do ano 2000. É claro que havia certas ferramentas para a entrega de software, segundo a Wikipedia, o RPM, como o principal gerenciador de pacotes, surgiu em 1995, na versão 2.0 do RedHat Linux. Desde então, até os dias de hoje, o sistema é distribuído em formato de pacotes RPM e continua a existir e se desenvolver com sucesso.

As distribuições da família Debian seguiram um caminho semelhante e implementaram a entrega em formato de pacotes deb, que também se mantém inalterado até hoje.

Os gerenciadores de pacotes permitem a entrega dos próprios produtos de software, configurar durante a instalação, gerenciar dependências entre diferentes pacotes, realizar a remoção de produtos e a limpeza de resíduos durante a desinstalação. Ou seja, na maior parte, isso é tudo que é necessário, é por isso que eles sobreviveram por várias décadas praticamente sem mudanças.

A computação em nuvem adicionou aos gerenciadores de pacotes a instalação não apenas de mídias físicas, mas também de repositórios em nuvem, mas a essência mudou pouco.

Vale destacar que atualmente há alguns movimentos em direção à substituição dos pacotes deb por pacotes snap, mas isso será abordado mais adiante.

Assim, essa nova geração de desenvolvedores em nuvem, que não conheceu nem DEB nem RPM, também cresceu lentamente, adquirindo experiência, os produtos foram se tornando mais complexos, e foram necessárias formas mais racionais de entrega do que FTP, scripts bash e outras gambiarras estudantis.
E aqui entra o Docker, uma espécie de mistura de virtualização, controle de recursos e método de entrega. Isso agora é tendência, moderno entre os jovens, mas será que é necessário para tudo? É uma panaceia?

Pelo que observei, muitas vezes o Docker é proposto não como uma escolha sensata, mas simplesmente porque, por um lado, é o que se discute na comunidade, e aqueles que o recomendam só conhecem ele. Por outro lado, os bons e velhos sistemas de empacotamento, na maior parte, permanecem silenciosos — eles existem e fazem seu trabalho de forma discreta. Nessa situação, não há muito para escolher — a escolha é óbvia — Docker.

Vou tentar compartilhar a experiência de como foi a nossa implementação do Docker e o que resultou disso.


Scripts personalizados

Inicialmente, havia scripts bash que realizavam a implantação de arquivos jar nas máquinas apropriadas. Esse processo era gerenciado pelo Jenkins. Isso funcionou bem, uma vez que o próprio arquivo jar já é uma construção que contém classes, recursos e até mesmo configurações. Se você incluir tudo o que puder nele, descompactá-lo com um script não é a tarefa mais difícil.

Mas os scripts têm algumas desvantagens:

  • os scripts geralmente são escritos às pressas e, portanto, são tão primitivos que contêm apenas um único cenário bem-sucedido. Isso é facilitado pelo fato de que o desenvolvedor está interessado em uma entrega rápida, enquanto um script adequado requer um investimento considerável de recursos.
  • como consequência do ponto anterior, os scripts não incluem procedimentos de desinstalação.
  • não há um procedimento de atualização estabelecido.
  • quando um novo produto aparece, é necessário escrever um novo script.
  • não há suporte para dependências.

Claro, é possível escrever um script sofisticado, mas, como mencionei antes, isso consome tempo de desenvolvimento, e, como sabemos, o tempo é sempre escasso.

Tudo isso limita evidentemente o uso desse método de implantação a sistemas muito simples. Chegou a hora de mudar isso.


Docker

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outrosEm algum momento, começaram a chegar até nós novos desenvolvedores repletos de ideias e fissurados por Docker. Bem, vamos em frente — vamos fazer! Houve duas tentativas. Ambas, infelizes — digamos assim, devido a grandes ambições, mas com experiência real insuficiente. Era necessário apressar e finalizar de qualquer forma? Dificilmente — a equipe deve evoluir gradualmente para o nível necessário antes de conseguir usar as ferramentas apropriadas. Além disso, ao usar imagens Docker prontas, frequentemente encontramos problemas na rede (o que, possivelmente, estava ainda relacionado à imaturidade do próprio Docker) ou era difícil expandir os contêineres de terceiros.

Quais incômodos encontramos?

  • Problemas de rede no modo bridge.
  • É inconveniente visualizar logs no contêiner (a menos que eles sejam exportados separadamente para o sistema de arquivos da máquina host).
  • Periodicamente, houve um estranho congelamento do ElasticSearch dentro do contêiner, a causa não foi identificada, sendo o contêiner oficial.
  • É incômodo usar o shell dentro do contêiner — tudo é muito limitado, não há as ferramentas habituais.
  • O grande tamanho dos contêineres coletados - é caro armazenar.
  • Devido ao grande tamanho dos contêineres, é difícil manter múltiplas versões.
  • Montagem mais longa, ao contrário de outros métodos (scripts ou pacotes deb).

Por outro lado, por que o serviço Spring na forma de um arquivo jar é pior para implantar através do mesmo deb? Realmente precisamos de isolamento de recursos? Vale a pena abrir mão das ferramentas convenientes do sistema operacional colocando o serviço em um contêiner severamente limitado?

Como mostrou a prática - na realidade, isso não é necessário; um pacote deb é suficiente em 90% dos casos.

Quando o velho e bom deb não funciona e quando realmente precisávamos do Docker?

Para nós, isso foi a implementação de serviços em Python. Muitas bibliotecas necessárias para aprendizado de máquina que estão ausentes na distribuição padrão do sistema operacional (e as que estavam não eram as versões adequadas), hacks de configuração, a necessidade de diferentes versões para diferentes serviços que operam na mesma máquina host resultaram no fato de que o único modo razoável de entrega dessa mistura complexa era o Docker. O esforço de montar um contêiner Docker acabou sendo menor do que a ideia de empacotar tudo isso em pacotes deb separados com dependências; na realidade, ninguém em sã consciência se atreveria a fazer isso.

O segundo ponto onde se pretende usar o Docker é para a implementação de serviços no esquema de blue-green deploy. Mas aqui queremos uma complexidade crescente gradual: primeiro, pacotes deb são montados e, em seguida, um contêiner Docker é construído a partir deles.


Pacotes Snap

A evolução dos meios de entrega, ou reflexões sobre Docker, deb, jar e outros Voltando aos pacotes Snap. Eles apareceram oficialmente pela primeira vez no Ubuntu 16.04. Ao contrário dos pacotes deb e rpm habituais, o snap carrega todas as dependências. Por um lado, isso ajuda a evitar conflitos de bibliotecas, por outro lado, isso resulta em tamanhos de pacotes finais maiores. Além disso, isso pode impactar a segurança do sistema: ao fornecer o snap, o desenvolvedor que cria o pacote deve acompanhar todas as mudanças nas bibliotecas incluídas. Em suma, não é tão simples e a felicidade universal com seu uso não se concretiza. No entanto, ainda assim, é uma alternativa bastante razoável se o mesmo Docker é usado apenas como um meio de empacotamento, e não de virtualização.



Como resultado, agora utilizamos uma combinação razoável de pacotes deb e contêineres Docker, que, em alguns casos, talvez possamos substituir por pacotes snap.

Apenas usuários registrados podem participar da pesquisa. Entre, por favor.

E você, o que utiliza para a entrega?

  • Scripts personalizados

  • Copiamos manualmente via FTP

  • pacotes deb

  • pacotes rpm

  • pacotes snap

  • Imagens Docker

  • Imagens de máquinas virtuais

  • Clonamos o HDD inteiro

  • puppet

  • ansible

  • Outro

109 usuários votaram. 32 usuários se abstiveram.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster