Engenharia do Caos: a arte da destruição deliberada. Parte 2

Observação. trad.: Este artigo dá continuidade a uma grande série de artigos do evangelista de tecnologia da AWS Adrian Hornsby, que se propõe a explicar de forma simples e clara a importância da experimentação para mitigar as consequências de falhas em sistemas de TI.

Engenharia do Caos: a arte da destruição deliberada. Parte 2

“Se você não preparar um plano, então você planeja fracassar.” - Benjamim Franklin

В a primeira parte Nesta série de artigos, apresentei o conceito de engenharia do caos e expliquei como ela ajuda a encontrar e corrigir falhas no sistema antes que elas levem a falhas na produção. Também discutiu como a engenharia do caos promove mudanças culturais positivas dentro das organizações.

No final da primeira parte prometi falar sobre “ferramentas e métodos para introduzir falhas em sistemas”. Infelizmente, minha cabeça tinha seus próprios planos a esse respeito e neste artigo tentarei responder à pergunta mais popular que surge entre as pessoas que desejam entrar na engenharia do caos: O que quebrar primeiro?

Ótima pergunta! No entanto, ele não parece estar particularmente incomodado com este panda...

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Não mexa com o panda do caos!

Resposta curta: direcione serviços críticos ao longo do caminho da solicitação.

Resposta mais longa, mas mais clara: Para entender por onde começar a experimentar o caos, preste atenção em três áreas:

  1. Olhar para histórico de falhas e identificar padrões;
  2. decidir sobre dependências críticas;
  3. Use o chamado efeito de excesso de confiança.

É engraçado, mas esta parte poderia facilmente ser chamada "Uma jornada para a autodescoberta e a iluminação". Nele começaremos a “brincar” com alguns instrumentos legais.

1. A resposta está no passado

Se você se lembra, na primeira parte apresentei o conceito de Correção de Erros (COE) - um método pelo qual analisamos nossos erros - erros em tecnologia, processo ou organização - para entender sua(s) causa(s) e prevenir recorrência no futuro. Em geral, é aqui que você deve começar.

“Para entender o presente, você precisa conhecer o passado.” - Carl sagan

Observe o histórico de falhas, marque-as no COE ou post-mortem e classifique-as. Identifique padrões comuns que muitas vezes levam a problemas e, para cada COE, pergunte-se o seguinte:

“Isso poderia ter sido previsto e, portanto, evitado pela injeção de falhas?”

Lembro-me de um fracasso no início da minha carreira. Poderia ter sido facilmente evitado se tivéssemos realizado alguns experimentos simples de caos:

Em condições normais, as instâncias de back-end respondem às verificações de integridade de balanceador de carga (ELB)). O ELB usa essas verificações para redirecionar solicitações para instâncias íntegras. Quando se descobre que uma instância “não é íntegra”, o ELB para de enviar solicitações a ela. Um dia, após uma campanha de marketing bem-sucedida, o volume de tráfego aumentou e os backends começaram a responder às verificações de saúde mais lentamente do que o normal. Deve dizer-se que estes exames de saúde foram profundo, ou seja, o estado das dependências foi verificado.

No entanto, tudo ficou bem por um tempo.

Então, já sob condições bastante estressantes, uma das instâncias começou a executar uma tarefa cron ETL regular e não crítica. A combinação de alto tráfego e cronjob elevou a utilização da CPU para quase 100%. A sobrecarga da CPU atrasou ainda mais as respostas às verificações de integridade, tanto que o ELB decidiu que a instância estava apresentando problemas de desempenho. Como esperado, o balanceador parou de distribuir tráfego para ele, o que, por sua vez, levou a um aumento na carga das demais instâncias do grupo.

De repente, todas as outras instâncias também começaram a falhar na verificação de integridade.

Iniciar uma nova instância exigiu o download e a instalação de pacotes e demorou muito mais do que o ELB levou para desativá-los - um por um - no grupo de escalonamento automático. É claro que logo todo o processo atingiu um ponto crítico e o aplicativo travou.

Então entendemos para sempre os seguintes pontos:

  • A instalação de software ao criar uma nova instância leva muito tempo; é melhor dar preferência à abordagem imutável e AMI Dourado.
  • Em situações complexas, as respostas aos exames de saúde e aos ELB devem ter prioridade – a última coisa que queremos é complicar a vida das restantes instâncias.
  • O cache local de verificações de integridade ajuda muito (mesmo que por alguns segundos).
  • Em uma situação difícil, não execute tarefas cron e outros processos não críticos - economize recursos para as tarefas mais importantes.
  • Ao fazer o escalonamento automático, use instâncias menores. Um grupo de 10 exemplares pequenos é melhor que um grupo de 4 exemplares grandes; se uma instância falhar, no primeiro caso 10% do tráfego será distribuído em 9 pontos, no segundo - 25% do tráfego em três pontos.

