Os administradores de sistema da Sysadminka se reúnem em Chelyabinsk e, finalmente, fiz um relatório sobre a nossa solução para aplicativos de trabalho no 1C-Bitrix em Kubernetes.
Bitrix, Kubernetes, Ceph - uma ótima mistura?
Vou lhe contar como montamos uma solução funcional para tudo isso.
Vamos lá!

O Mitap foi realizado em 18 de abril em Chelyabinsk. Você pode ler sobre nossas mitaps no Timepad e assistir no YouTube .
Se você deseja nos apresentar um relatório ou como ouvinte - para Wellcome, escreva para vadim.isakanov@gmail.com e Telegram t.me/vadimisakanov.
Meu relatório

Slides
Bitrix na solução Kubernetes Southbridge 1.0
Vou falar sobre a nossa solução no formato "para manequins no Kubernetes", como foi feito na reunião. Mas suponho que as palavras Bitrix, Docker, Kubernetes, Ceph sejam conhecidas pelo menos no nível dos artigos da Wikipedia.
O que você tem sobre o Bitrix no Kubernetes?
Em toda a Internet, há muito pouca informação sobre a operação de aplicativos no Bitrix no Kubernetes.
Encontrei apenas esses materiais:
Relatório de Alexander Serbul, 1C-Bitrix e Anton Tuzlukov, da Qsoft:
Eu recomendo ouvi-lo.
Desenvolvimento de solução própria do usuário serkyron em Habré .
Eu também encontrei essa solução .
III ... na verdade.
Aviso, não verificamos a qualidade das soluções usando os links acima :-)
Aliás, ao preparar nossa solução, conversei com Alexander Serbul, então o relatório dele ainda não estava, então nos meus slides existe o item “Bitrix não usa Kubernetes”.
Mas já existem muitas imagens prontas do Docker para o Bitrix funcionar no Docker: https://hub.docker.com/search?q=bitrix&type=image
Isso é suficiente para criar uma solução completa do Bitrix no Kubernetes?
Não. Há um grande número de problemas que precisam ser resolvidos.
Quais são os problemas com o Bitrix no Kubernetes?
Primeiro - imagens prontas para o Dockerhub não são adequadas para o Kubernetes
Se queremos construir uma arquitetura de microsserviço (e no Kubernetes geralmente queremos), o aplicativo no Kubernetes precisa ser dividido em contêineres e garantir que cada contêiner execute uma pequena função (e faz isso bem). Por que apenas um? Em suma - quanto mais simples, mais confiável.
Se for mais autêntico, veja este artigo e vídeo: https://habr.com/en/company/southbridge/blog/426637/
As imagens do Docker no Dockerhub são construídas principalmente com base no princípio de "tudo em um", portanto ainda tínhamos que fabricar nossa própria bicicleta e até fazer 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 (um diretório com o nome da nova seção foi adicionado).
Alteradas as propriedades do componente no painel de administração - o código foi alterado.
O Kubernetes “por padrão” não sabe como trabalhar com isso, os contêineres devem ser sem estado.
Razão: cada contêiner (sub) no cluster processa apenas parte do tráfego. Se você alterar o código em apenas um contêiner (inferior), em diferentes pods o código será diferente, o site funcionará de maneira diferente, diferentes versões do site serão mostradas para diferentes usuários. Você não pode viver assim.
Terceiro - você precisa resolver o problema da implantação
Se temos um servidor monolítico e um servidor "clássico", tudo é muito simples: implantamos uma nova base de código, migramos o banco de dados, mudamos o tráfego para a nova versão do código. A troca ocorre instantaneamente.
Se temos um site no Kubernetes, ele é visto em microsserviços, existem muitos contêineres com código. Você precisa coletar contêineres com a nova versão do código, distribuí-los em vez dos antigos, executar corretamente a migração do banco de dados e, idealmente, fazer isso de forma invisível para os visitantes. Felizmente, o Kubernetes nos ajuda nisso, suportando uma nuvem inteira de diferentes tipos de implantação.
Quarto - você precisa resolver o problema de armazenamento estático
Se seu site pesar "apenas" 10 gigabytes e você o implantar inteiramente em contêineres, você receberá contêineres com 10 gigabytes, que serão implantados para sempre.
Você precisa armazenar as partes mais "pesadas" do site fora dos contêineres, e surge a questão de como fazê-lo corretamente
O que não está em nossa decisão
O código Bitrix inteiro para microfunções / microsserviços não é cortado (para 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 como um todo.
Também não armazenamos a base no Kubernetes (no entanto, implementei soluções com a base no Kubernetes para ambientes de desenvolvedor, mas não para produção).
Os administradores do site ainda perceberão que o site funciona 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".
Decidimos sobre os problemas, decidimos sobre a necessidade de implementar o microsserviço, o objetivo é claro - obter um sistema funcional para trabalhar em aplicativos Bitrix no Kubernetes, preservando os recursos do Bitrix e as vantagens do Kubernetes. Começamos a implementação.
Arquitetura
Muitos lares "trabalhando" com um servidor web (trabalhadores).
Um abaixo com coroas de coroa (necessariamente apenas um).
Uma atualização para editar o código do site no painel de administração (somente uma também é necessária).

Resolvemos problemas:
- Onde armazenar sessões?
- Onde armazenar o cache?
- Onde armazenar estática, não colocar gigabytes de estática em um monte de contêineres?
- Como o banco de dados funcionará?
Imagem do Docker
Começamos criando uma imagem do Docker.
A opção ideal é que tenhamos uma imagem universal, e, com base nisso, obtemos pods de trabalho e pods com colchetes e pods de atualização.
Fizemos exatamente essa imagem .
Inclui nginx, apache / php-fpm (pode ser selecionado durante a montagem), msmtp para envio de email e cron.
Ao montar a imagem, a base de código completa do site é copiada para o diretório / app (com exceção das partes que colocaremos em um armazenamento compartilhado separado).
Microsserviços, serviços
lareiras de trabalhadores:
- Contêiner com contêiner nginx + apache / php-fpm + msmtp
- msmtp não funcionou em um microsserviço separado, o Bitrix começa a se ressentir por não poder enviar email diretamente
- Cada contêiner possui uma base de código completa.
- Proibição de alterar o código em contêineres.
cron em:
- contêiner com apache, php, cron
- base de código completa incluída
- proibição de alterar código em contêineres
atualização em:
- contêiner com contêiner nginx + apache / php-fpm + msmtp
- não há proibição de alterar código em contêineres
armazenamento de sessão
Armazenamento em cache Bitrix
Mais importante: armazenamos senhas para conectar-se a tudo, desde o banco de dados até o correio em segredos do kubernetes. Recebemos um bônus, as senhas são visíveis apenas para aqueles a quem damos acesso a segredos, e não para todos que têm acesso à base de código do projeto.
Armazenamento estático
Você pode usar qualquer coisa: ceph, nfs (mas nfs não são recomendados para produção), armazenamento em rede de provedores "em nuvem" etc.
O armazenamento precisará ser conectado em contêineres ao diretório / upload / do site e outros diretórios com estática.
Banco de Dados
Para simplificar, recomendamos mover a base para fora do Kubernetes. A base do Kubernetes é uma tarefa complexa separada, que tornará o circuito muito mais complicado.
Armazenamento de sessão
Usamos o memcached :)
Ele faz um bom trabalho de armazenamento de sessões, clusters e é suportado nativamente como session.save_path no php. Esse sistema foi desenvolvido muitas vezes na arquitetura monolítica clássica, quando construímos clusters com um grande número de servidores da web. Para implantação, usamos leme.
$ helm install stable/memcached --name session
php.ini - aqui nas configurações de imagem estão definidas para armazenar sessões no memcached
Usamos variáveis de ambiente para transferir dados do host com https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ .
Isso permite que você use o mesmo código nos ambientes dev, stage, test, prod (os nomes de host de memcached neles serão diferentes, portanto, precisamos transferir um nome de host exclusivo para as sessões para cada ambiente).
Armazenamento em cache Bitrix
Precisamos de um armazenamento à prova de falhas no qual todos os lares possam escrever e do qual possamos ler.
Também usamos o memcached.
Esta solução é recomendada pelo próprio Bitrix.
$ helm install stable/memcached --name cache
bitrix / .settings_extra.php - aqui no Bitrix é definido onde armazenamos o cache
Também usamos variáveis de ambiente.
Krontaski
Existem diferentes abordagens para fazer crontabs no Kubernetes.
- implantação separada com uma lareira
- cronjob para executar o crontask (se for um aplicativo da web - com wget https: // $ host $ cronjobname ou kubectl exec dentro de uma das áreas de trabalho, etc.)
- etc.
Você pode argumentar sobre o mais correto, mas, neste caso, escolhemos a opção "implantação separada com pods para crontask"
Como fazer:
- adicione coroas através do ConfigMap ou via config / addcron
- em uma instância, execute um contêiner idêntico ao submarino do trabalhador e permita a execução de tarefas de coroa nele
- a mesma base de código é usada, graças à unificação, a montagem do contêiner é simples
Que bom temos:
- temos crontaski trabalhando em um ambiente idêntico ao ambiente de desenvolvimento (janela de encaixe)
- Krontaski não precisa ser "reescrito" para Kubernetes, eles funcionam da mesma forma e na mesma base de código de antes
- Os membros da coroa podem adicionar todos os membros da equipe com direitos de confirmação ao ramo de produção, e não apenas administradores
Módulo Southbridge K8SDeploy e edição de código no painel de administração
Estávamos falando sobre atualização em?
E como direcionar o tráfego para lá?
Hooray, nós escrevemos um módulo para isso no php :) Este é um pequeno módulo clássico para o Bitrix. Ainda não está disponível ao público, mas planejamos abri-lo.
O módulo é instalado como um módulo regular no Bitrix:

