Benchmark de consumo de CPU para Istio e Linkerd

Benchmark de consumo de CPU para Istio e Linkerd

Introdução

Nós na Shopify começamos a implementar o Istio como service mesh. No geral, estamos satisfeitos, exceto por uma coisa: isso é caro.

Em nos benchmarks publicados para Istio é mencionado:

Com o Istio 1.1, o proxy consome cerca de 0,6 vCPU (núcleos virtuais) para 1000 requisições por segundo.

Para a primeira região no service mesh (com 2 proxies de cada lado da conexão), teremos 1200 núcleos apenas para o proxy, considerando um milhão de requisições por segundo. De acordo com a calculadora de custos do Google, isso resulta em cerca de $40/mês/núcleo para a configuração n1-standard-64, portanto, apenas esta região custará mais de 50 mil dólares por mês para 1 milhão de requisições por segundo.

Ivan Sim (Ivan Sim) comparou claramente as latências do service mesh no ano passado e prometeu o mesmo para memória e CPU, mas não conseguiu:

Aparentemente, values-istio-test.yaml aumentará bastante as requisições para a CPU. Se eu calculei corretamente, serão necessários cerca de 24 núcleos de CPU para o painel de controle e 0,5 CPU para cada proxy. Eu não tenho tantos. Repetirei os testes quando mais recursos forem alocados para mim.

Queria me certificar de quão próximos os resultados do Istio estão de outro service mesh de código aberto: Linkerd.

Instalação do service mesh

Primeiro, instalei no cluster SuperGloo:

$ supergloo init
instalando a versão 0.3.12 do supergloo
usando o URI do gráfico https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz
configmap/sidecar-injection-resources criado
serviceaccount/supergloo criado
serviceaccount/discovery criado
serviceaccount/mesh-discovery criado
clusterrole.rbac.authorization.k8s.io/discovery criado
clusterrole.rbac.authorization.k8s.io/mesh-discovery criado
clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding criado
clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding criado
clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding criado
deployment.extensions/supergloo criado
deployment.extensions/discovery criado
deployment.extensions/mesh-discovery criado
instalação bem-sucedida!

Usei o SuperGloo porque ele simplifica bastante a instalação inicial do service mesh. Eu quase não precisei fazer nada. Em produção, não usamos o SuperGloo, mas para uma tarefa como esta, ele é ideal. Tive que executar literalmente apenas alguns comandos para cada service mesh. Usei dois clusters para isolamento — um para Istio e outro para Linkerd.

O experimento foi realizado no Google Kubernetes Engine. Usei Kubernetes 1.12.7-gke.7 e um pool de nós n1-standard-4 com escalonamento automático de nós (mínimo 4, máximo 16).

Depois, instalei ambos os service mesh através da linha de comando.

Primeiro o Linkerd:

$ supergloo install linkerd --name linkerd
+---------+--------------+---------+---------------------------+
| INSTALL |     TYPE     | STATUS  |          DETAILS          |
+---------+--------------+---------+---------------------------+
| linkerd | Linkerd Mesh | Pending | enabled: true             |
|         |              |         | version: stable-2.3.0     |
|         |              |         | namespace: linkerd        |
|         |              |         | mtls enabled: true        |
|         |              |         | auto inject enabled: true |
+---------+--------------+---------+---------------------------+

Depois, Istio:

$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true
+---------+------------+---------+---------------------------+
| INSTALL |    TYPE    | STATUS  |          DETAILS          |
+---------+------------+---------+---------------------------+
| istio   | Istio Mesh | Pending | enabled: true             |
|         |            |         | version: 1.0.6            |
|         |            |         | namespace: istio-system   |
|         |            |         | mtls enabled: true        |
|         |            |         | auto inject enabled: true |
|         |            |         | grafana enabled: true     |
|         |            |         | prometheus enabled: true  |
|         |            |         | jaeger enabled: true      |
+---------+------------+---------+---------------------------+

O crash-loop levou alguns minutos, e então os painéis de controle estabilizaram.

(Nota. O SuperGloo atualmente suporta apenas Istio 1.0.x. Eu repeti o experimento com Istio 1.1.3, mas não percebi diferença significativa.)

Configuração da injeção automática do Istio

Para que o Istio instale o sidecar Envoy, usamos o injetor de sidecar — MutatingAdmissionWebhook. Não vamos falar sobre isso neste artigo. Apenas direi que é um controlador que monitoriza o acesso de todos os novos pods e adiciona dinamicamente o sidecar e o initContainer, que é responsável por tarefas iptables.

Nós, da Shopify, escrevemos nosso próprio controlador de acesso para injeção de sidecars, mas neste benchmark eu utilizei o controlador que vem com o Istio. O controlador padrão injeta sidecars quando há um rótulo no namespace istio-injection: enabled:

$ kubectl label namespace irs-client-dev istio-injection=enabled
namespace/irs-client-dev labeled

$ kubectl label namespace irs-server-dev istio-injection=enabled
namespace/irs-server-dev labeled

Configuração da injeção automática do Linkerd

Para configurar a injeção de sidecars do Linkerd, usamos anotações (eu as adicionei manualmente através de kubectl edit):

metadata:
  annotations:
    linkerd.io/inject: enabled

$ k edit ns irs-server-dev 
namespace/irs-server-dev edited

