
Olá Habr! Meu nome é Dmitry, sou desenvolvedor do ISPsystem. Recentemente, lançamos na versão beta do teste uma nova versão do painel de controle da máquina virtual. Hoje vou lhe contar como decidimos o que levar de um produto antigo e o que é melhor recusar. Vou abordar as questões mais importantes para nós: uma biblioteca para trabalhar com libvirt, suporte para vários sistemas operacionais durante a instalação do produto, a transição do monólito para os microsserviços e a implantação de máquinas virtuais.
O artigo é sobre o
VMmanager . Este é um sistema para gerenciar, implantar e monitorar máquinas virtuais com base na virtualização KVM e OVZ. A quinta geração saiu em 2012. Desde então, a interface ficou muito desatualizada e a arquitetura centralizada impediu o desenvolvimento do produto. É hora de fazer uma nova versão.
A primeira história. Usamos o trabalho dos elfos domésticos
Trabalhar com libvirt: considere opções, selecione bibliotecas
Como uma ferramenta para gerenciar a virtualização KVM, nosso produto usa libvirt. Em 2012, uma biblioteca escrita em C foi escolhida para trabalhar com ela, por isso era mais conveniente para essa equipe de desenvolvimento. Como resultado - uma grande quantidade de código escrito em C ++, chamando a biblioteca C, que implementa o trabalho direto com libvirt.
E agora, no limiar de um novo projeto, olhamos para trás e examinamos nosso produto, avaliamos se vale a pena tomar uma solução / tecnologia específica; o que se provou e o que precisa ser lembrado e nunca repetido.
Sentamos e fazemos uma retrospectiva de muitos anos de trabalho na versão anterior do produto. Somos pacientes, pegamos adesivos e escrevemos três tipos de papéis:
- O que teve sucesso no produto? O que os usuários elogiaram? O que nunca ouviu reclamações? Do que você gostou?
- O que falhou? Quais eram os problemas constantemente? O que dificultou o trabalho e por que eles começaram uma nova filial?
- O que pode ser mudado? O que os usuários solicitam? O que os membros da equipe querem mudar?
O grupo de pessoas que estragam o papel com zelo deve incluir aqueles que estão em contato próximo com o produto há séculos e aqueles que podem dar uma nova olhada no produto. Não se esqueça da solicitação de recursos e do gerente de produtos. Adesivos prontos são colados no quadro, eles definitivamente nos ajudarão.

De volta à história. Examinamos um pedaço de código em que o padrão C ++ 98 coexiste pacificamente com chamadas da biblioteca C. Lembramos que 2018 é o ano e decidimos deixá-lo em paz. Mas como repetir a funcionalidade de trabalhar com máquinas virtuais (VMs), tornando o código mais compacto e conveniente para o trabalho?
Estudamos a questão, entendemos que, independentemente da solução e do idioma escolhido, será um invólucro na biblioteca C. Como uma opção interessante, vale a pena notar que a
biblioteca do Go do DigitalOcean , usa o protocolo RPC para se comunicar diretamente com a libvirt, mas tem suas desvantagens. Nós nos instalamos na
biblioteca Python .
Como resultado, obtivemos a velocidade de escrever código, facilidade de uso e leitura. Vale a pena explicar essas belas palavras.
- Velocidade . Agora, podemos prototipar rapidamente uma certa parte do trabalho com o domínio diretamente do console no servidor de depuração, sem reconstruir o aplicativo principal.
- Simplicidade . Em vez de chamar muitos métodos C ++ em um determinado manipulador, temos uma chamada de script Python com passagem de parâmetro.
- A depuração também é o mais rápida e indolor possível. Na minha opinião, a longo prazo, isso pode trazer uma experiência interessante para o usuário. Imagine, o administrador do sistema, infeliz por suas máquinas virtuais estarem aguardando um desligamento antes da destruição, e redefine o script para o método host_stop.
Também posso escrever um painel para você?
Como resultado, obtivemos uma ferramenta simples e conveniente para trabalhar com máquinas virtuais no nível do servidor.
A segunda história. Um produto bem embalado não precisa de carícias adicionais
Distribuição de produtos: recusamos muitos pacotes e passamos para o Docker

