Як запусціць Istio, выкарыстоўваючы Kubernetes у production. Частка 1

Што такое Ісціё? Гэта так званы Service mesh, тэхналогія, якая дадае ўзровень абстракцыі над сеткай. Мы перахапляем увесь ці частку трафіку ў кластары і вырабляем пэўны набор аперацый з ім. Які менавіта? Напрыклад, які робіцца разумны роўтынг, або рэалізуемы падыход circuit breaker, можам арганізоўваць «canary deployment», часткова перамыкаючы трафік на новую версію сэрвісу, а можам абмяжоўваць вонкавыя ўзаемадзеянні і кантраляваць усе паходы з кластара ў вонкавую сетку. Ёсць магчымасць задаваць policy правілы для кантролю паходаў паміж рознымі мікрасэрвісамі. Нарэшце, мы можам атрымаць усю карту ўзаемадзеяння па сетцы і зрабіць уніфікаваны збор метрык цалкам празрыста для прыкладанняў.

Пра механізм працы можна прачытаць у афіцыйнай дакументацыі. Istio - гэта сапраўды магутная прылада, які дазваляе вырашыць мноства задач і праблем. У гэтым артыкуле я б хацеў адказаць на асноўныя пытанні, якія звычайна ўзнікаюць у пачатку працы з Istio. Гэта дапаможа вам разабрацца з ім хутчэй.

Як запусціць Istio, выкарыстоўваючы Kubernetes у production. Частка 1

Прынцып працы

Istio складаецца з двух асноўных зон - control plane і data plane. Control plane утрымоўвае ў сабе асноўныя кампаненты, якія забяспечваюць карэктную працу астатніх. У бягучай версіі (1.0) control plane мае тры асноўныя кампаненты: Pilot, Mixer, Citadel. Citadel мы разглядаць не будзем, ен патрэбен для генерацыі сертыфікатаў для забеспячэння працы mutual TLS паміж сэрвісамі. Давайце паглядзім падрабязней на прыладу і прызначэнне Pilot і Mixer.

Як запусціць Istio, выкарыстоўваючы Kubernetes у production. Частка 1

Pilot - гэта галоўны кіраўнік кампанент, які распаўсюджвае ўсю інфармацыю аб тым, што ў нас ёсць у кластары - сэрвісы, іх endpoint'ы і routing правілы (напрыклад, правілы для Canary deployment або правілы circuit breaker).

Mixer - апцыянальны кампанент control plane, які дае магчымасць збору метрык, логаў і любой інфармацыі аб сеткавым узаемадзеянні. Таксама ён сочыць за выкананнем Policy правілаў і захаваннем rate limit'аў.

Data plane рэалізуецца з дапамогай sidecar кантэйнераў-проксі. Па змаўчанні выкарыстоўваецца магутны проксі-сервер envoy. Ён можа быць заменены на іншую рэалізацыю, напрыклад nginx (nginmesh).

Для таго, каб Istio працаваў цалкам празрыста для прыкладанняў, есць сістэма аўтаматычнага inject'інга. Апошняя рэалізацыя падыходзіць для версій Kubernetes 1.9+ (mutational admission webhook). Для Kubernetes версіяў 1.7, 1.8 ёсць магчымасць выкарыстоўваць Initializer.

Sidecar кантэйнеры злучаюцца з Pilot па пратаколе GRPC, які дазваляе аптымізаваць мадэль пушынгу змен, якія адбываюцца ў кластары. GRPC пачаў выкарыстоўвацца ў Envoy пачынальна з версіі 1.6, у Istio ён выкарыстоўваецца з версіі 0.8 і ўяўляе з сябе pilot-agent абгортку на golang над envoy, якая канфігуруе параметры запуску.

Pilot і Mixer з'яўляюцца цалкам stateless кампанентамі, увесь стан трымаюць у памяці. Канфігурацыя для іх задаецца ў выглядзе Kubernetes Custom Resources, якія захоўваюцца ў etcd.
Istio-agent атрымлівае адрас Pilot і адчыняе GRPC stream да яго.

