Os bancos de dados vivem no Kubernetes?

Os bancos de dados vivem no Kubernetes?

Historicamente, a indústria de TI se divide em dois campos, aqueles que estão "a favor" e aqueles que estão "contra". E o tema das discussões pode ser absolutamente arbitrário. Qual sistema operacional é melhor: Windows ou Linux? Usar Android ou iOS no smartphone? Armazenar tudo na nuvem ou utilizar datacenters RAID frios e guardar os discos em um cofre? Os programadores PHP têm o direito de se chamar de programadores? Esses debates, às vezes, têm um caráter exclusivamente existencial e não têm base além do interesse esportivo.

Assim, com o surgimento dos containers e de todo esse universo que adoramos com Docker e o Kubernetes, começaram as discussões "a favor" e "contra" o uso de novas possibilidades em diversas áreas do backend. (Adiantamos que, embora na maioria das vezes o Kubernetes seja citado como orquestrador, a escolha deste instrumento em particular não é fundamental. Você pode substituí-lo por qualquer outro que achar mais conveniente e familiar.)

E, à primeira vista, poderia parecer uma simples discussão entre dois lados da mesma moeda. Assim como a eterna rivalidade entre Windows e Linux, na qual pessoas razoáveis existem em algum lugar no meio. Porém, no caso da containerização, as coisas não são tão simples. Geralmente, nesses debates não há um lado certo, mas no caso de "usar" ou "não usar" containers para armazenar bancos de dados, tudo se inverte. Porque, em certo sentido, tanto os defensores quanto os opositores desse abordagem estão corretos.

Lado Luminoso

Podemos resumir a argumentação do Lado Luminoso em uma frase: “Ei, 2019 está aí!” Soa como populismo, sem dúvida, mas se olharmos a situação em detalhe, há seus benefícios. Vamos analisar esses pontos agora.

Suponhamos que você tenha um grande projeto web. Ele pode ter sido inicialmente construído com base em uma abordagem de microsserviços, ou pode ter chegado a essa arquitetura de forma evolutiva — isso, na verdade, não é muito importante. Você dividiu nosso projeto em microsserviços separados, configurou a orquestração, o balanceamento de carga e a escalabilidade. E agora, com a consciência tranquila, você está tomando um mojito na rede enquanto desfruta dos efeitos dos hacks, em vez de precisar reiniciar servidores que caíram. Mas em todas as ações, é preciso ter consistência. Muito frequentemente, apenas o próprio aplicativo — o código — é conteinerizado. E o que mais temos além do código?

Correto, os dados. O coração de qualquer projeto são seus dados: isso pode ser desde um banco de dados típico — MySQL, PostgreSQL, MongoDB — até fontes de armazenamento utilizadas para busca (ElasticSearch), ou armazenamento key-value para cache — por exemplo, Redis, etc. Neste momento, não vamos falar sobre as implementações problemáticas de backend, onde o banco de dados cai devido a consultas mal escritas, mas sim sobre como garantir a resiliência desse banco de dados sob a carga do cliente. Afinal, quando conteinerizamos nosso aplicativo e permitimos que ele escale livremente para lidar com qualquer quantidade de solicitações recebidas, isso necessariamente aumenta também a carga sobre o banco de dados.

Na verdade, o canal de acesso ao banco de dados e o servidor em que ele está rodando se tornam o gargalo em nosso maravilhoso backend containerizado. O principal motivo da virtualização por contêiner é a mobilidade e flexibilidade da estrutura, permitindo organizar a distribuição da carga máxima em toda a infraestrutura disponível da forma mais eficiente possível. Ou seja, se não containerizarmos e não distribuirmos todos os elementos do sistema pelo cluster — estamos cometendo um erro muito sério.

É muito mais lógico agrupar não apenas o próprio aplicativo, mas também os serviços responsáveis pelo armazenamento de dados. Ao implementar e implantar servidores web independentes que distribuam a carga entre si no k8s, já resolvemos o problema de sincronização de dados — como os comentários em postagens, se pegarmos como exemplo algum meio de comunicação ou plataforma de blogs. De qualquer forma, criamos uma representação interna da base de dados, mesmo que virtual, como ExternalService. A questão é que a própria base de dados ainda não está agrupada — os servidores web implantados no cluster obtêm informações sobre as mudanças da nossa base de dados estática que funciona separadamente.