O VMmanager 5 é distribuído como um conjunto de pacotes Linux. O CentOS 6/7 e, até recentemente, o Debian 7. são suportados O que isso significa? Isso significa mais servidores de criação para CI / CD, mais testes e mais atenção ao código. Devemos lembrar que quando no repositório oficial do CentOS 7 qemu versão 1.5.3, no CentOS 6 é 0.12.1. Ao mesmo tempo, o usuário pode usar repositórios nos quais a versão deste pacote é muito maior. Isso significa que você precisa oferecer suporte a diferentes versões da API ao trabalhar com VMs, em particular durante a migração. Devemos lembrar a diferença entre inicializadores (init, systemd), levar em consideração a diferença nos nomes de pacotes e utilitários. Os utilitários que funcionam no CentOS não funcionarão no Debian, ou suas versões nos repositórios oficiais variam amplamente. Para cada push, você precisa coletar pacotes para todas as versões, e é aconselhável não esquecer de testá-los também.
Tudo isso no novo produto não combina conosco. Para não suportar lógica diferente, abandonamos vários sistemas e deixamos apenas o CentOS 7. O problema foi resolvido? Na verdade não.
Também não queremos verificar a versão do sistema operacional antes da instalação, se os utilitários necessários estão disponíveis, quais regras estão instaladas no SELinux e não queremos reconfigurar as listas de firewall e repositório. Gostaria de uma vez - e é tudo, clicando em para
destruir cada segundo para implantar todo o ambiente e o próprio produto. Diz-se - feito, o projeto é embrulhado em um contêiner de encaixe.
Agora basta:
O painel está instalado e funcionando.
É claro que estou exagerando, o usuário deve instalar o Docker por conta própria e temos mais de um contêiner, e atualmente o VMmanager é executado no modo enxame como um serviço SaaS. Sobre o que encontramos ao escolher o Docker e como resolvê-lo, você pode escrever um artigo separado.
O fato em si é o quão importante é simplificar o desenvolvimento e, o mais importante - a implantação do seu produto, install.sh, que ocupava
2097 linhas .
Como resultado:
- Um ambiente de instalação homogêneo do produto simplifica o código do programa e reduz os custos de montagem e teste.
- Distribuir o aplicativo como um contêiner de docker torna a implantação simples e previsível.
A terceira história. Primeiro relacionamento com microsserviços
Arquitetura: abandonamos o monólito em favor dos microsserviços, ou não

