Como migramos mais de 700 servidores para o Salt
Por muito tempo, ficamos satisfeitos com uma configuração complexa e incômoda com 2 repositórios Git, onde parte dos dados são armazenados no MySQL e a outra parte é o Puppet 3.8. Mas nossas necessidades cresceram gradualmente, o número de serviços aumentou e o desempenho da configuração diminuiu. Em seguida, nos propusemos a tarefa de melhorar a configuração, otimizando todos os dados e ferramentas disponíveis.
Nossa equipe selecionou uma configuração adequada para si em 3 etapas. Compartilhamos nossa experiência de otimização do Salt, como aplicar e personalizar sem esforço extra.
Nota: No Habré encontramos ótimos artigos de nossos colegas, por isso não vamos nos alongar sobre os assuntos já abordados. É altamente recomendável ler:
O que é bom sobre o SaltStack e quais tarefas podem ser resolvidas com ele - um artigo desegurança, Tecnologias positivas.
Instalação, lançamento, primeiros comandos e familiaridade com funções - artigo do autorzerghack007...
Salt é um sistema de gerenciamento de configuração e execução remota. Uma estrutura de infraestrutura de código aberto escrita em Python.

Por que sal?
Salt, Ansible, Puppet e Chef são opções decentes para escolher uma ferramenta de gerenciamento de configuração. Escolhemos o Salt porque priorizamos os seguintes benefícios:
- Modularidade, disponibilidade de API na versão gratuita, ao contrário de Ansible.
- Python, o que significa que você pode entender facilmente qualquer componente e escrever você mesmo a funcionalidade que está faltando.
- Alto desempenho e escalabilidade. O assistente estabelece uma conexão permanente com os lacaios usando ZeroMQ para desempenho máximo.
- Os reatores são um tipo de gatilho que são executados quando uma determinada mensagem aparece no barramento de mensagens.
- Orquestração - a capacidade de construir relacionamentos complexos e executar ações em uma sequência específica, por exemplo, configurar primeiro o balanceador de carga e, em seguida, o cluster de servidor web.
- Puppet e Chef são escritos em Ruby. Nossa equipe não possui um especialista competente para trabalhar com esta linguagem de programação, mas o Python é bem conhecido e frequentemente utilizado por nós.
- Para as equipes que usaram o Ansible anteriormente, a capacidade de usar os manuais do Ansible será relevante. Isso permitirá que você migre para o Sal sem dor.
Observação:
estamos usando o sal há quase dois anos e recomendamos que você preste atenção aos seguintes pontos:
- Salt, , . , . , SaltStack .
- SaltStack . , . : , . , cmd.run file.managed, .