Як я ўжо сказаў, Istio рэалізуе ўсю функцыянальнасць цалкам празрыста для прыкладанняў. Давайце разбяромся як. Алгарытм такі:

  1. Дэплоім новую версію сэрвісу.
  2. У залежнасці ад падыходу injecting'а sidecar кантэйнера дадаюцца istio-init кантэйнер і istio-agent кантэйнер (envoy) на этапе прымянення канфігурацыі, альбо яны могуць быць ужо ўручную ўстаўлены ў апісанне Pod сутнасці Kubernetes.
  3. istio-init кантэйнер уяўляе з сябе скрыпт, які прымяняе правілы iptables для пода. Ёсць два варыянты для налады заварочвання трафіку ў istio-agent кантэйнер: выкарыстоўваць redirect правілы iptables, альбо TPROXY. На момант напісання артыкула па змаўчанні выкарыстоўваецца падыход з redirect правіламі. У istio-init ёсць магчымасць наладзіць які менавіта трафік трэба перахапляць і накіроўваць у istio-agent. Напрыклад, для таго, каб перахапляць увесь уваходны і ўвесь выходны трафік, трэба ўсталяваць параметры -i и -b у значэнне *. Можна пазначыць канкрэтныя парты, якія трэба перахапляць. Для таго, каб не перахапляць пэўную падсетку, можна паказаць яе з дапамогай сцяга -x.
  4. Пасля выканання init кантэйнераў, запускаюцца асноўныя, і ў тым ліку pilot-agent (envoy). Ён падлучаецца да ўжо разгорнутага Pilot па GRPC і атрымлівае інфармацыю аб усіх існых сэрвісах і routing палітыках у кластары. Па атрыманых дадзеных, ён канфігуруе cluster'ы і прапісвае ім непасрэдна endpoint'ы нашых прыкладанняў у Kubernetes кластары. Таксама неабходна адзначыць важны момант: envoy дынамічна наладжвае listeners (пары IP, port), якія пачынае слухаць. Таму, калі запыты ўваходзяць у pod, перанакіроўваюцца з дапамогай redirect iptables правіл у sidecar, envoy ужо паспяхова можа апрацоўваць гэтыя злучэнні і разумець, куды трэба далей праксіраваць трафік. Таксама на гэтым этапе адбываецца адпраўка інфармацыі ў Mixer, які мы разгледзім пазней, і адпраўка tracing span'аў.

У выніку мы атрымліваем цэлую сетку envoy проксі-сервераў, якія мы можам наладжваць з адной кропкі (Pilot). Усе inbound і outbound запыты праходзяць праз envoy. Прычым, перахапляецца толькі TCP трафік. Гэта значыць, што Kubernetes service IP рэзалвуецца з дапамогай kube-dns па UDP без змены. Затым ужо пасля рэзолву адбываецца перахоп выходнага запыту і апрацоўка envoy'ем, які ўжо вырашае на які endpoint трэба адправіць запыт (ці не адправіць, у выпадку палітык доступу ці спрацоўкі circuit breaker алгарытму).

З Pilot разабраліся, зараз трэба зразумець як працуе Mixer і навошта ён патрэбен. Прачытаць афіцыйную дакументацыю па ім можна тут.

Mixer у бягучым выглядзе ўяўляе з сябе два кампаненты: istio-telemetry, istio-policy (да версіі 0.8 гэта быў адзін кампанент istio-mixer). І той, і іншы ўяўляюць з сябе mixer, кожны з якіх адказваюць за сваю задачу. Istio telemetry прымае па GRPC ад sidecar кантэйнераў Report інфармацыю аб тым, хто куды ідзе і з якімі параметрамі. Istio-policy прымае Check запыты для праверкі задавальнення Policy правілам. Poilicy check праводзяцца, вядома, не на кожны запыт, а кэшуюцца на кліенце (у sidecar) на вызначаны час. Report check'і адпраўляюцца batch запытамі. Як наладжваць і якія менавіта параметры трэба адсылаць паглядзім крыху пазней.

