Istio і Kubernetes у production. Частка 2. Tracing

У мінулым артыкуле мы разгледзелі базавыя кампаненты Service Mesh Istio, пазнаёміліся з сістэмай і адказалі на асноўныя пытанні, якія звычайна ўзнікаюць у пачатку працы з Istio. У гэтай частцы мы паглядзім на тое, як арганізаваць збор tracing інфармацыі па сетцы.

Istio і Kubernetes у production. Частка 2. Tracing

Першае, што прыходзіць у галаву шматлікім распрацоўнікам і сістэмным адміністратарам, калі яны чуюць словы Service Mesh – гэта tracing. І сапраўды, мы дадаем у кожны вузел сеткі спецыяльны проксі-сервер, праз які праходзіць увесь TCP-трафік. Здаецца, што зараз можна лёгка адпраўляць інфармацыю аб усіх сеткавых узаемадзеяннях у сетцы. Нажаль, у рэальнасці з'яўляецца мноства нюансаў, якія неабходна ўлічваць. Давайце разгледзім іх.

Памылка нумар адзін: мы можам бясплатна атрымаць дадзеныя аб паходах па сетцы

Насамрэч, адносна бясплатна мы можам толькі атрымаць злучаныя стрэлкамі вузлы нашай сістэмы і rate дадзеных, які праходзіць паміж сэрвісамі (па сутнасці - толькі колькасць байтаў у адзінку часу). Аднак у большасці выпадкаў нашы сэрвісы маюць зносіны па нейкім пратаколе прыкладнага ўзроўня, такому як, HTTP, gRPC, Redis і гэтак далей. І, вядома, мы жадаем бачыць трэйсінг інфармацыю менавіта па гэтых пратаколах, жадаем бачыць rate запытаў, а не rate дадзеных. Жадаем разумець latency запытаў па нашым пратаколе. Нарэшце, мы хочам бачыць поўны шлях, які праходзіць запыт ад уваходу ў нашу сістэму да атрымання адказу карыстальнікам. Гэта задача вырашаецца ўжо не так проста.

Для пачатку давайце разгледзім як выглядае адпраўка tracing span'ов з пункта гледжання архітэктуры ў Istio. Як мы памятаем з першай часткі, для збору тэлеметрыі ў Istio ёсць асобны кампанент, які завецца Mixer. Аднак, у бягучай версіі 1.0.* адпраўка робіцца напрамую з проксі сервераў, а менавіта, з envoy proxy. Envoy proxy падтрымлівае адпраўку tracing span'аў па пратаколе zipkin са скрынкі. Іншыя пратаколы можна падлучыць, але толькі праз убудову. З Istio мы адразу атрымліваем сабраны і наладжаны envoy proxy, у якім падтрымліваецца толькі zipkin пратакол. Калі мы жадаем выкарыстаць, напрыклад, Jaeger пратакол і адпраўляць tracing span'ы па UDP, то нам трэба будзе сабраць свой istio-proxy выява. Падтрымка кастамных плагінаў для istio-proxy ёсць, аднак яна ўсё яшчэ ў alpha версіі. Таму, калі мы жадаем абыйсціся без вялікай колькасці кастамных налад, круг выкарыстоўваных тэхналогій для захоўвання і прыёму tracing span'ов памяншаецца. З асноўных сістэм, па сутнасці, зараз можна выкарыстоўваць сам Zipkin, альбо Jaeger, але адпраўляць туды ўсё па zipkin сумяшчальнаму пратаколу (што значна менш эфектыўна). Сам zipkin пратакол мяркуе адпраўку ўсёй tracing інфармацыі на калектары па HTTP пратаколе, што досыць накладна.

Як я ўжо сказаў, трэйсіць мы хочам пратаколы прыкладнога ўзроўню. А гэта значыць, што проксі-сэрвэры, якія стаяць побач з кожным сэрвісам, павінны разумець, якое менавіта ўзаемадзеяньне адбываецца цяпер. Па змаўчанні, Istio наладжвае для ўсіх партоў plain TCP тып, што азначае, што ніякіх трэйсаў адпраўляцца не будзе. Для таго, каб трэйсы адпраўляліся, трэба, па-першае, уключыць такую ​​опцыю ў галоўным mesh config'е і, што вельмі важна, прайменаваць усе парты ў service сутнасцяў kubernetes у адпаведнасці з пратаколам, які ў выкарыстоўваецца ў сэрвісе. Гэта значыць, напрыклад, вось так:

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