Assim, isso poderia ter sido previsto e, portanto, evitado pela introdução do problema?

Sime de várias maneiras.

Primeiro, simulando alto uso da CPU usando ferramentas como stress-ng ou cpuburn:

❯ stress-ng --matrix 1 -t 60s

Engenharia do Caos: a arte da destruição deliberada. Parte 2
estresse

Em segundo lugar, ao sobrecarregar a instância com wrk e outros utilitários semelhantes:

❯ wrk -t12 -c400 -d20s http://127.0.0.1/api/health

Engenharia do Caos: a arte da destruição deliberada. Parte 2

Os experimentos são relativamente simples, mas podem fornecer um bom alimento para reflexão sem ter que passar pelo estresse de um fracasso real.

contudo não pare aí. Tente reproduzir a falha em um ambiente de teste e verifique sua resposta à pergunta "Isto poderia ter sido previsto e, portanto, evitado pela introdução de uma falha?" Este é um mini experimento de caos dentro de um experimento de caos para testar suposições, mas começando com uma falha.

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Foi um sonho ou realmente aconteceu?

Então estude o histórico de falhas, analise EOC, marque-os e classifique-os por “raio de acerto” — ou, mais precisamente, pelo número de clientes afetados — e, em seguida, procure padrões. Pergunte a si mesmo se isso poderia ter sido previsto e evitado pela introdução do problema. Verifique sua resposta.

Em seguida, mude para os padrões mais comuns com maior alcance.

2. Construa um mapa de dependências

Reserve um momento para pensar sobre sua aplicação. Existe um mapa claro de suas dependências? Você sabe qual impacto eles terão se houver uma falha?

Se você não estiver muito familiarizado com o código do seu aplicativo ou se ele ficar muito grande, pode ser difícil entender o que o código faz e quais são suas dependências. Compreender essas dependências e seu possível impacto na aplicação e nos usuários é fundamental para saber por onde começar com a engenharia do caos: o ponto de partida é o componente com maior raio de impacto.

Identificar e documentar dependências é chamado de "construindo um mapa de dependência» (mapeamento de dependência). Isso normalmente é feito para aplicativos com uma grande base de código usando ferramentas de criação de perfil de código. (perfil de código) e instrumentação (instrumentação). Você também pode construir um mapa monitorando o tráfego de rede.

No entanto, nem todas as dependências são iguais (o que complica ainda mais o processo). Alguns crítico, outro - secundário (pelo menos em teoria, já que muitas vezes ocorrem travamentos devido a problemas com dependências que foram consideradas não críticas).

Sem dependências críticas, o serviço não pode funcionar. Dependências não críticas "não deveria» influenciar o serviço em caso de queda. Para entender as dependências, você precisa ter um entendimento claro das APIs usadas pelo seu aplicativo. Isso pode ser muito mais difícil do que parece – pelo menos para aplicações grandes.

Comece examinando todas as APIs. Destaque o mais significativo e crítico... Pegar dependências do repositório de código, confira registros de conexãoe, em seguida, visualize documentação (é claro, se existir - caso contrário, você ainda teráоproblemas maiores). Use as ferramentas para perfil e rastreamento, filtre chamadas externas.

Você pode usar programas como netstat - um utilitário de linha de comando que exibe uma lista de todas as conexões de rede (soquetes ativos) no sistema. Por exemplo, para listar todas as conexões atuais, digite:

❯ netstat -a | more 

Engenharia do Caos: a arte da destruição deliberada. Parte 2

Na AWS você pode usar registros de fluxo (logs de fluxo) VPC é um método que permite coletar informações sobre o tráfego IP que entra ou sai de interfaces de rede em uma VPC. Esses logs também podem ajudar em outras tarefas – por exemplo, encontrar uma resposta para a pergunta sobre por que determinado tráfego não chega à instância.

Você também pode usar Raio-X da AWS. O X-Ray permite que você obtenha informações detalhadas e "definitivas" (de ponta a ponta) visão geral das solicitações à medida que elas se movem pelo aplicativo e também cria um mapa dos componentes subjacentes do aplicativo. Muito conveniente se você precisar identificar dependências.

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Console do AWS X-Ray