Mixer мяркуецца як высокадаступны кампанент, які забяспечвае бесперабойную працу па зборцы і апрацоўцы telemetry дадзеных. Сістэма атрымліваецца ў выніку як шматузроўневы буфер. Першапачаткова дадзеныя буферызуюцца на баку sidecar кантэйнераў, затым на баку mixer і потым адпраўляюцца ў так званыя mixer backend'ы. У выніку, калі які-небудзь з кампанентаў сістэмы адмаўляе, буфер расце і пасля ўзнаўлення сістэмы мітусіцца. Mixer backend'ы ўяўляюць з сябе канчатковыя кропкі адпраўкі дадзеных аб тэлеметрыі: statsd, newrelic і тд. Можна напісаць свой backend, гэта дастаткова проста, і мы паглядзім як гэта зрабіць.

Як запусціць Istio, выкарыстоўваючы Kubernetes у production. Частка 1

Калі падсумаваць, схема працы з istio-telemetry такая.

  1. Сэрвіс 1 дасылае запыт у сэрвіс 2.
  2. Пры выхадзе з сэрвісу 1, запыт заварочваецца ў яго ж sidecar.
  3. Sidecar envoy сочыць за тым, як праходзіць запыт у сэрвіс 2 і падрыхтоўвае неабходную інфармацыю.
  4. Затым дасылае яе ў istio-telemetry з дапамогай Report запыту.
  5. Istio-telemetry вызначае, ці трэба дасылаць гэты Report у backend'ы, у якія менавіта і якія дадзеныя трэба адпраўляць.
  6. Istio-telemetry адпраўляе Report дадзеныя ў backend, калі гэта неабходна.

Цяпер паглядзім, як разгарнуць у сістэме Istio, які складаецца толькі з асноўных кампанентаў (Pilot і sidecar envoy).

Для пачатку паглядзім на асноўную канфігурацыю (mesh), якую чытае Pilot:

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-

    # пока что не включаем отправку tracing информации (pilot настроит envoy’и таким образом, что отправка не будет происходить)
    enableTracing: false

    # пока что не указываем mixer endpoint’ы, чтобы sidecar контейнеры не отправляли информацию туда
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004

    # ставим временной промежуток, с которым будет envoy переспрашивать Pilot (это для старой версии envoy proxy)
    rdsRefreshDelay: 5s

    # default конфигурация для envoy sidecar
    defaultConfig:
      # аналогично как rdsRefreshDelay
      discoveryRefreshDelay: 5s

      # оставляем по умолчанию (путь к конфигурации и бинарю envoy)
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"

      # дефолтное имя запущенного sidecar контейнера (используется, например, в именах сервиса при отправке tracing span’ов)
      serviceCluster: istio-proxy

      # время, которое будет ждать envoy до того, как он принудительно завершит все установленные соединения
      drainDuration: 45s
      parentShutdownDuration: 1m0s

      # по умолчанию используются REDIRECT правила iptables. Можно изменить на TPROXY.
      #interceptionMode: REDIRECT

      # Порт, на котором будет запущена admin панель каждого sidecar контейнера (envoy)
      proxyAdminPort: 15000

      # адрес, по которому будут отправляться trace’ы по zipkin протоколу (в начале мы отключили саму отправку, поэтому это поле сейчас не будет использоваться)
      zipkinAddress: tracing-collector.tracing:9411

      # statsd адрес для отправки метрик envoy контейнеров (отключаем)
      # statsdUdpAddress: aggregator:8126

      # выключаем поддержку опции Mutual TLS
      controlPlaneAuthPolicy: NONE

      # адрес, на котором будет слушать istio-pilot для того, чтобы сообщать информацию о service discovery всем sidecar контейнерам
      discoveryAddress: istio-pilot.istio-system:15007