Sente uma pegadinha? Usamos k8s ou Swarm para distribuir a carga e evitar a queda do principal servidor web, mas não fazemos isso para a base de dados. Contudo, se a base de dados cair, toda a nossa infraestrutura agrupada perde o sentido — de que adianta páginas web vazias que retornam um erro de acesso à base de dados?

É precisamente por isso que a agrupação deve envolver não apenas os servidores web, como é normalmente feito, mas também a infraestrutura da base de dados. Apenas assim podemos garantir uma estrutura que funciona plenamente em uma única unidade, mas ainda assim independente umas das outras. Mesmo que metade do nosso backend “desmorone” sob carga — o restante sobreviverá, e o sistema de sincronização da base de dados entre si dentro do cluster, junto com a possibilidade de escalonamento infinito e implantação de novos clusters, ajudará a alcançar rapidamente as capacidades necessárias — se houver racks no datacenter.

Além disso, o modelo de base de dados distribuída em clusters permite levar essa mesma base de dados para onde ela é necessária; se estamos falando de um serviço global, é bastante ilógico operar um cluster web em algum lugar na área de São Francisco e ao mesmo tempo trafegar pacotes ao acessar a base de dados na região de Moscou e voltar.

Além disso, a containerização da base de dados permite construir todos os elementos do sistema em um mesmo nível de abstração. Isso, por sua vez, possibilita gerenciar esse sistema diretamente do código, pelos desenvolvedores, sem a necessidade de envolver ativamente os administradores. Os desenvolvedores perceberam que precisavam de um SGBD separado para um novo subprojeto — fácil! Criaram um arquivo yaml, carregaram no cluster, e tudo pronto.

E, claro, a operação interna torna-se muito mais fácil. Diga-me, quantas vezes você fechou os olhos quando um novo membro da equipe tentou acessar o banco de dados de produção? Que, na verdade, é o único que você tem e que está rodando agora mesmo? Claro, todos nós somos adultos aqui, e temos um backup recente em algum lugar, e ainda mais atrás — atrás da prateleira com os pepinos da avó e os esquis antigos — um outro backup, possivelmente até em armazenamento frio, porque uma vez seu escritório pegou fogo. Mas, mesmo assim, cada entrada de um novo membro da equipe que tem acesso à infraestrutura de produção e, claro, ao banco de dados de produção é um balde de Valium para todos ao redor. Quem conhece esse novato? E se ele for desastrado? É assustador, concorda?

A conteinerização e, na verdade, a topologia física distribuída do seu banco de dados ajudam a evitar esses momentos de estresse. Você não confia no novato? Ok! Vamos criar um cluster próprio para ele trabalhar e desconectá-lo dos outros clusters de banco de dados — a sincronização será apenas por push manual e a ativação simultânea de duas chaves (uma para o líder da equipe e a outra para o admin). E todos ficam felizes.

Agora é hora de mudar de ideia em relação à clusterização do banco de dados.

Lado Sombrio

Refletindo sobre por que não se deve conteinerizar o banco de dados e continuar a operá-lo em um único central servidor, não vamos nos rebaixar a retóricas de ortodoxos e afirmações do tipo "nossos antecessores operavam bancos de dados em hardware, e nós iremos fazer o mesmo!" Em vez disso, vamos tentar imaginar uma situação em que a conteinerização realmente traria dividendos significativos.

Concorde que os projetos que realmente precisam de um banco de dados em contêiner podem ser contados com os dedos de uma mão, mesmo que não muito habilidosa. Na maioria dos casos, até mesmo o uso de k8s ou Docker Swarm se mostra excessivo — muitas vezes, essas ferramentas são usadas pela popularidade geral das tecnologias e pela pressão de diretores para jogar tudo nas nuvens e em contêineres. Porque agora isso está na moda e todo mundo está fazendo isso.

Em pelo menos metade dos casos, o uso do Kubernetes ou simplesmente do Docker em um projeto é desnecessário. A questão é que nem todas as equipes ou empresas de outsourcing contratadas para gerenciar a infraestrutura do cliente têm plena consciência disso. Pior ainda, quando os contêineres são impostos, pois isso se torna um custo considerável para o cliente.