E fica assim:

Ele permite que você defina um cookie que identifique o administrador do site e permite que o Kubernetes envie tráfego para atualização.
Quando as alterações forem concluídas, você precisará pressionar git push, as alterações de código serão enviadas para git; o sistema coletará a imagem com a nova versão do código e a "rolará" pelo cluster, substituindo os pods antigos.
Sim, é uma muleta, mas, ao mesmo tempo, mantemos a arquitetura de microsserviço e não tiramos dos usuários do Bitrix a oportunidade favorita de corrigir o código no painel de administração. No final, esta é uma opção, você pode resolver o problema de editar o código de uma maneira diferente.
Gráfico do leme
Para criar aplicativos no Kubernetes, geralmente usamos o gerenciador de pacotes Helm.
Para nossa solução Bitrix na Kubernetes, Sergey Bondarev, nosso principal administrador de sistemas, escreveu um gráfico Helm especial.
Ele cria trabalhador, ugrade, cron lareiras, configura entradas, serviços, transfere variáveis dos segredos do Kubernetes para lareiras.
Armazenamos o código no Gitlab e também executamos o assembly Helm no Gitlab.
Em suma, parece que isso
$ 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 durante a implantação. É legal quando você não está em pânico "conserte o código do ftp, porque o produto caiu", e o Kubernetes faz isso automaticamente, e sem tempo de inatividade.
Implantar
Sim, somos fãs do Gitlab e do Gitlab CI, use-o :)
Ao se comprometer com o Gitlab no repositório do projeto, o Gitlab lança um pipeline que implementará a nova versão do ambiente.
Etapas:
- build (crie uma nova imagem do Docker)
- teste (teste)
- limpeza (remova o ambiente de teste)
- push (envie para o registro do Docker)
- deploy (implantamos o aplicativo no Kubernetes via Helm).

Viva, estamos prontos para apresentá-lo!
Bem, ou faça perguntas, se houver.
Então o que fizemos
Do ponto de vista técnico:
- Bitrix dockerized;
- "Corte" o Bitrix em recipientes, cada um dos quais desempenhando um mínimo de funções;
- alcançou o estado sem estado de contêineres;
- resolveu o problema com a atualização do Bitrix no Kubernetes;
- todas as funções do Bitrix continuaram funcionando (quase todas);
- trabalhou implantação no Kubernetes e reversão entre versões.
Do ponto de vista comercial:
- tolerância a falhas;
- Ferramentas Kubernetes (fácil integração com o Gitlab CI, implantação contínua, etc);
- senhas em segredo (visíveis apenas para aqueles que têm acesso direto a senhas);
- é conveniente criar ambientes adicionais (para desenvolvimento, testes etc.) dentro de uma única infraestrutura.