Southbridge em Chelyabinsk e Bitrix em Kubernetes

Os encontros de administradores de sistema Sysadminka estão acontecendo em Chelyabinsk e, no último deles, apresentei um relatório sobre nossa solução para executar aplicativos em 1C-Bitrix em Kubernetes.

Bitrix, Kubernetes, Ceph – uma ótima mistura?

Vou lhe contar como montamos uma solução funcional para tudo isso.

Vamos lá!

Southbridge em Chelyabinsk e Bitrix em Kubernetes

O encontro aconteceu no dia 18 de abril em Chelyabinsk. Você pode ler sobre nossos encontros em Bloco de tempo e olhe para Youtube.

Se você quiser vir até nós com um relatório ou como ouvinte - seja bem-vindo, escreva para [email protegido] e no Telegram t.me/vadimisakanov.

Meu relatório

Southbridge em Chelyabinsk e Bitrix em Kubernetes

Slides

Solução "Bitrix em Kubernetes, versão Southbridge 1.0"

Falarei sobre nossa solução no formato “for dummies in Kubernetes”, como foi feito no meetup. Mas presumo que você conheça as palavras Bitrix, Docker, Kubernetes, Ceph, pelo menos no nível dos artigos da Wikipedia.

O que está pronto sobre o Bitrix no Kubernetes?

Há muito pouca informação em toda a Internet sobre o funcionamento dos aplicativos Bitrix no Kubernetes.
Só encontrei estes materiais:

Relatório de Alexander Serbul, 1C-Bitrix e Anton Tuzlukov da Qsoft:

Eu recomendo ouvi-lo.

Desenvolvendo sua própria solução a partir do usuário Serkyron em Habré.
Encontrei mais tal decisão.

Eaand... na verdade, isso é tudo.

Aviso, não verificamos a qualidade das soluções dos links acima :)
Aliás, ao preparar nossa solução, conversei com Alexander Serbul, então o relatório dele ainda não havia aparecido, então nos meus slides há um item “Bitrix não usa Kubernetes”.

Mas já existem muitas imagens Docker prontas para executar o Bitrix no Docker: https://hub.docker.com/search?q=bitrix&type=image

Isso é suficiente para criar uma solução completa para Bitrix no Kubernetes?
Não. Há um grande número de problemas que precisam ser resolvidos.

Quais são os problemas do Bitrix no Kubernetes?

Primeiro, imagens prontas do Dockerhub não são adequadas para Kubernetes

Se quisermos construir uma arquitetura de microsserviços (e geralmente fazemos no Kubernetes), precisamos separar nosso aplicativo Kubernetes em contêineres e fazer com que cada contêiner execute uma pequena função (e faça-o bem). Por que apenas um? Resumindo, quanto mais simples, mais confiável.
Para ser mais específico, assista a este artigo e vídeo, por favor: https://habr.com/ru/company/southbridge/blog/426637/

As imagens do Docker no Dockerhub são construídas principalmente com base no princípio tudo-em-um, então ainda tivemos que fazer nossa própria bicicleta e até mesmo criar imagens do zero.

Segundo - o código do site é editado no painel de administração

Criamos uma nova seção no site - o código foi atualizado (foi adicionado um diretório com o nome da nova seção).

Se você alterou as propriedades de um componente no painel de administração, o código mudou.

Kubernetes “por padrão” não pode funcionar com isso; os contêineres devem ser sem estado.

Motivo: cada contêiner (pod) no cluster processa apenas uma parte do tráfego. Se você alterar o código em apenas um contêiner (pod), o código será diferente em diferentes pods, o site funcionará de maneira diferente e diferentes versões do site serão mostradas para diferentes usuários. Você não pode viver assim.

Terceiro - você precisa resolver o problema de implantação

Se tivermos um monólito e um servidor “clássico”, tudo é bastante simples: implantamos uma nova base de código, migramos o banco de dados, transferimos o tráfego para a nova versão do código. A troca ocorre instantaneamente.
Se tivermos um site no Kubernetes dividido em microsserviços, há muitos contêineres com código - ah. Você precisa coletar contêineres com uma nova versão do código, implementá-los em vez dos antigos, migrar corretamente o banco de dados e, de preferência, fazer isso despercebido pelos visitantes. Felizmente, o Kubernetes nos ajuda com isso, oferecendo suporte a vários tipos diferentes de implantações.

Quarto - você precisa resolver o problema de armazenamento de estática

Se o seu site tiver “apenas” 10 gigabytes e você o implantar inteiramente em contêineres, você acabará com contêineres de 10 gigabytes que levarão uma eternidade para serem implantados.
Você precisa armazenar as partes “mais pesadas” do local fora dos contêineres, e surge a dúvida de como fazer isso corretamente