Um mapa de dependência de rede é apenas uma solução parcial. Sim, mostra qual aplicativo se comunica com qual, mas existem outras dependências.

Muitos aplicativos usam DNS para se conectar a dependências, enquanto outros podem usar descoberta de serviço ou até mesmo endereços IP codificados em arquivos de configuração (por exemplo, /etc/hosts).

Por exemplo, você pode criar Buraco negro de DNS via iptables e veja o que quebra. Para fazer isso, digite o seguinte comando:

❯ iptables -I OUTPUT -p udp --dport 53 -j REJECT -m comment --comment "Reject DNS"

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Buraco negro do DNS

Se o /etc/hosts ou outros arquivos de configuração, você encontrará endereços IP sobre os quais nada sabe (sim, infelizmente, isso também acontece), você pode ajudar novamente iptables. Digamos que você descobriu 8.8.8.8 e não sei se este é o endereço do servidor DNS público do Google. Usando iptables Você pode bloquear o tráfego de entrada e saída para este endereço usando os seguintes comandos:

❯ iptables -A INPUT -s 8.8.8.8 -j DROP -m comment --comment "Reject from 8.8.8.8"
❯ iptables -A OUTPUT -d 8.8.8.8 -j DROP -m comment --comment "Reject to 8.8.8.8"

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Fechando acesso

A primeira regra descarta todos os pacotes do DNS público do Google: ping funciona, mas os pacotes não são retornados. A segunda regra descarta todos os pacotes originados do seu sistema para o DNS público do Google - em resposta a ping nós conseguimos Operação não permitida.

Nota: neste caso específico seria melhor usar whois 8.8.8.8, mas este é apenas um exemplo.

Podemos ir ainda mais fundo na toca do coelho, porque tudo que usa TCP e UDP também depende de IP. Na maioria dos casos, o IP está vinculado ao ARP. Não se esqueça dos firewalls...

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Se você tomar a pílula vermelha, você permanecerá no País das Maravilhas, e eu lhe mostrarei a profundidade da toca do coelho."

Uma abordagem mais radical é desconectar carros um por um e veja o que está quebrado... torne-se um "macaco do caos". É claro que muitos sistemas de produção não são projetados para esse tipo de ataque de força bruta, mas pelo menos podem ser testados em um ambiente de teste.

Construir um mapa de dependências costuma ser uma tarefa muito demorada. Falei recentemente com um cliente que passou quase 2 anos desenvolvendo uma ferramenta que gera mapas de dependências de forma semiautomática para centenas de microsserviços e comandos.

O resultado, porém, é extremamente interessante e útil. Você aprenderá muito sobre seu sistema, suas dependências e operações. Novamente, seja paciente: é a jornada em si que mais importa.

3. Cuidado com o excesso de confiança

“Quem sonha com o quê, acredita.” - Demóstenes

Você já ouviu falar efeito de excesso de confiança?

Segundo a Wikipedia, o efeito do excesso de confiança é “um viés cognitivo em que a confiança de uma pessoa nas suas ações e decisões é significativamente maior do que a precisão objetiva desses julgamentos, especialmente quando o nível de confiança é relativamente alto”.

Engenharia do Caos: a arte da destruição deliberada. Parte 2
Baseado no instinto e na experiência...

Na minha experiência, essa distorção é uma ótima dica de por onde começar com a engenharia do caos.

Cuidado com o operador excessivamente confiante:

Charlie: “Essa coisa não cai há cinco anos, está tudo bem!”
Crash: “Espere... estarei aí em breve!”

O preconceito como consequência do excesso de confiança é algo insidioso e até perigoso devido aos diversos fatores que o influenciam. Isso é especialmente verdadeiro quando os membros da equipe dedicam seus corações a uma tecnologia ou passam muito tempo “consertando” ela.

Resumindo

A busca por um ponto de partida para a engenharia do caos sempre traz mais resultados do que o esperado, e as equipes que começam a quebrar as coisas muito rapidamente perdem de vista a essência mais global e interessante do (caos-)Engenharia - uso criativo métodos científicos и evidência empírica para o projeto, desenvolvimento, operação, manutenção e melhoria de sistemas (software).

Isto conclui a segunda parte. Por favor, escreva comentários, compartilhe opiniões ou apenas bata palmas Médio. Na próxima parte eu realmente Considerarei ferramentas e métodos para introduzir falhas nos sistemas. Até!

PS do tradutor

Leia também em nosso blog:

Fonte: habr.com

Adicionar um comentário