, , , .
. .
Dado:
Então, nossa configuração inicial é:
- 2 repositórios Git (um é para engenheiros e administradores; o segundo é para servidores altamente críticos, disponíveis apenas para administradores);
- um pedaço de dados em MySQL;
- a outra parte - no Puppet 3.8 (exagerado com herança, praticamente não usando Hiera - armazenamento de valor-chave).
Objetivo: migrar o sistema de gerenciamento de configuração para o Salt, aumentar seu desempenho, tornar o gerenciamento do servidor mais conveniente e compreensível.
Solução: em
primeiro lugar, começamos a migrar a configuração original para o Salt de servidores de serviço não críticos separados, ao mesmo tempo que nos livramos do código obsoleto.
Em seguida, preparamos a configuração dos servidores VDS. No nosso caso, são perfis para servidores de serviço, servidores de desenvolvimento e servidores cliente.
O principal problema ao mudar do Puppet para o Salt era um sistema operacional desatualizado (em 2018, havia o Ubuntu 12.04 e 14.04). Antes da migração, era necessário atualizar o SO e não afetar o funcionamento do serviço / servidor. Fora isso, tudo era fácil: os colegas gradualmente se envolveram no processo.
Entre as principais vantagens, a equipe observou, por exemplo, sintaxe mais compreensível. Meus colegas e eu concordamos em usar dicas de práticas recomendadas de sal , mas as complementamos com nossas próprias recomendações que refletem nossas particularidades.
A equipe também avaliou os métodos de entrega de configuração: push (o mestre "empurra") e puxa (o minion "puxa"). O modo Masterless ajuda se você precisa testar algo simples e ao mesmo tempo não mexer com o repositório Git. Executar um lacaio no modo sem mestre permite que você use o gerenciamento de configuração do Salt em uma máquina sem ter que ir para o mestre do Salt em outra máquina. A configuração é totalmente local.
Até 300 lacaios com essa solução, não tivemos problemas sérios. A configuração mestre naquele momento é um VDS com 6 núcleos e 4 GB de memória.
No entanto, assim que o número de lacaios atingiu 300, a carga média (carga média do sistema) aumentou para 3,5-4, e o sistema ficou muito lento. Anteriormente, o comando state.apply levava de 30 a 40 segundos, mas agora leva 18 minutos!
Esse resultado, é claro, era inaceitável para nós. Além disso, especialistas de outras empresas escreveram sobre histórias de sucesso com 10.000 lacaios. Começamos a descobrir qual era o problema.
As observações do mestre não deram uma resposta inequívoca à pergunta. Havia memória suficiente, a rede não foi carregada, o disco foi utilizado em 10%. Achávamos que a culpa era do GitLab, mas também não.
Parece que não havia potência de processador suficiente: ao adicionar núcleos, a média de carga caiu naturalmente, e o comando state.apply foi executado, embora mais rápido, cerca de 5-7 minutos, mas não tão rápido quanto gostaríamos.
Adicionar trabalhadores resolveu parcialmente o problema, mas aumentou significativamente o consumo de memória.
Então decidimos otimizar a própria configuração.
Estágio 1
Como os pilares são um armazenamento protegido, o acesso ao armazenamento está associado a operações de criptografia e você deve pagar pelo acesso a ele com tempo de CPU. Com isso, reduzimos o número de ligações para os pilares: os mesmos dados foram coletados apenas uma vez; se fossem necessários em outro lugar, eram acessados por meio de importação ({% - from 'defaults / pillar.sls' import profile%}).
A configuração é aplicada uma vez por hora, o tempo de execução é escolhido aleatoriamente. Depois de analisar quantas tarefas são realizadas por minuto e como elas são distribuídas uniformemente ao longo de uma hora, descobrimos: no início da hora, do 1º ao 8º minuto, passa-se mais tarefas e no 34º minuto, nenhuma! Escrevemos um runner que passava por todos os lacaios uma vez por semana e distribuía tarefas uniformemente. Graças a essa abordagem, a carga ficou uniforme, sem saltos.
Houve sugestões para mudar para um servidor de ferro, mas na época ele não estava lá e ... resolvemos o problema de uma forma diferente. Adicionamos um pouco de memória e colocamos todo o cache nela. Olhando para o painel do Grafana, primeiro pensamos que o salt-master não estava funcionando, pois a média de carga caiu para 0,5. Verificamos o tempo de execução de state.apply e também ficamos surpresos - 20-30 segundos. Foi uma vitória!
Estágio 2
Seis meses depois, o número de lacaios aumentou para 650 e ... a degradação do desempenho voltou. O gráfico da média de carga aumenta com o número de lacaios.
A primeira coisa que fizemos: habilitou o cache do pilar, defina o tempo de vida para 1 hora (pillar_cache_ttl: 3600). Percebemos que agora nossos commits não serão instantâneos e terão que esperar que o master atualize o cache.
Como não queríamos esperar nada, criamos ganchos no GitLab. Isso permite que o commit indique para qual lacaio você precisa atualizar o cache. O cache do Pillars reduziu significativamente a carga e o tempo para aplicar a configuração.
Estágio 3
Meditamos um pouco sobre os logs de depuração e apresentamos uma hipótese: e se aumentarmos o intervalo de atualização para o backend do arquivo e o cache da lista de arquivos (gitfs_update_interval, fileserver_list_cache_time)? A atualização acontecia uma vez por minuto e às vezes demorava até 15 segundos. Aumentando o intervalo de atualização de 1 minuto para 10 minutos, ganhamos novamente em velocidade! O indicador LA diminuiu de 1,5 para 0,5. O tempo de aplicação da configuração foi reduzido para os 20 segundos desejados. Apesar do fato de que LA cresceu novamente depois de algum tempo, a velocidade de execução do estado.aplicar não mudou significativamente. Uma atualização forçada desses caches foi adicionada aos ganchos do git push.

Adicionamos análises ao Elasticsearch: reescrevemos o elasticsearch_return integrado e agora podemos monitorar os resultados de state.apply (tempo médio de execução, estado mais longo e número de erros).
resultados
Agora estamos completamente satisfeitos com o desempenho de Salt. Existem planos para dobrar o número de lacaios. Ainda é difícil dizer como nosso mestre vai lidar com tamanha carga. Talvez passemos para a escala horizontal ou encontremos um parâmetro mágico. O tempo vai dizer!
Se você estiver usando gitfs como back-end, dê cinco! Provavelmente, você está passando pelos mesmos problemas que nós. Teremos o maior prazer em discutir esse tópico nos comentários.