O que está faltando em nossa solução?

Todo o código Bitrix não está dividido em microfunções/microsserviços (de forma que o registro seja separado, o módulo da loja online seja separado, etc.). Armazenamos toda a base de código em cada contêiner.

Também não armazenamos banco de dados em Kubernetes (ainda implementei soluções com banco de dados em Kubernetes para ambientes de desenvolvimento, mas não para produção).

Ainda será perceptível para os administradores do site que o site é executado no Kubernetes. A função “verificação do sistema” não funciona corretamente, para editar o código do site no painel de administração, você deve primeiro clicar no botão “Quero editar o código”.

Os problemas foram identificados, a necessidade de implementação de microsserviços foi determinada, o objetivo é claro - obter um sistema funcional para execução de aplicações no Bitrix no Kubernetes, preservando tanto as capacidades do Bitrix quanto as vantagens do Kubernetes. Vamos começar a implementação.

Arquitetura

Existem muitos pods “funcionais” com um servidor web (trabalhadores).
Um abaixo com tarefas cron (apenas uma é necessária).
Uma atualização para editar o código do site no painel de administração (também é necessária apenas uma).

Southbridge em Chelyabinsk e Bitrix em Kubernetes

Resolvemos questões:

  • Onde armazenar sessões?
  • Onde armazenar o cache?
  • Onde armazenar estática, para não colocar gigabytes de estática em vários contêineres?
  • Como funcionará o banco de dados?

Imagem do Docker

Começamos construindo uma imagem Docker.

A opção ideal é que tenhamos uma imagem universal, com base nela obtemos pods de trabalho, pods com Crontasks e pods de atualização.

Fizemos exatamente essa imagem.

Inclui nginx, apache/php-fpm (pode ser selecionado durante a construção), msmtp para envio de e-mail e cron.

Ao montar a imagem, toda a base de código do site é copiada para o diretório /app (com exceção das partes que moveremos para um armazenamento compartilhado separado).

Microsserviços, serviços

pods de trabalho:

  • Contêiner com nginx + contêiner apache/php-fpm + msmtp
  • Não funcionou mover o msmtp para um microsserviço separado, o Bitrix está começando a ficar indignado por não poder enviar e-mails diretamente
  • Cada contêiner possui uma base de código completa.
  • Proibição de alteração de código em containers.

cron em:

  • contêiner com apache, php, cron
  • base de código completa incluída
  • proibição de alteração de código em contêineres

atualização em:

  • contêiner nginx + contêiner apache/php-fpm + msmtp
  • Não há proibição de alteração de código em contêineres

armazenamento de sessão

Armazenamento em cache Bitrix

Outra coisa importante: armazenamos senhas para conexão de tudo, do banco de dados ao correio, nos segredos do Kubernetes. Ganhamos um bônus: as senhas ficam visíveis apenas para aqueles a quem damos acesso aos segredos, e não para todos que têm acesso à base de código do projeto.

Armazenamento para estática

Você pode usar qualquer coisa: ceph, nfs (mas não recomendamos nfs para produção), armazenamento de rede de provedores de nuvem, etc.

O armazenamento precisará estar conectado em contêineres ao diretório /upload/ do site e outros diretórios com conteúdo estático.

Banco de dados

Para simplificar, recomendamos mover o banco de dados para fora do Kubernetes. A base no Kubernetes é uma tarefa complexa separada; tornará o esquema uma ordem de magnitude mais complexo.

Armazenamento de sessão

Usamos memcached :)

Ele lida bem com o armazenamento de sessões, é agrupado e tem suporte “nativo” como session.save_path em php. Tal sistema foi testado diversas vezes na arquitetura monolítica clássica, quando construímos clusters com um grande número de servidores web. Para implantação usamos helm.

$ helm install stable/memcached --name session

php.ini - aqui a imagem contém configurações para armazenar sessões no memcached

Usamos variáveis ​​de ambiente para passar dados sobre hosts com memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Isso permite que você use o mesmo código nos ambientes de desenvolvimento, estágio, teste e produção (os nomes de host do memcached neles serão diferentes, portanto, precisamos passar um nome de host exclusivo para sessões para cada ambiente).
Armazenamento em cache Bitrix

Precisamos de armazenamento tolerante a falhas onde todos os pods possam gravar e ler.

Também usamos memcached.
Esta solução é recomendada pelo próprio Bitrix.

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php - aqui no Bitrix é especificado onde o cache é armazenado

Também usamos variáveis ​​de ambiente.

Krontaski