Можна таксама выкарыстоўваць складовыя імёны, напрыклад http-magic (Istio убачыць http і распазнае гэты порт як http endpoint). Фармат такі: proto-extra.

Для таго, каб не патчыць велізарную колькасць канфігурацый для вызначэння пратакола, можна скарыстацца брудным workaround'ам: прапатчыць Pilot кампанент у момант, калі ён як раз выконвае логіку вызначэння пратакола. У выніку, вядома, трэба будзе змяніць гэтую логіку на стандартную і перайсці на канвенцыю наймення ўсіх партоў.

Для таго, каб зразумець ці сапраўды пратакол вызначаны дакладна, трэба зайсці ў любы з sidecar кантэйнераў з envoy proxy і зрабіць запыт на порт admin інтэрфейсу envoy з location /config_dump. У атрыманай канфігурацыі трэба паглядзець у патрэбнага сэрвісу поле operation. Яно выкарыстоўваецца ў Istio як ідэнтыфікатар таго, куды адбываецца запыт. Для таго, каб кастамізаваць у Istio значэнне гэтага параметру (мы затым будзем бачыць яго ў нашай tracing сістэме), неабходна на этапе запуску sidecar кантэйнера паказаць сцяг serviceCluster. Напрыклад, яго можна вось так вылічаць са зменных, атрыманых з downward API kubernetes:

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

Добры прыклад для разумення таго, як працуе tracing у envoy, есць тут.

Сам endpoint для адпраўкі tracing span'аў неабходна таксама паказаць у сцягах запуску envoy proxy, напрыклад: --zipkinAddress tracing-collector.tracing:9411

Памылка нумар два: мы можам нядорага атрымаць поўныя трэйсы праходу запытаў па сістэме са скрынкі

Нажаль, гэта не так. Складанасць укаранення залежыць ад таго, якім чынам у вас ужо рэалізавана ўзаемадзеянне сэрвісаў. Чаму так?

Справа ў тым, што для таго, каб istio-proxy змог зразумець адпаведнасць уваходных запытаў у сэрвіс з якія выходзяць з гэтага ж сэрвісу, нядосыць проста перахапляць увесь трафік. Трэба мець нейкі ідэнтыфікатар сувязі. У HTTP envoy proxy выкарыстоўваюцца адмысловыя загалоўкі, па якіх envoy разумее які менавіта запыт да сэрвісу спараджае пэўныя запыты ў іншыя сэрвісы. Спіс такіх загалоўкаў:

  • x-request-id,
  • x-b3-traceid,
  • x-b3-spanid,
  • x-b3-parentspanid,
  • x-b3-sampled,
  • x-b3-flags,
  • x-ot-span-context.

Калі ў вас адзіная кропка, напрыклад, базавы кліент, у якім можна дадаць такую ​​логіку, тое ўсё выдатна, вам толькі трэба будзе дачакацца абнаўлення гэтай бібліятэкі ва ўсіх кліентаў. Але калі ў вас вельмі гетэрагенная сістэма і няма ўніфікацыі ў паходзе з сэрвісаў у сэрвісы па сетцы, то гэта хутчэй за ўсё будзе вялікай праблемай. Без дадання падобнай логікі ўся tracing інфармацыя будзе толькі "аднаузроўневай". Гэта значыць, мы атрымаем усе міжсэрвісныя ўзаемадзеянні, але яны не будуць склеены ў адзіныя ланцужкі праходу па сетцы.

Заключэнне

Istio падае зручную прыладу для збору tracing інфармацыі па сетцы, аднак трэба разумець, што для ўкаранення запатрабуецца адаптаваць сваю сістэму і ўлічыць асаблівасці рэалізацыі Istio. У выніку трэба вырашыць два асноўных моманту: вызначэнне пратакола прыкладнога ўзроўня (які павінен падтрымлівацца envoy proxy) і наладу пракіду інфармацыі аб злучанасці запытаў у сэрвіс ад запытаў з сэрвісу (з дапамогай header'ов, у выпадку HTTP пратаколу). Калі гэтыя пытанні вырашаны, мы атрымліваем магутны інструмент, які дазваляе празрыста збіраць інфармацыю з сеткі нават у вельмі гетэрагенных сістэмах, напісаных на мностве розных моў і фрэймворкаў.

У наступным артыкуле пра Service Mesh разгледзім адну з самых вялікіх праблем Istio - вялікае спажыванне аператыўнай памяці кожным sidecar проксі кантэйнерам і абмяркуем, як з ёй можна змагацца.

Крыніца: habr.com

Дадаць каментар