De modo geral, existe a opinião de que a mafia do Docker/Kubernetes simplesmente subjuga os clientes que delegam essas questões de infraestrutura para o outsourcing. Afinal, para trabalhar com clusters, são necessários engenheiros que compreendam isso e a arquitetura da solução implementada. Nós já comentamos sobre nosso caso com a publicação Republic — lá, treinamos a equipe do cliente a trabalhar nas realidades do Kubernetes, e todos ficaram satisfeitos. E foi um trabalho honesto. Muitas vezes, os 'implementadores' do Kubernetes sequestram a infraestrutura do cliente — agora, apenas eles entendem como tudo funciona, enquanto do lado do cliente não há especialistas.

Agora imagine que estamos entregando não apenas a parte do servidor web, mas também a manutenção do banco de dados ao outsourcing. Já dissemos que o banco de dados é o coração, e a perda do coração é fatal para qualquer organismo vivo. Resumindo, as perspectivas não são as melhores. Portanto, em vez do hype em torno do Kubernetes, muitos projetos deveriam simplesmente investir em um plano adequado na AWS, que resolveria todos os problemas de carga em seus sites/projetos. Mas a AWS já não é mais tendência, e a aparência custa mais do que o dinheiro — infelizmente, isso também se aplica ao setor de TI.

Ok. Talvez a clusterização realmente seja necessária para o projeto, mas se a questão das aplicações stateless está clara, como então organizar uma conexão de rede adequada para um banco de dados clusterizado?

Quando falamos sobre a solução de engenharia sem costura que representa a transição para o k8s, a nossa maior preocupação é a replicação de dados em um banco de dados clusterizado. Alguns SGBDs têm uma abordagem bastante flexível em relação à distribuição de dados entre suas instâncias. No entanto, muitos outros não são tão receptivos. E, frequentemente, o principal argumento na escolha do SGBD para nosso projeto não é a capacidade de replicação com o mínimo de recursos e custos de engenharia. Especialmente se o projeto não foi inicialmente planejado como microserviço e simplesmente evoluiu nessa direção.

Acreditamos que não é necessário falar sobre a velocidade dos discos de rede — eles são lentos. Ou seja, não temos a real possibilidade de, caso necessário, reiniciar a instância do SGBD em algum lugar onde haja mais, por exemplo, poder de processamento ou memória RAM livre. Rapidamente esbarramos na performance do subsistema de disco virtualizado. Portanto, o SGBD deve estar vinculado ao seu próprio conjunto pessoal de máquinas, localizadas nas proximidades. Ou então precisamos encontrar uma maneira de garantir uma sincronização de dados suficientemente rápida com as reservas planejadas.

Continuando o assunto dos sistemas de arquivos virtuais: os Docker Volumes, infelizmente, não são isentos de problemas. De modo geral, em questões de armazenamento de dados confiável e de longo prazo, gostaríamos de utilizar esquemas tecnicamente simples. E a adição de uma nova camada de abstração do sistema de arquivos do contêiner para o sistema de arquivos do host pai — isso por si só já é um risco. Mas quando ainda surgem dificuldades na operação do sistema de contêinerização em transmitir dados entre essas camadas, a situação se complica ainda mais. No momento, a maioria dos problemas conhecidos pela humanidade parece ter sido resolvida. Mas vocês entendem, quanto mais complexo o mecanismo, mais simples ele se quebra.

À luz de todas essas "aventuras", é muito mais vantajoso e simples manter o banco de dados em um único lugar, e mesmo que você precise da containerização da aplicação — deixe-a rodar sozinha e, através de um gateway de distribuição, receba a conexão simultânea com o banco de dados, que será lido e escrito apenas uma vez e em um só lugar. Essa abordagem reduz a probabilidade de erros e desincronizações a níveis mínimos.

A que estamos nos referindo? Ao fato de que a containerização de bancos de dados é apropriada quando existe uma necessidade real. Não se pode simplesmente empacotar um banco de dados de um aplicativo completo e fazê-lo rodar como se você tivesse uma dúzia de microsserviços — isso não funciona assim. E é preciso entender isso claramente.

Em vez de uma conclusão

Se você espera uma conclusão clara sobre "virtualizar ou não o banco de dados", lamentamos: não a terá aqui. Porque ao criar qualquer solução de infraestrutura, deve-se seguir não as modas e o progresso, mas, primeiramente, o bom senso.

Existem projetos para os quais os princípios e ferramentas que vêm com o Kubernetes se encaixam perfeitamente, e nesses projetos a paz se estabelece pelo menos na área de backend. E há projetos que precisam não de containerização, mas de uma infraestrutura de servidor adequada, porque eles não conseguem fundamentalmente se reescalar para um modelo de cluster de microsserviços, pois isso causaria falhas.

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