Existem diferentes abordagens para executar Crontasks no Kubernetes.

  • implantação separada com um pod para executar Crontasks
  • cronjob para executar crontasks (se este for um aplicativo web - com wget https://$host$cronjobname, ou kubectl exec dentro de um dos pods de trabalho, etc.)
  • etc.

Você pode argumentar sobre o mais correto, mas neste caso escolhemos a opção “implantação separada com pods para Crontasks”

Como isso é feito:

  • adicione tarefas cron via ConfigMap ou através do arquivo config/addcron
  • em uma instância, lançamos um contêiner idêntico ao pod de trabalho + permitimos a execução de tarefas coroa nele
  • a mesma base de código é usada, graças à unificação, a montagem do contêiner é simples

Que bom obtemos:

  • temos Crontasks funcionando em um ambiente idêntico ao ambiente dos desenvolvedores (docker)
  • Crontasks não precisam ser “reescritos” para Kubernetes, eles funcionam da mesma forma e na mesma base de código de antes
  • tarefas cron podem ser adicionadas por todos os membros da equipe com direitos de commit na ramificação de produção, não apenas pelos administradores

Módulo Southbridge K8SDeploy e edição de código no painel de administração

Estávamos falando sobre atualização em?
Como direcionar o tráfego para lá?
Viva, escrevemos um módulo para isso em PHP :) Este é um pequeno módulo clássico para Bitrix. Ainda não está disponível publicamente, mas planejamos abri-lo.
O módulo é instalado como um módulo normal no Bitrix:

Southbridge em Chelyabinsk e Bitrix em Kubernetes

E fica assim:

Southbridge em Chelyabinsk e Bitrix em Kubernetes

Ele permite que você defina um cookie que identifica o administrador do site e permite que o Kubernetes envie tráfego para o pod de atualização.

Quando as alterações forem concluídas, você precisa clicar em git push, as alterações no código serão enviadas para o git, então o sistema construirá uma imagem com uma nova versão do código e a “distribuirá” pelo cluster, substituindo os pods antigos .

Sim, é uma espécie de muleta, mas ao mesmo tempo mantemos a arquitetura de microsserviços e não tiramos dos usuários do Bitrix sua oportunidade favorita de corrigir o código do painel de administração. No final das contas, isso é uma opção; você pode resolver o problema de edição do código de uma forma diferente.

Gráfico do leme

Para construir aplicativos no Kubernetes, normalmente usamos o gerenciador de pacotes Helm.
Para nossa solução Bitrix em Kubernetes, Sergey Bondarev, nosso administrador de sistema líder, escreveu um gráfico Helm especial.

Ele cria pods de trabalho, ugrade e cron, configura entradas, serviços e transfere variáveis ​​de segredos do Kubernetes para pods.

Armazenamos o código no Gitlab e também executamos a construção do Helm no Gitlab.

Resumindo, parece assim

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

O Helm também permite que você faça uma reversão “perfeita” se algo der errado repentinamente durante a implantação. É bom quando você não está em pânico “conserte o código via ftp porque o produto caiu”, mas o Kubernetes faz isso automaticamente e sem tempo de inatividade.

Implantar

Sim, somos fãs do Gitlab e do Gitlab CI, nós o usamos :)
Ao fazer commit no Gitlab para o repositório do projeto, o Gitlab lança um pipeline que implanta uma nova versão do ambiente.

Estágios:

  • build (construindo uma nova imagem Docker)
  • teste (teste)
  • limpar (removendo o ambiente de teste)
  • push (enviamos para o registro do Docker)
  • implantar (implantamos o aplicativo no Kubernetes via Helm).

Southbridge em Chelyabinsk e Bitrix em Kubernetes

Viva, está pronto, vamos implementar!
Bem, ou faça perguntas, se houver.

Então, o que nós fizemos

Do ponto de vista técnico:

  • Bitrix dockerizado;
  • “cortar” o Bitrix em contêineres, cada um executando um mínimo de funções;
  • alcançou o estado sem estado dos contêineres;
  • resolveu o problema de atualização do Bitrix no Kubernetes;
  • todas as funções do Bitrix continuaram funcionando (quase todas);
  • Trabalhamos na implantação no Kubernetes e no rollback entre versões.

Do ponto de vista empresarial:

  • tolerância ao erro;
  • Ferramentas Kubernetes (fácil integração com Gitlab CI, implantação contínua, etc);
  • senhas secretas (visíveis apenas para aqueles que têm acesso direto às senhas);
  • É conveniente criar ambientes adicionais (para desenvolvimento, testes, etc.) dentro de uma única infraestrutura.

Fonte: habr.com

Adicionar um comentário