A quinta versão do produto é um grande sistema monolítico com o padrão C ++ desatualizado. Como resultado, a implementação problemática de novas tecnologias e a dificuldade de refatorar o código legado, baixa escala horizontal. Na nova filial, eles decidiram usar a abordagem de microsserviço como uma das maneiras de evitar esses problemas.
Os microsserviços são uma tendência moderna que possui vantagens e desvantagens. Tentarei apresentar minha visão dos pontos fortes dessa arquitetura e falar sobre a solução dos problemas que ela traz ao projeto. Vale a pena notar que este será o primeiro olhar para a arquitetura de microsserviço na prática, do lado de um desenvolvedor comum. Aspectos que provavelmente não mencionarei são abordados em um
bom artigo de revisão .
Lado positivo
O serviço pequeno oferece muitas oportunidades.Além da conveniência de escrever, testar e depurar, os microsserviços introduziram uma nova linguagem de programação no projeto. Quando seu projeto é um monólito, é difícil imaginar que um dia você tente reescrever parte dele em outro idioma que lhe interesse. Na arquitetura de microsserviços - por favor. Além da linguagem de programação, você também pode experimentar novas tecnologias, com a única ressalva de que tudo isso será justificado para os negócios. Por exemplo, escrevemos alguns dos microsserviços em Golang, economizando bastante tempo.
Dimensionamento da equipePodemos dividir muitas pessoas que se comprometeram com um repositório e tentaram manter a estrutura do monólito em suas cabeças em várias equipes. Cada equipe estará envolvida em seu serviço. Além disso, a entrada de uma nova pessoa no trabalho é muito mais simples e rápida, devido ao contexto limitado em que ele trabalhará. Por outro lado, há menos agregadores de pessoas do conhecimento mundial, que sempre podem ser descobertos sobre qualquer aspecto de um sistema imenso. Talvez com o tempo eu reconsidere minha atitude a esse respeito.
Degradação independenteEu atribuiria a degradação independente aos lados positivo e negativo dos microsserviços, porque quem precisa do seu aplicativo se, por exemplo, existir um serviço de autorização? No entanto, este ainda é um lado positivo. Anteriormente, a coleta de estatísticas de várias centenas de máquinas virtuais fazia nosso monólito trabalhar duro, no momento do pico de carregamento, a espera por um pedido do usuário aumentava significativamente. Um serviço de coleta de estatísticas separado pode coletá-lo sem afetar outros serviços, enquanto ainda pode ser dimensionado adicionando novo hardware ou aumentando o número de coletores das mesmas estatísticas. E podemos até selecionar um servidor separado para o Graphite, onde este serviço registra estatísticas. Com um monólito, onde há uma base, isso é impossível.
Lado negativo
Contexto da solicitaçãoToda a minha depuração no monólito se resumiu a duas consultas no console:
Feito! Posso acompanhar a solicitação inteira, desde o recebimento até o sistema até que ocorra um erro.
Mas e agora, quando a solicitação viaja do microsserviço para o microsserviço, acompanhada de chamadas adicionais para serviços e registros vizinhos em vários bancos de dados? Para isso, implementamos as informações da solicitação, que contêm o identificador da solicitação e informações sobre o usuário ou serviço que a produziu. Portanto, fica mais fácil rastrear toda a cadeia de eventos, mas o desejo é escrever um serviço de agregação de logs, porque, afinal, temos uma arquitetura de microsserviço. Você também pode procurar o Elasticsearch, esse problema está aberto e será resolvido em breve.
Inconsistência de dadosOs dados nos microsserviços são descentralizados, não há um banco de dados único no qual todas as informações são armazenadas. Ao refletir sobre este artigo, analisei as principais interações entre microsserviços em minha mente - onde podemos obter duplicatas, onde usamos transações entre redes - e percebi que resolvemos o problema de inconsistência com um monólito.
Realmente construímos um monólito com uma base principal, envolvendo a maioria das ações transacionais. E ao redor do monólito foram coletados todos os microsserviços que não afetam a consistência dos dados principais. A exceção é um monte de autorização de serviço + monólito. O problema nesse caso é que o banco de dados do aplicativo base não contém usuários, suas funções e parâmetros adicionais, tudo isso no serviço de autorização.
O usuário do sistema pode trabalhar com máquinas virtuais em um monólito, enquanto no serviço de autorização seus direitos podem mudar ou ele será completamente bloqueado. O sistema deve responder a isso em tempo hábil. Nessa situação, a consistência dos dados é alcançada verificando os parâmetros do usuário antes de executar qualquer solicitação.
Quanto aos microsserviços restantes, a incapacidade de se registrar no serviço de estatísticas não afeta a operação da máquina virtual e essa ação sempre pode ser repetida. Bem, estamos fazendo um microsserviço de coleta de estatísticas. Mas o serviço de domínio define (criando uma máquina virtual usando libvirt) nunca verá a luz, pois quem precisa de um espaço em branco da máquina sem sua existência real.
A quarta história. Fresco é o inimigo do bem
Implantação de VM: instalando a partir de imagens, em vez de instalar através de uma rede
Na quinta versão do produto, a implantação de uma máquina virtual leva muito tempo para padrões reais. O motivo disso é a instalação do sistema operacional pela rede.
Para Centos, Fedora, RedHat é o
método kickstart :
1. Crie um arquivo de kickstart.
2. Especifique o link para o arquivo de resposta nos parâmetros do kernel linux inst.ks = <link para o arquivo kickstart>.
3. Execute a instalação do kickstart.
O arquivo Kickstart é bastante flexível, nele você pode descrever todas as etapas da instalação, começando pelo método e definindo o fuso horário, terminando com o particionamento do disco e a configuração da rede. O parâmetro url em nossos modelos indica que a instalação é de um servidor remoto.
Para Debian e Ubuntu, o método
preseed :
É semelhante ao anterior, esse método também é construído em torno do arquivo de configuração e seu conteúdo. Nele, também configuramos a instalação pela rede.
A instalação do FreeBSD é semelhante, mas em vez de um arquivo kickstart, existe um shell script de nossa própria produção.
Aspectos positivos da abordagem
Esta opção de instalação permite que você use um modelo em nossos dois produtos: VMmanager e
DCImanager (gerenciamento de servidores dedicados).
A implantação de máquinas virtuais é bastante flexível, o administrador do painel pode simplesmente copiar o modelo do sistema operacional e alterar o arquivo de configuração como achar melhor.
Todos os usuários sempre têm versões atualizadas dos sistemas operacionais, se forem atualizados em tempo hábil em um servidor remoto.