$ k get ns irs-server-dev -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    linkerd.io/inject: enabled
  name: irs-server-dev
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

Simulador de tolerância a falhas do Istio

Criamos um simulador de resiliência do Istio para experimentar o tráfego exclusivo da Shopify. Precisávamos de uma ferramenta para criar uma topologia arbitrária que representasse uma parte específica do grafo do nosso serviço com configurações dinâmicas para modelar cargas de trabalho específicas.

A infraestrutura da Shopify enfrenta grande carga durante vendas relâmpago. Nesse contexto, a Shopify recomenda que os vendedores realizem essas vendas com mais frequência. Grandes clientes às vezes nos avisam sobre uma venda relâmpago agendada. Outros a realizam de forma inesperada a qualquer hora do dia e da noite.

Queríamos que nosso simulador de resiliência modelasse os fluxos de trabalho que correspondem às topologias e cargas de trabalho que anteriormente causaram sobrecarga na infraestrutura da Shopify. O principal objetivo do uso de service mesh é garantir a confiabilidade e a resiliência em nível de rede, e é importante que a service mesh lide de forma eficaz com as cargas que anteriormente prejudicaram os serviços.

No núcleo do simulador de resiliência está um nó de trabalho que atua como um nó de service mesh. O nó de trabalho pode ser configurado estaticamente na inicialização ou dinamicamente por meio da API REST. Usamos a configuração dinâmica dos nós de trabalho para criar fluxos de trabalho na forma de testes regressivos.

Aqui está um exemplo desse processo:

  • Iniciamos 10 servidores como bar um serviço que retorna uma resposta 200/OK em 100 ms.
  • Iniciamos 10 clientes — cada um enviando 100 solicitações por segundo para bar.
  • A cada 10 segundos, removemos 1 servidor, monitoramos erros 5xx no cliente.

No final do fluxo de trabalho, analisamos os logs e métricas e verificamos se o teste foi concluído. Assim, aprendemos sobre o desempenho da nossa service mesh e realizamos um teste regressivo para validar nossas suposições sobre resiliência.

(Nota. Estamos considerando abrir o código-fonte do simulador de resiliência do Istio, mas ainda não estamos prontos para isso.)

Simulador de resiliência do Istio para benchmark de service mesh

Estamos configurando vários nós de trabalho do simulador:

  • irs-client-loadgen: 3 réplicas que enviam 100 solicitações por segundo para irs-client.
  • irs-client: 3 réplicas que recebem a solicitação, aguardam 100 ms e redirecionam a solicitação para irs-server.
  • irs-server: 3 réplicas que retornam 200/OK em 100 ms.

Com esta configuração, podemos medir um fluxo estável de tráfego entre 9 pontos finais. Os Sidecars em irs-client-loadgen e irs-server recebem 100 solicitações por segundo, enquanto irs-client — 200 (entrantes e saídas).

Monitoramos o uso de recursos através de DataDog, pois não temos um cluster Prometheus.

Resultados

Painéis de controlo

Primeiro, examinamos o consumo de CPU.

Benchmark de consumo de CPU para Istio e Linkerd
Painel de controle do Linkerd ~22 mil milhões

Benchmark de consumo de CPU para Istio e Linkerd
Painel de controle do Istio: ~750 mil milhões

O painel de controle do Istio utiliza aproximadamente 35 vezes mais recursos de CPU, que o Linkerd. Claro, tudo está configurado com as configurações padrão, e muitos recursos de CPU são consumidos aqui pelo istio-telemetry (isso pode ser desativado, abrindo mão de algumas funcionalidades). Mesmo sem esse componente, ainda obtém-se mais de 100 mil milhões, ou seja, 4 vezes mais, que o Linkerd.

Proxy Sidecar

Em seguida, verificamos o uso do proxy. Aqui deveria haver uma relação linear com o número de solicitações, mas para cada sidecar há algumas sobrecargas que afetam a curva.

Benchmark de consumo de CPU para Istio e Linkerd
Linkerd: ~100 mil milhões para irs-client, ~50 mil milhões para irs-client-loadgen

Os resultados parecem lógicos, já que o proxy client recebe duas vezes mais tráfego do que o proxy loadgen: para cada solicitação de saída do loadgen, há uma solicitação de entrada e uma de saída para o client.

Benchmark de consumo de CPU para Istio e Linkerd
Istio/Envoy: ~155 mil milhões para irs-client, ~75 mil milhões para irs-client-loadgen

Observamos resultados semelhantes para os sidecars do Istio.

Mas, em geral, o proxy Istio/Envoy consome aproximadamente 50% mais recursos de CPU, do que o Linkerd.

A mesma tendência é observada do lado do servidor:

Benchmark de consumo de CPU para Istio e Linkerd
Linkerd: ~50 mil milhões para irs-server

Benchmark de consumo de CPU para Istio e Linkerd
Istio/Envoy: ~80 mil milhões para irs-server

Do lado do servidor, o sidecar Istio/Envoy consome aproximadamente 60% mais recursos de CPU, do que o Linkerd.

Conclusão

O proxy Istio Envoy consome 50%+ mais CPU do que o Linkerd, na nossa carga de trabalho simulada. O painel de controle do Linkerd consome muito menos recursos do que o Istio, especialmente no que diz respeito aos componentes principais.

Ainda estamos pensando em como reduzir esses custos. Se você tiver ideias, compartilhe!

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster