Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd

Pagpapakilala

Tayo ay nasa Shopify nagsimulang i-deploy ang Istio bilang isang service mesh. Sa prinsipyo, lahat ay maayos, maliban sa isang bagay: ang mahal.

Π’ nai-publish na mga benchmark para kay Istio ang sabi nito:

Sa Istio 1.1, kumukonsumo ang proxy ng humigit-kumulang 0,6 vCPU (mga virtual core) bawat 1000 kahilingan kada segundo.

Para sa unang rehiyon sa service mesh (2 proxy sa bawat panig ng koneksyon), magkakaroon tayo ng 1200 core para lang sa proxy, sa rate na isang milyong kahilingan kada segundo. Ayon sa calculator ng gastos ng Google, magiging humigit-kumulang $40/buwan/core para sa configuration n1-standard-64, ibig sabihin, ang rehiyong ito lamang ay gagastos sa amin ng higit sa 50 libong dolyar bawat buwan para sa 1 milyong kahilingan bawat segundo.

Ivan Sim (Ivan Sim) biswal na inihambing pagkaantala ng service mesh noong nakaraang taon at nangako ng pareho para sa memorya at processor, ngunit hindi ito gumana:

Tila, ang values-istio-test.yaml ay seryosong magpapalaki ng mga kahilingan sa CPU. Kung nagawa ko nang tama ang aking matematika, kailangan mo ng humigit-kumulang 24 na CPU core para sa control panel at 0,5 CPU para sa bawat proxy. Wala akong ganon karami. Uulitin ko ang mga pagsubok kapag mas maraming mapagkukunan ang inilaan sa akin.

Nais kong makita sa aking sarili kung gaano kapareho ang pagganap ni Istio sa isa pang open source service mesh: Linkerd.

Pag-install ng mesh ng serbisyo

Una sa lahat, na-install ko ito sa isang kumpol SuperGloo:

$ supergloo init
installing supergloo version 0.3.12
using chart uri https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz
configmap/sidecar-injection-resources created
serviceaccount/supergloo created
serviceaccount/discovery created
serviceaccount/mesh-discovery created
clusterrole.rbac.authorization.k8s.io/discovery created
clusterrole.rbac.authorization.k8s.io/mesh-discovery created
clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding created
deployment.extensions/supergloo created
deployment.extensions/discovery created
deployment.extensions/mesh-discovery created
install successful!

Ginamit ko ang SuperGloo dahil mas pinadali nito ang pag-bootstrap ng service mesh. Wala akong masyadong ginawa. Hindi namin ginagamit ang SuperGloo sa produksyon, ngunit perpekto ito para sa ganoong gawain. Kinailangan kong gumamit ng literal ng ilang mga utos para sa bawat mesh ng serbisyo. Gumamit ako ng dalawang kumpol para sa paghihiwalay - isa bawat isa para sa Istio at Linkerd.

Isinagawa ang eksperimento sa Google Kubernetes Engine. Gumamit ako ng Kubernetes 1.12.7-gke.7 at isang pool ng mga node n1-standard-4 na may awtomatikong pag-scale ng node (minimum 4, maximum 16).

Pagkatapos ay na-install ko ang parehong mga service meshes mula sa command line.

Unang Naka-link:

$ 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 |
+---------+--------------+---------+---------------------------+

Pagkatapos 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      |
+---------+------------+---------+---------------------------+

Ang crash-loop ay tumagal ng ilang minuto, at pagkatapos ay nag-stabilize ang mga control panel.

(Tandaan: Sinusuportahan lang ng SuperGloo ang Istio 1.0.x sa ngayon. Inulit ko ang eksperimento sa Istio 1.1.3, ngunit hindi napansin ang anumang kapansin-pansing pagkakaiba.)

Pagse-set up ng Istio Automatic Deployment

Upang mai-install ni Istio ang sidecar Envoy, ginagamit namin ang sidecar injector βˆ’ MutatingAdmissionWebhook. Hindi natin ito pag-uusapan sa artikulong ito. Sabihin ko lang na isa itong controller na sumusubaybay sa pag-access ng lahat ng bagong pod at dynamic na nagdaragdag ng sidecar at initContainer, na responsable para sa mga gawain iptables.

Kami sa Shopify ay sumulat ng aming sariling access controller upang ipatupad ang mga sidecar, ngunit para sa benchmark na ito ginamit ko ang controller na kasama ng Istio. Ang controller ay nag-inject ng mga sidecar bilang default kapag may shortcut sa 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

Pagse-set up ng awtomatikong pag-deploy ng Linkerd

Para i-set up ang Linkerd sidecar embedding, gumagamit kami ng mga anotasyon (manu-mano kong idinagdag ang mga ito sa pamamagitan ng 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

Istio Fault Tolerance Simulator

Gumawa kami ng fault tolerance simulator na tinatawag na Istio para mag-eksperimento sa trapikong natatangi sa Shopify. Kailangan namin ng tool para gumawa ng custom na topology na kumakatawan sa isang partikular na bahagi ng aming service graph, na dynamic na naka-configure upang magmodelo ng mga partikular na workload.

Ang imprastraktura ng Shopify ay nasa ilalim ng mabigat na pagkarga sa panahon ng flash sales. Kasabay nito, Shopify Inirerekomenda ng mga nagbebenta na i-hold ang mga naturang benta nang mas madalas. Minsan nagbabala ang malalaking customer tungkol sa isang nakaplanong flash sale. Ang iba ay nagsagawa ng mga ito nang hindi inaasahan para sa atin sa anumang oras sa araw o gabi.

Gusto namin ang aming resiliency simulator na magmodelo ng mga workflow na tumutugma sa mga topologies at workloads na nanaig sa imprastraktura ng Shopify sa nakaraan. Ang pangunahing layunin ng paggamit ng service mesh ay kailangan namin ng pagiging maaasahan at fault tolerance sa antas ng network, at mahalaga para sa amin na epektibong makayanan ng service mesh ang mga load na dati nang nakakagambala sa mga serbisyo.

Sa gitna ng fault tolerance simulator ay isang worker node, na gumaganap bilang isang service mesh node. Ang worker node ay maaaring i-configure nang statically sa startup o dynamic na paraan sa pamamagitan ng REST API. Gumagamit kami ng dynamic na configuration ng mga worker node para gumawa ng mga workflow sa anyo ng mga regression test.

Narito ang isang halimbawa ng naturang proseso:

  • Naglulunsad kami ng 10 server bilang bar serbisyong nagbabalik ng tugon 200/OK pagkatapos ng 100 ms.
  • Naglulunsad kami ng 10 kliyente - ang bawat isa ay nagpapadala ng 100 kahilingan bawat segundo sa bar.
  • Bawat 10 segundo ay nag-aalis kami ng 1 server at sinusubaybayan ang mga error 5xx sa kliyente.

Sa pagtatapos ng daloy ng trabaho, sinusuri namin ang mga log at sukatan at suriin kung pumasa ang pagsubok. Sa ganitong paraan, nalaman namin ang tungkol sa performance ng aming service mesh at nagpapatakbo ng regression test para subukan ang aming mga pagpapalagay tungkol sa fault tolerance.

(Tandaan: Iniisip namin ang tungkol sa open sourcing sa Istio fault tolerance simulator, ngunit hindi pa kami handang gawin ito.)

Istio fault tolerance simulator para sa benchmark ng mesh ng serbisyo

Nag-set up kami ng ilang gumaganang node ng simulator:

  • irs-client-loadgen: 3 replika na nagpapadala ng 100 kahilingan bawat segundo bawat irs-client.
  • irs-client: 3 replika na tumatanggap ng kahilingan, maghintay ng 100ms at ipasa ang kahilingan sa irs-server.
  • irs-server: 3 replicas na nagbabalik 200/OK pagkatapos ng 100 ms.

Sa configuration na ito, masusukat natin ang isang matatag na daloy ng trapiko sa pagitan ng 9 na endpoint. Mga sidecar sa irs-client-loadgen ΠΈ irs-server makatanggap ng 100 kahilingan kada segundo, at irs-client β€” 200 (papasok at papalabas).

Sinusubaybayan namin ang paggamit ng mapagkukunan sa pamamagitan ng DataDogdahil wala kaming Prometheus cluster.

Natuklasan

Mga control panel

Una, sinuri namin ang pagkonsumo ng CPU.

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Linkerd control panel ~22 millicore

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Istio control panel: ~750 millicore

Ang Istio control panel ay gumagamit ng humigit-kumulang 35 beses na mas maraming mapagkukunan ng CPUkaysa kay Linkerd. Siyempre, ang lahat ay naka-install bilang default, at ang istio-telemetry ay gumagamit ng maraming mapagkukunan ng processor dito (maaari itong hindi paganahin sa pamamagitan ng hindi pagpapagana ng ilang mga pag-andar). Kung aalisin natin ang bahaging ito, makakakuha pa rin tayo ng higit sa 100 millicore, ibig sabihin 4 beses pakaysa kay Linkerd.

Sidecar proxy

Pagkatapos ay sinubukan namin ang paggamit ng isang proxy. Dapat mayroong isang linear na relasyon sa bilang ng mga kahilingan, ngunit para sa bawat sidecar mayroong ilang overhead na nakakaapekto sa curve.

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Linkerd: ~100 millicores para sa irs-client, ~50 millicores para sa irs-client-loadgen

Ang mga resulta ay mukhang lohikal, dahil ang client proxy ay tumatanggap ng dalawang beses na mas maraming trapiko kaysa sa loadgen proxy: para sa bawat papalabas na kahilingan mula sa loadgen, ang kliyente ay may isang papasok at isang papalabas.

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Istio/Envoy: ~155 millicores para sa irs-client, ~75 millicores para sa irs-client-loadgen

Nakikita namin ang mga katulad na resulta para sa mga sidecar ng Istio.

Ngunit sa pangkalahatan, ang mga proxy ng Istio/Envoy ay kumukonsumo humigit-kumulang 50% higit pang mga mapagkukunan ng CPUkaysa kay Linkerd.

Nakikita namin ang parehong scheme sa gilid ng server:

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Linkerd: ~50 millicore para sa irs-server

Benchmark ng pagkonsumo ng CPU para sa Istio at Linkerd
Istio/Envoy: ~80 millicore para sa irs-server

Sa gilid ng server, ang sidecar na Istio/Envoy ay gumagamit humigit-kumulang 60% higit pang mga mapagkukunan ng CPUkaysa kay Linkerd.

Konklusyon

Ang Istio Envoy proxy ay gumagamit ng 50+% na mas maraming CPU kaysa sa Linkerd sa aming simulate na workload. Ang Linkerd control panel ay gumagamit ng mas kaunting mapagkukunan kaysa sa Istio, lalo na para sa mga pangunahing bahagi.

Pinag-iisipan pa namin kung paano bawasan ang mga gastos na ito. Kung mayroon kang mga ideya, mangyaring ibahagi!

Pinagmulan: www.habr.com

Magdagdag ng komento