Padrões de armazenamento Kubernetes


Olá Habr!

Lembramos que lançamos outro livro extremamente interessante e útil sobre os padrões do Kubernetes. Tudo começou com “ Patterns ” de Brendan Burns e, a propósito, o trabalho nesse segmento está em pleno andamento . Hoje, convidamos você a ler um artigo do blog do MinIO que resume as tendências e especificidades dos padrões de armazenamento de dados no Kubernetes.


Kubernetes mudou fundamentalmente os padrões tradicionais de desenvolvimento e implantação de aplicativos. Agora, a equipe pode levar dias para desenvolver, testar e implantar o aplicativo - em diferentes ambientes e tudo isso nos clusters do Kubernetes. Esse trabalho com a tecnologia de gerações anteriores geralmente levava semanas, se não meses.

Essa aceleração foi possível graças à abstração fornecida pelo Kubernetes - ou seja, devido ao fato de o próprio Kubernetes interagir com detalhes de baixo nível de máquinas físicas ou virtuais, permitindo que os usuários declarem, entre outros parâmetros, o processador desejado, a memória necessária, o número de instâncias de contêiner. Como o Kubernetes é suportado por uma enorme comunidade e o escopo do Kubernetes está em constante expansão, ele lidera por uma ampla margem entre todas as plataformas de orquestração de contêineres.

À medida que o uso do Kubernetes se expande, também aumenta a confusão sobre os padrões de armazenamento usados ​​nele .

Com a competição geral por um pedaço de torta Kubernetes (isto é, para armazenamento de dados), quando se trata de falar sobre armazenamento de dados, o sinal está se afogando em barulho alto.
O Kubernetes incorpora um modelo moderno para desenvolver, implantar e gerenciar aplicativos. Um modelo tão moderno desconecta o armazenamento de dados da computação. Para entender completamente esse desapego no contexto do Kubernetes, você também precisa entender o que são aplicativos com estado e sem estado e como o armazenamento de dados é combinado com isso. É aqui que a abordagem da API REST usada pelo S3 tem vantagens claras sobre a abordagem POSIX / CSI, típica de outras soluções.

Neste artigo, falaremos sobre padrões de armazenamento no Kubernetes e discutiremos separadamente o debate sobre aplicativos sem estado e sem estado, para que possamos entender claramente a diferença entre eles e por que é importante. Além disso, consideraremos os aplicativos e os padrões de armazenamento de dados usados ​​neles à luz das práticas recomendadas para trabalhar com contêineres e Kubernetes.

Contêineres sem estado


Os contêineres são inerentemente leves e efêmeros. Eles podem ser facilmente parados, excluídos ou implantados em outro nó - tudo isso leva alguns segundos. Em um grande sistema de orquestração de contêineres, essas operações ocorrem continuamente e os usuários nem percebem essas alterações. No entanto, os movimentos são possíveis apenas se o contêiner não tiver dependências no nó em que está localizado. Diz-se que esses contêineres funcionam sem preservação do estado .

Stateful Containers


Se o contêiner armazenar dados em dispositivos conectados localmente (ou em um dispositivo de bloco), o armazém de dados em que está localizado terá que ser movido para um novo nó junto com o próprio contêiner - em caso de falha. Isso é importante, porque, caso contrário, o aplicativo em execução no contêiner não poderá funcionar corretamente, pois precisa acessar os dados armazenados na mídia local. Dizem que esses contêineres são stateful .

Do ponto de vista puramente técnico, os containers com estado também podem ser movidos para outros nós. Normalmente, isso é conseguido usando sistemas de arquivos distribuídos ou bloquear armazenamentos de rede conectados a todos os nós nos quais os contêineres operam. Assim, os contêineres obtêm acesso aos volumes para armazenamento persistente de dados e as informações são armazenadas em discos localizados em toda a rede. Chamarei esse método de “ abordagem de contêiner de preservação do estado ” e no restante do artigo chamarei por uma questão de uniformidade.



Em uma abordagem típica de contêiner com estado, todos os pods de aplicativos são anexados a um sistema de arquivos distribuído - um tipo de armazenamento compartilhado é obtido, onde todos os dados do aplicativo são adquiridos. Embora algumas variações sejam possíveis, essa é uma abordagem de alto nível.

Agora, vamos ver por que a abordagem de contêiner com estado no mundo baseado em nuvem é antipadrão.

Design de aplicativo baseado em nuvem


Tradicionalmente, os aplicativos usavam bancos de dados para armazenamento estruturado de informações e discos locais ou sistemas de arquivos distribuídos, onde todos os dados não estruturados ou semiestruturados eram despejados. À medida que o volume de dados não estruturados aumentou, os desenvolvedores perceberam que o POSIX era muito falador, associado a custos significativos e, por fim, interfere no aplicativo ao passar para uma escala realmente grande.

Isso contribuiu principalmente para o surgimento de um novo padrão para armazenamento de dados, ou seja, armazenamentos baseados em nuvem que funcionam principalmente com base na API REST e liberam o aplicativo da manutenção onerosa do armazém de dados local. Nesse caso, o aplicativo realmente entra no modo de operação sem salvar o estado (já que o estado está no armazenamento remoto). Aplicativos modernos estão sendo construídos do zero, já levando esse fator em consideração. Como regra, qualquer aplicativo moderno que processe dados de um tipo ou de outro (logs, metadados, blobs etc.) é construído em um paradigma orientado à nuvem, em que o estado é transferido para um sistema de software especialmente alocado para seu armazenamento.

Uma abordagem stateful de contêiner faz todo esse paradigma reverter exatamente para onde começou!

Ao usar interfaces POSIX para armazenar dados, os aplicativos funcionam da mesma maneira como se mantivessem o estado e, por isso, afastam-se dos postulados mais importantes do design baseado em nuvem, ou seja, da capacidade de variar o tamanho dos fluxos de trabalho do aplicativo, dependendo da entrada. carregar, vá para um novo nó assim que o nó atual falhar e assim por diante.

Uma análise mais detalhada dessa situação revela que, ao escolher um data warehouse, enfrentamos repetidamente o dilema “API POSIX versus REST”, mas com agravamento adicional dos problemas do POSIX causados ​​pela natureza distribuída dos ambientes Kubernetes. Em particular,

  • POSIX : POSIX , . , . API , , S3 API, , , «» . , . .
  • : , , . , , ( ), , . - POSIX . , S3 API , , , .
  • : POSIX : . - . , API, , , ..
  • : , . , , , . , , , .


Enquanto a interface de armazenamento de dados do contêiner (CSI) ajudou muito na distribuição do nível de volume do Kubernetes, passando-o parcialmente para fornecedores de data warehouse de terceiros, mas também contribuiu acidentalmente para a convicção de que a abordagem de contêiner com estado era o método recomendado de armazenamento de dados no Kubernetes.

O CSI foi desenvolvido como padrão para fornecer sistemas arbitrários de armazenamento de blocos e arquivos para aplicativos legados ao trabalhar com o Kubernetes. E, como foi mostrado neste artigo, a única situação em que uma abordagem de contêiner com estado (e CSI em sua forma atual) é apropriada é quando o próprio aplicativo é um sistema legado no qual é impossível adicionar suporte à API de armazenamento de dados do objeto.

É importante entender que, ao usar o CSI em sua forma atual, ou seja, ao montar volumes ao trabalhar com aplicativos modernos, encontraremos aproximadamente os mesmos problemas encontrados nos sistemas em que o armazenamento de dados é organizado no estilo POSIX.

Melhor abordagem


Nesse caso, é importante entender que a maioria dos aplicativos não é inerentemente aprimorada especificamente para trabalhar com ou sem preservação de estado. Esse comportamento depende da arquitetura geral do sistema e das opções específicas selecionadas durante o design. Vamos falar um pouco sobre aplicativos com estado.

