Saiba de tudo sobre seus serviços com Jaeger e Linkerd
Lucas Santos
Posted on September 26, 2020
Já falamos um pouco sobre o Linkerd no último post, agora, para podermos estender ainda mais o nosso conhecimento sobre service mesh, vamos falar de um conceito interessante que vamos explorar com mais calma em outros artigos. Mas aqui vamos ter um exemplo prático! O Tracing.
Tracing
Tracing é um dos elementos da tríade que compõe o que vamos tratar mais a frente como Observabilidade , porém, no momento vamos focar nesse aspecto.
O tracing é a capacidade de poder acompanhar uma request de ponta a ponta verificando a ordem das chamadas dos serviços, o payload enviado e recebido por cada um, as respostas de cada serviço e também o tempo que cada request demorou.
Implementar um tracing simples em uma aplicação não é uma tarefa complexa, basta fazermos um log de tudo que recebemos e enviamos. Porém, existe um outro conceito chamado deep tracing ou distributed tracing que é justamente voltado à aplicações distribuídas.
E é ai que as coisas começam a ficar complicadas...
Deep Tracing
Deep Tracing é o nome que se dá à técnica de ligar logs de uma chamada a outra, formando uma linha do tempo do que foi feito. A cada log, damos o nome de um span e uma request pode desencadear múltiplos spans, ainda mais quando estamos tratando com microsserviços que chamam uns aos outros em sequencia.
Sendo muito simplista, o que o Deep Tracing faz é adicionar um header na request inicial que é chamado de Request ID – cada implementação da técnica tem seu próprio nome para isso. A cada nova request, esse ID é passado para frente e, combinada com a data da requisição, essas informações são utilizadas para construir um histórico de tudo que foi feito.
O problema é que, para fazer a implementação manual disso tudo, temos que:
- Ter uma noção muito boa da nossa aplicação
- Interceptar todas as chamadas HTTP e colocar um header em cada uma delas
O que não é uma tarefa fácil, por isso existem ferramentas como o Jaeger.
Jaeger
O Jaeger é uma ferramenta open source hospedada pela CNCF que serve justamente para evitar a complicação de ter que faz o deploy e implementação de todas as partes móveis que compõem um sistema de tracing distribuído.
Ele também utiliza o Open Telemetry um projeto que visa simplificar a telemetria de aplicações através de um conjunto padrão de ferramentas para obtenção de métricas.
O Jaeger é escrito em Golang, o que torna ele super rápido e muito útil para sistemas que estão distribuídos ou então possuem uma malha complexa de serviços. Sabe o que mais vai bem com essa arquitetura? O Linkerd!
Linkerd e Jaeger
Service Mesh e Observabilidade são conceitos que andam lado a lado, porém nem sempre você tem a capacidade de implementar ambos de forma simples. E é ai que tanto o Linkerd quanto o Jaeger brilham individualmente, mas, além de serem incríveis por si só, eles são ainda melhores juntos.
Usar o Linkerd com o Jaeger é uma excelente forma de obter todas as informações e métricas possíveis de sua aplicação de forma rápida e prática, até porque o próprio Linkerd suporta add-ons que incluem tanto o Jaeger como o OpenCensus Collector, uma ferramenta de coleta de métricas.
Mas chega de conceitos! A melhor forma de explicar o que é o Jaeger é através da prática! Então vamos colocar a mão na massa!
Aplicando Tracing
Para começar, vou assumir que você já está com o cluster criado e com o Linkerd Instalado, se você ainda não instalou tudo, volta para o artigo anterior e siga o tutorial até o final
Com o nosso cluster configurado e o Linkerd já instalado, vamos começar instalando a configuração all-in-one, que provê uma única imagem que contém todos os elementos necessários para que o tracing do Jaeger funcione tranquilamente.
Para instalar essa configuração, vamos criar um novo arquivo chamado config.yaml
e colocar o seguinte conteúdo nele:
tracing:
enabled: true
Então, vamos executar um comando do Linkerd para adicionar o novo add-on, na pasta aonde você criou o novo arquivo execute o seguinte comando:
linkerd upgrade --addon-config config.yaml | kubectl apply -f -
Assim que terminarmos, devemos ter dois novos deploys, um chamado linkerd-collector
e outro chamado linkerd-jaeger
no namespace linkerd
:
Anotações
Para detectar as mudanças e começar a realizar o tracing, o Linkerd utiliza duas anotações novas nos nossos deployments, sempre que precisarmos fazer essa modificação vamos incluir estas linhas juntamente com a anotação linkerd.io/inject: enabled
, ficando assim:
spec:
template:
metadata:
annotations:
linkerd.io/inject: enabled
config.linkerd.io/trace-collector: linkerd-collector.linkerd:55678
config.alpha.linkerd.io/trace-collector-service-account: linkerd-collector
Instrumentação
O tracing, diferentemente da maioria das técnicas do DevOps, exige uma instrumentação na aplicação, ou seja, temos que manualmente inserir o código do coletor de métricas no nosso sistema para que ele possa identificar e adicionar os headers e o ID para o trace.
Isso pode ser feito de forma manual na nossa aplicação usando Node através deste pacote, porém, para mantermos o processo mais simples, vamos utilizar a aplicação padrão do Linkerd para testar.
Primeiramente instalamos a aplicação com o comando
kubectl apply -f https://run.linkerd.io/emojivoto.yml
Depois executamos o seguinte comando para que possamos incluir a anotação que mostramos anteriormente
kubectl -n emojivoto patch -f https://run.linkerd.io/emojivoto.yml -p '
spec:
template:
metadata:
annotations:
linkerd.io/inject: enabled
config.linkerd.io/trace-collector: linkerd-collector.linkerd:55678
config.alpha.linkerd.io/trace-collector-service-account: linkerd-collector
'
Esperamos o deployment terminar de ser finalizado. Você pode executar o comando a seguir para acompanhar:
kubectl -n emojivoto rollout status deploy/web
Para finalizar, vamos ativar o tracing setando uma nova variável de ambiente no deployment com o seguinte comando
kubectl -n emojivoto set env --all deploy OC_AGENT_HOST=linkerd-collector.linkerd:55678
Explorando o Jaeger
Vamos ter certeza de que nossa implementação funcionou quando rodarmos o comando linkerd dashboard
e virmos o ícone do Jaeger ao lado dos nossos namespaces
Se clicarmos nele, teremos todas as chamadas feitas dentro da aplicação e poderemos acompanhar o histórico de tudo que foi chamado via HTTP
Se clicarmos em uma das linhas, conseguiremos ver por onde todas as requisições passaram e quais serviços foram chamados, bem como seus payloads e tempos
Outra funcionalidade interessante é a capacidade do Jaeger identificar a possível arquitetura do sistema. Basta clicar na guia "System Architecture" e selecionar entre o grafo direcionado e o DAG:
Podemos também explorar cada uma das requisições individualmente através do mesmo ícone do Jaeger em cada uma das linhas quando iniciamos o "Live View" de uma rota.
Conclusão
Vamos falar mais de observabilidade por aqui no futuro, mas tenha em mente que o tracing é uma das principais razões pelo qual o service mesh é tão cobiçado. O poder que é possível extrair quando você sabe exatamente o que está acontecendo em seu sistema permite que você resolva bugs e trate erros de forma muito mais simples e rápida.
Espero que tenham gostado do artigo, deixe seu comentário, curta e compartilhe! Vamos ajudar todo mundo a entender o que é tracing! Não se esqueça de se inscrever na newsletter para mais conteúdo exclusivo!
Até mais!
Posted on September 26, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.