Lado negativo
Como a prática demonstrou, os usuários do VMmanager não precisavam de flexibilidade de instalação: em comparação com servidores dedicados, poucas pessoas se preocupavam com configurações específicas de arquivos kickstart para máquinas virtuais. Mas esperar pela instalação do sistema operacional era realmente um luxo inadmissível. O outro lado da relevância dos sistemas operacionais é que parte do instalador está na rede e parte local do
initrd . E suas versões devem corresponder.
Estes são problemas solucionáveis. Você pode criar um pool de máquinas instaladas e criar seu próprio repositório para sistemas operacionais, mas isso implica custos adicionais.
Como resolver esses problemas sem criar repositórios e pools? Selecionamos os arquivos de imagem do sistema operacional. Agora, o processo de instalação fica assim:
1. Copiando a imagem do sistema operacional para o disco da máquina virtual.
2. Aumente a seção principal da imagem pelo tamanho do espaço livre após a cópia.
3. Configuração básica (configuração de senha, fuso horário etc.).
Tudo novo é bem esquecido de idade. Usamos imagens do SO no VDSmanager-Linux, o progenitor do VMmanager.
Mas e a flexibilidade de instalação? A prática mostrou que a maioria dos usuários não está interessada em configurações específicas de rede e mapeamento de disco em máquinas virtuais.
E a relevância dos dados? Isso pode ser alcançado pela presença de imagens com as versões mais recentes do SO no repositório, e pequenas atualizações podem ser instaladas no script de configuração inicial. Assim, a máquina virtual já estará criada e em execução e, para isso, você encontrará a atualização condicional do yum em execução.
Em troca, obtemos uma máquina virtual pronta, cuja implantação depende apenas da cópia do disco, do aumento da partição do disco e da inicialização do sistema operacional. A implementação dessa abordagem para trabalhar com máquinas nos dá a oportunidade de criar nossas próprias imagens e compartilhá-las. O usuário pode instalar um pacote
configurável LAMP ou algum ambiente complexo na máquina virtual e criar uma imagem dessa máquina. Agora, outras pessoas não precisarão perder tempo instalando os utilitários necessários.
Implementamos a configuração e modificação de partições usando os utilitários do
conjunto libguestfs . Por exemplo, alterar uma senha em uma máquina Linux passou de 40 linhas de código, consistindo em mount, chroot e usermod, em uma linha:
command = "/usr/bin/virt-customize --root-password password:{password} --domain '{domain_name}'".format(password=args.password, domain_name=args.domain_name)
Como resultado, conseguimos obter a máquina virtual finalizada o mais rápido possível. Vale ressaltar que, com a configuração da rede e a instalação de scripts internos, o tempo de implantação aumentou um pouco. Resolvemos esse problema exibindo as etapas de instalação no front-end, preenchendo assim a pausa formada entre a criação e a prontidão completa da máquina.
Também tivemos uma abordagem mais flexível para implantar máquinas virtuais, com base nas quais é conveniente criar suas próprias imagens com o ambiente necessário.
O que você conseguiu fazer
Na sexta versão do produto, tentamos levar em consideração a principal desvantagem da quinta: a complexidade da interação do usuário com o produto. Reduzimos o prazo de entrega das principais ações. Juntamente com uma interface sem bloqueio, isso possibilita o trabalho com o painel sem uma espera forçada. A conteinerização tornou o processo de instalação do produto mais fácil e conveniente. O uso de tecnologias modernas e várias linguagens de programação simplificou o suporte e a manutenção para programadores e especialistas em suporte técnico. A mudança para microsserviços permitiu adicionar novos recursos rapidamente e com pequenas restrições.
Concluindo, quero dizer que o novo produto é uma boa oportunidade para tentar outras abordagens de desenvolvimento, novas tecnologias. Vale lembrar por que você está fazendo isso, que novidades isso trará para você e seus usuários. Vá em frente!
Convidamos a comunidade Habr a ver a versão beta do VMmanager 6 e deixar seus comentários. Para fazer isso, acesse my.saasvm.com , faça login e conecte um servidor dedicado (CentOS 7 x64, acesso à Internet, endereço IP público).
Se você não possui um servidor, escreva-nos para help@ispsystem.com ou converse no site , forneceremos equipamentos de teste de nosso parceiro, Selectel.
Leia mais nas notícias no site do ISPsystem .