Em princípio, todos os dados do aplicativo podem ser divididos em vários tipos amplos:

  • Dados de log
  • Dados do carimbo de data / hora
  • Dados de transação
  • Metadados
  • Imagens de contêiner
  • Dados de blob (blobs)

Todos esses tipos de dados são muito bem suportados em plataformas modernas de armazenamento de dados e existem várias plataformas baseadas na nuvem adaptadas para fornecer dados em cada um desses formatos específicos. Por exemplo, dados e metadados de transação podem residir em um banco de dados moderno baseado em nuvem, como CockroachDB, YugaByte, etc. Imagens de contêiner ou dados de blob podem ser armazenados no registro da janela de encaixe com base no MinIO. Os dados do registro de data e hora podem ser armazenados em um banco de dados de séries temporais, como o InfluxDB, etc. Não entraremos em detalhes de cada tipo de dados e aplicativos relacionados, mas a idéia geral é evitar o armazenamento persistente de dados com base na montagem do disco local.



Além disso, muitas vezes é eficaz fornecer uma camada de cache temporária, que serve como um tipo de armazenamento temporário de arquivos para aplicativos, mas os aplicativos não devem depender desse nível como fonte de verdade.

Armazenamento de aplicativos com estado


Embora na maioria dos casos seja útil manter os aplicativos sem estado, os aplicativos projetados para armazenar dados - por exemplo, bancos de dados, armazenamento de objetos, armazenamento de chave e valor - devem manter o estado. Vamos ver por que esses aplicativos são implantados no Kubernetes. Tome o MinIO como exemplo, mas princípios semelhantes se aplicam a qualquer outro grande sistema de armazenamento baseado em nuvem.

Os aplicativos centralizados na nuvem são projetados para maximizar o uso da flexibilidade inerente aos contêineres. Isso significa que eles não fazem suposições sobre o ambiente em que serão implantados. Por exemplo, o MinIO usa um mecanismo de codificação de apagamento interno, que fornece ao sistema estabilidade suficiente para permanecer operacional, mesmo que metade das unidades falhe. O MinIO também gerencia a integridade e a segurança dos dados usando seu próprio hash e criptografia no servidor.

Para esses aplicativos baseados na nuvem, os volumes persistentes locais (PV) são mais convenientes como armazenamento de backup. O PV local fornece a capacidade de armazenar dados brutos, enquanto os aplicativos executados sobre esses PVs coletam informações de forma independente para dimensionar dados e gerenciar requisitos crescentes de dados.

Essa abordagem é muito mais simples e escalável significativamente melhor em comparação com o PV baseado em CSI, que traz seus próprios níveis de gerenciamento de dados e redundância ao sistema; o fato é que esses níveis geralmente entram em conflito com aplicativos projetados de acordo com o princípio da preservação do estado.

Movimento confiante para desvincular dados da computação


Neste artigo, falamos sobre como os aplicativos são reorientados para funcionar sem salvar o estado ou, em outras palavras, o armazenamento de dados é delimitado pela computação neles. Em conclusão, consideramos alguns exemplos reais dessa tendência.

O Spark , a renomada plataforma de análise de dados, tem sido tradicionalmente usada com implantação e implantação com estado no sistema de arquivos HDFS. No entanto, à medida que o Spark faz a transição para um mundo baseado em nuvem, essa plataforma está sendo cada vez mais usada sem preservação de estado usando o `s3a`. O Spark usa s3a para transferir o estado para outros sistemas, enquanto os contêineres do Spark funcionam totalmente sem preservação do estado. Outros grandes players corporativos no campo da análise de big data, em particular Vertica , Teradata, Greenplum também vai trabalhar com a divisão de armazenamento de dados e computação sobre eles.

Padrões semelhantes também podem ser vistos em outras grandes plataformas analíticas, incluindo Presto, Tensorflow para R, Jupyter. O estado de upload para sistemas de armazenamento em nuvem remotos facilita muito o gerenciamento e o dimensionamento de seu aplicativo. Além disso, ajuda a portabilidade do aplicativo para uma variedade de ambientes.

All Articles