Istio e Kubernetes em produção. Parte 2. Rastreamento

No passado статье Analisamos os componentes básicos do Service Mesh Istio, conhecemos o sistema e respondemos às principais dúvidas que costumam surgir quando se começa a trabalhar com o Istio. Nesta parte veremos como organizar a coleta de informações de rastreamento em uma rede.

Istio e Kubernetes em produção. Parte 2. Rastreamento

A primeira coisa que vem à mente de muitos desenvolvedores e administradores de sistema quando ouvem as palavras Service Mesh é rastreamento. Na verdade, adicionamos um servidor proxy especial a cada nó da rede através do qual passa todo o tráfego TCP. Parece que agora é possível enviar facilmente informações sobre todas as interações de rede na rede. Infelizmente, na realidade existem muitas nuances que precisam ser levadas em consideração. Vamos dar uma olhada neles.

Equívoco número um: podemos obter dados de caminhadas online gratuitamente.

Na verdade, de forma relativamente gratuita, só podemos conectar os nós do nosso sistema por setas e a taxa de dados que passa entre os serviços (na verdade, apenas o número de bytes por unidade de tempo). No entanto, na maioria dos casos, nossos serviços se comunicam por meio de algum tipo de protocolo da camada de aplicação, como HTTP, gRPC, Redis e assim por diante. E, claro, queremos ver informações de rastreamento especificamente para esses protocolos; queremos ver a taxa de solicitação, não a taxa de dados. Queremos entender a latência das solicitações usando nosso protocolo. Por fim, queremos ver o caminho completo que uma solicitação percorre desde o login em nosso sistema até o recebimento de uma resposta do usuário. Este problema já não é tão fácil de resolver.

Primeiro, vamos ver como são os intervalos de rastreamento de envio do ponto de vista arquitetônico no Istio. Como lembramos na primeira parte, o Istio possui um componente separado chamado Mixer para coleta de telemetria. Porém, na versão atual 1.0.*, o envio é feito diretamente dos servidores proxy, ou seja, do proxy envoy. O proxy Envoy oferece suporte ao envio de intervalos de rastreamento usando o protocolo zipkin pronto para uso. É possível conectar outros protocolos, mas apenas através de um plugin. Com o Istio obtemos imediatamente um proxy enviado montado e configurado, que suporta apenas o protocolo zipkin. Se quisermos usar, por exemplo, o protocolo Jaeger e enviar intervalos de rastreamento via UDP, precisaremos construir nossa própria imagem istio-proxy. Há suporte para plug-ins personalizados para istio-proxy, mas ainda está na versão alfa. Portanto, se quisermos prescindir de um grande número de configurações personalizadas, a gama de tecnologias utilizadas para armazenar e receber intervalos de rastreamento é reduzida. Dos principais sistemas, aliás, agora você pode usar o próprio Zipkin, ou Jaeger, mas enviar tudo para lá usando o protocolo compatível com zipkin (que é muito menos eficiente). O próprio protocolo zipkin envolve o envio de todas as informações de rastreamento aos coletores por meio do protocolo HTTP, que é bastante caro.

Como já disse, queremos rastrear protocolos em nível de aplicação. Isso significa que os servidores proxy próximos a cada serviço devem entender que tipo de interação está acontecendo agora. Por padrão, o Istio configura todas as portas como TCP simples, o que significa que nenhum rastreamento será enviado. Para que os traces sejam enviados, você deve, primeiramente, habilitar esta opção na configuração principal da malha e, o que é muito importante, nomear todas as portas das entidades do serviço kubernetes de acordo com o protocolo que é utilizado no serviço. Isso é, por exemplo, assim:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: nginx

Você também pode usar nomes compostos como http-magic (o Istio verá http e reconhecerá essa porta como um endpoint http). O formato é: proto-extra.

Para não corrigir um grande número de configurações para determinar o protocolo, você pode usar uma solução alternativa suja: corrigir o componente Pilot no momento em que ele está apenas executa lógica de definição de protocolo. No final, é claro, será necessário mudar essa lógica para padrão e mudar para uma convenção de nomenclatura para todas as portas.

Para entender se o protocolo está realmente definido corretamente, você precisa entrar em qualquer um dos contêineres secundários com o proxy envoy e fazer uma solicitação à porta administrativa da interface do envoy com localização /config_dump. Na configuração resultante, é necessário observar o campo de operação do serviço desejado. É usado no Istio como identificador de onde a solicitação é feita. Para personalizar o valor deste parâmetro no Istio (veremos isso em nosso sistema de rastreamento), é necessário especificar o sinalizador serviceCluster na fase de lançamento do contêiner sidecar. Por exemplo, pode ser calculado assim a partir de variáveis ​​obtidas da API descendente do Kubernetes:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

Um bom exemplo para entender como funciona o rastreamento no envoy é aqui.

O próprio endpoint para enviar intervalos de rastreamento também deve ser especificado nos sinalizadores de inicialização do proxy envoy, por exemplo: --zipkinAddress tracing-collector.tracing:9411

Equívoco número dois: podemos obter rastros completos de solicitações de maneira econômica por meio do sistema pronto para uso

Infelizmente, não é. A complexidade da implementação depende de como você já implementou a interação de serviços. Por que é que?

O fato é que para que o istio-proxy consiga entender a correspondência das solicitações que chegam a um serviço com as que saem do mesmo serviço, não basta simplesmente interceptar todo o tráfego. Você precisa ter algum tipo de identificador de comunicação. O proxy HTTP Envoy usa cabeçalhos especiais, pelos quais o Envoy entende qual solicitação específica para o serviço gera solicitações específicas para outros serviços. Lista desses cabeçalhos:

  • x-request-id,
  • x-b3-traçado,
  • x-b3-espanídeo,
  • x-b3-parentspanid,
  • x-b3-amostrado,
  • x-b3-sinalizadores,
  • x-ot-span-contexto.

Se você tem um único ponto, por exemplo, um cliente básico, no qual pode adicionar tal lógica, então está tudo bem, basta aguardar que esta biblioteca seja atualizada para todos os clientes. Mas se você tiver um sistema muito heterogêneo e não houver unificação na passagem de um serviço para outro na rede, isso provavelmente será um grande problema. Sem adicionar essa lógica, todas as informações de rastreamento serão apenas de “nível único”. Ou seja, receberemos todas as interações entre serviços, mas elas não ficarão coladas em cadeias únicas de passagem pela rede.

Conclusão

O Istio fornece uma ferramenta conveniente para coletar informações de rastreamento em uma rede, mas você deve entender que para implementação será necessário adaptar seu sistema e levar em consideração os recursos da implementação do Istio. Como resultado, dois pontos principais precisam ser resolvidos: definir o protocolo de nível de aplicação (que deve ser suportado pelo proxy enviado) e configurar o encaminhamento de informações sobre a conexão de solicitações ao serviço a partir de solicitações do serviço (usando cabeçalhos , no caso do protocolo HTTP). Quando essas questões são resolvidas, temos uma ferramenta poderosa que nos permite coletar informações da rede de forma transparente, mesmo em sistemas muito heterogêneos escritos em diversas linguagens e frameworks.

No próximo artigo sobre Service Mesh, veremos um dos maiores problemas do Istio – o grande consumo de RAM por cada contêiner de proxy sidecar e discutiremos como você pode lidar com isso.

Fonte: habr.com

Adicionar um comentário