Усе асноўныя кампаненты кіравання (control plane) размесцім у namespace istio-system у Kubernetes.

Мінімальна нам трэба разгарнуць толькі Pilot. Для гэтага скарыстаемся такой канфігурацыяй.

І наладзім уручную injecting sidecar кантэйнера.

Init container:

initContainers:
 - name: istio-init
   args:
   - -p
   - "15001"
   - -u
   - "1337"
   - -m
   - REDIRECT
   - -i
   - '*'
   - -b
   - '*'
   - -d
   - ""
   image: istio/proxy_init:1.0.0
   imagePullPolicy: IfNotPresent
   resources:
     limits:
       memory: 128Mi
   securityContext:
     capabilities:
       add:
       - NET_ADMIN

І sidecar:

       name: istio-proxy
       args:
         - "bash"
         - "-c"
         - |
           exec /usr/local/bin/pilot-agent proxy sidecar 
           --configPath 
           /etc/istio/proxy 
           --binaryPath 
           /usr/local/bin/envoy 
           --serviceCluster 
           service-name 
           --drainDuration 
           45s 
           --parentShutdownDuration 
           1m0s 
           --discoveryAddress 
           istio-pilot.istio-system:15007 
           --discoveryRefreshDelay 
           1s 
           --connectTimeout 
           10s 
           --proxyAdminPort 
           "15000" 
           --controlPlaneAuthPolicy 
           NONE
         env:
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         - name: INSTANCE_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
         - name: ISTIO_META_POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: ISTIO_META_INTERCEPTION_MODE
           value: REDIRECT
         image: istio/proxyv2:1.0.0
         imagePullPolicy: IfNotPresent
         resources:
           requests:
             cpu: 100m
             memory: 128Mi
           limits:
             memory: 2048Mi
         securityContext:
           privileged: false
           readOnlyRootFilesystem: true
           runAsUser: 1337
         volumeMounts:
         - mountPath: /etc/istio/proxy
           name: istio-envoy

Для таго, каб усё паспяхова запусцілася, трэба завесці ServiceAccount, ClusterRole, ClusterRoleBinding, CRD для Pilot, апісанні якіх можна знайсці тут.

У выніку сэрвіс, у які мы inject'ім sidecar з envoy, павінен паспяхова запусціцца, атрымаць увесь discovery з пілота і апрацоўваць запыты.

Важна разумець, што ўсе кампаненты control plane з'яўляюцца stateless прыкладаннямі і могуць быць без праблем гарызантальна маштабаваны. Усе дадзеныя ляжаць у etcd у выглядзе кастамных апісанняў рэсурсаў Kubernetes.

Таксама ў Istio (пакуль што эксперыментальна) ёсць магчымасць запуску па-за кластарам і магчымасць глядзець і мацаць service discovery паміж некалькімі Kubernetes кластарамі. Падрабязней пра гэта можна пачытаць тут.

Пры мультыкластарнай усталёўцы варта ўлічваць наступныя абмежаванні:

  1. Pod CIDR і Service CIDR павінны быць унікальныя па ўсіх кластарах і не павінны перасякацца.
  2. Усе Pod CIDR павінны быць даступныя ад любых Pod CIDR паміж кластарамі.
  3. Усе серверы Kubernetes API павінны быць даступныя адзін для аднаго.

Гэта пачатковыя звесткі, якія дапамогуць вам прыступіць да працы з Istio. Аднак ёсць яшчэ мноства падводных камянёў. Напрыклад, асаблівасці роўтынгу знешняга трафіку (вонкі кластара), падыходы да адладкі sidecar'аў, прафіляванне, настройка mixer і напісанне кастамнага mixer backend, настройка tracing механізму і яго праца з дапамогай envoy.
Усё гэта мы разгледзім у наступных публікацыях. Задавайце вашыя пытанні, пастараюся іх асвятліць.

Крыніца: habr.com

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