Какво представлява ? Это так называемый Service mesh, технология, которая добавляет уровень абстракции над сетью. Мы перехватываем весь или часть трафика в кластере и производим определенный набор операций с ним. Какой именно? Например, делаем умный роутинг, или реализуем подход circuit breaker, можем организовывать «canary deployment», частично переключая трафик на новую версию сервиса, а можем ограничивать внешние взаимодействия и контролировать все походы из кластера во внешнюю сеть. Есть возможность задавать policy правила для контроля походов между разными микросервисами. Наконец, мы можем получить всю карту взаимодействия по сети и сделать унифицированный сбор метрик полностью прозрачно для приложений.
За механизма на работа може да се прочете в . Istio е наистина мощен инструмент, който позволява да се решат множество задачи и проблеми. В тази статия бих искал да отговоря на основните въпроси, които обикновено възникват в началото на работата с Istio. Това ще помогне да се запознаете с него по-бързо.

Принцип на работа
Istio се състои от две основни зони — control plane и data plane. Control plane съдържа основните компоненти, които осигуряват правилната работа на останалите. В текущата версия (1.0) control plane има три основни компонента: Pilot, Mixer, Citadel. Citadel няма да обсъждаме, той е необходим за генериране на сертификати за осигуряване на mutual TLS между услугите. Нека погледнем по-детайлно устройството и предназначението на Pilot и Mixer.

Pilot е главният управляващ компонент, който разпространява цялата информация за това, което имаме в кластера – услуги, техните endpoint’и и правила за routing (например, правила за Canary deployment или правила circuit breaker).
Mixer е опционален компонент на control plane, който предоставя възможност за събиране на метрики, логове и всяка информация за мрежовото взаимодействие. Той също така следи за спазването на Policy правилата и спазването на rate limit’ите.
Data plane се реализира с помощта на sidecar контейнери-прокси. По подразбиране се използва мощният . Той може да бъде заменен с друга реализация, например nginx (nginmesh).
За да работи Istio напълно прозрачно за приложенията, съществува система за автоматично inject’ване. Последната реализация е подходяща за версии на Kubernetes 1.9+ (mutational admission webhook). За версии на Kubernetes 1.7, 1.8 има възможност за използване на Initializer.
Sidecar контейнерите се свързват с Pilot по протокола GRPC, който позволява оптимизиране на модела за push на измененията, настъпващи в кластера. GRPC започва да се използва в Envoy, започвайки от версия 1.6, в Istio се използва от версия 0.8 и представлява pilot-agent — обвивка на golang над envoy, която конфигурира параметрите на стартиране.
Pilot и Mixer са напълно stateless компоненти, всички състояния се съхраняват в паметта. Конфигурацията за тях се задава под формата на Kubernetes Custom Resources, които се съхраняват в etcd.
Istio-agent получава адреса на Pilot и отваря GRPC stream към него.
Както вече казах, Istio реализира цялата функционалност напълно прозрачно за приложенията. Нека разберем как. Алгоритъмът е такъв:
- Деплоим нова версия на услугата.
- В зависимост от подхода за инжектиране на sidecar контейнера, се добавят istio-init контейнер и istio-agent контейнер (envoy) по време на прилагане на конфигурацията, или те могат да бъдат вече ръчно добавени в описанието на Pod съществото в Kubernetes.
- istio-init контейнерът представлява скрипт, който прилага правила iptables за пода. Има два варианта за конфигуриране на завиването на трафика в istio-agent контейнера: да се използват правила за пренасочване iptables, или . Към момента на написване на статията по подразбиране се използва подход с правила за пренасочване. В istio-init има възможност да се настрои какъв точно трафик трябва да бъде прихванат и насочен в istio-agent. Например, за да прихванете целия входящ и целия изходящ трафик, трябва да зададете параметри
-iи-bна стойността*. Можете да зададете конкретни портове, които да бъдат прихванати. За да не прихващате определена подсеть, можете да я зададете с помощта на флага-x. - След изпълнението на init контейнерите, се стартират основните, включително pilot-agent (envoy). Той се свързва с вече разгръщания Pilot по GRPC и получава информация за всички съществуващи услуги и routing политики в клъстера. На базата на получените данни, той конфигурира cluster-и и записва директно endpoint-ите на нашите приложения в Kubernetes клъстера. Също така е необходимо да се отбележи важен момент: envoy динамично настройва listeners (попарите IP, port), които започва да слуша. Така, когато заявките влизат в pod, те се пренасочват с помощта на правила за пренасочване iptables в sidecar, envoy вече успешно може да обработва тези връзки и да разбира къде да проксирва трафика. На този етап също така се изпраща информация в Mixer, който ще разгледаме по-късно, и се изпращат tracing span-ове.
В резултат получаваме цяла мрежа от envoy прокси-сървъри, които можем да конфигурираме от една точка (Pilot). Всички входящи и изходящи заявки преминават през envoy. Освен това, се прихваща само TCP трафик. Това означава, че IP на Kubernetes услугата се резолвира с помощта на 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. Policy check се провеждат, разбира се, не на всяка заявка, а се кешират на клиента (в sidecar) за определено време. Report check-ове се изпращат партидно. Как да настроим и какви точно параметри трябва да се изпращат, ще разгледаме по-късно.
Mixer е проектиран като компонент с висока наличност, който осигурява непрекъсната работа по събиране и обработка на telemetry данни. Системата в крайна сметка представлява многослойен буфер. Първоначално данните се буферират на страната на sidecar контейнерите, след това на страната на mixer и после се изпращат в така наречените mixer backend-ове. В крайна сметка, ако някой от компонентите на системата се провали, буферът нараства и след възстановяване на системата се изпразва. Mixer backend-овете представляват крайните точки за изпращане на данни за телеметрия: statsd, newrelic и т.н. Може да напишете свой собствен backend, това е достатъчно просто, и ние ще разгледаме как да го направим.

Ако обобщим, схемата на работа с istio-telemetry е следната.
- Сервис 1 изпраща заявка на сервис 2.
- При излизане от сервис 1, заявката се обгръща в неговия собствен sidecar.
- Sidecar envoy следи как протича заявката към сервис 2 и подготвя необходимата информация.
- След това я изпраща в istio-telemetry с помощта на Report заявка.
- Istio-telemetry определя дали да изпрати този Report в backend-овете, в кои точно и какви данни да изпрати.
- 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: |-
# Временно отключаем отправку информации о трассировке (Pilot настроит envoy’и так, что отправка не будет происходить)
enableTracing: false
# Временно не указываем конечные точки mixer, чтобы контейнеры sidecar не отправляли информацию туда
#mixerCheckServer: istio-policy.istio-system:15004
#mixerReportServer: istio-telemetry.istio-system:15004
# Устанавливаем временной промежуток, с которым будет envoy переспрашивать Pilot (это для старой версии envoy proxy)
rdsRefreshDelay: 5s
# Конфигурация по умолчанию для envoy sidecar
defaultConfig:
# Аналогично rdsRefreshDelay
discoveryRefreshDelay: 5s
# Оставляем по умолчанию (путь к конфигурации и бинарю envoy)
configPath: "/etc/istio/proxy"
binaryPath: "/usr/local/bin/envoy"
# Дефолтное имя запущенного контейнера sidecar (используется, например, в именах сервиса при отправке трассировок)
serviceCluster: istio-proxy
# Время, которое будет ждать envoy до принудительного завершения всех установленных соединений
drainDuration: 45s
parentShutdownDuration: 1m0s
# По умолчанию используются правила REDIRECT iptables. Можно изменить на TPROXY.
#interceptionMode: REDIRECT
# Порт, на котором будет запущена админ панель каждого контейнера sidecar (envoy)
proxyAdminPort: 15000
# Адрес, по которому будут отправляться трассировки по протоколу 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. За това ще използваме
И ще настроим ръчно внедряването на контейнера sidecar.
Init контейнер:
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:
име: istio-proxy
аргументи:
- "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:
- име: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- име: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- име: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- име: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- име: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
изображение: istio/proxyv2:1.0.0
imagePullPolicy: IfNotPresent
ресурси:
requests:
cpu: 100m
памет: 128Mi
limits:
памет: 2048Mi
securityContext:
privileged: false
readOnlyRootFilesystem: true
runAsUser: 1337
volumeMounts:
- mountPath: /etc/istio/proxy
name: istio-envoy
За да стартирате успешно всичко, е необходимо да създадете ServiceAccount, ClusterRole, ClusterRoleBinding и CRD за Pilot, описанията на които можете да намерите. .
В резултат на това, услугата, в която инжектираме sidecar с envoy, трябва успешно да стартира, да получи всички discovery от пилота и да обработва заявки.
Важно е да се разбере, че всички компоненти на control plane са stateless приложения и могат лесно да бъдат хоризонтално мащабируеми. Всички данни се съхраняват в etcd под формата на персонализирани описания на ресурсите на Kubernetes.
Също така, в Istio (все още експериментално) има възможност за стартиране извън кластера и възможност за наблюдение и споделяне на service discovery между няколко Kubernetes кластера. Повече информация можете да прочетете. .
При мултикластерна инсталация е необходимо да се вземат предвид следните ограничения:
- Pod CIDR и Service CIDR трябва да бъдат уникални за всички клъстери и не трябва да се пресичат.
- Всички Pod CIDR трябва да бъдат достъпни от всякакви Pod CIDR между клъстерите.
- Всички Kubernetes API сървъри трябва да бъдат достъпни един за друг.
Това са основните сведения, които ще ви помогнат да започнете работа с Istio. Обаче има още много подводни камъни. Например, особености на маршрутизацията на външния трафик (навън от клъстера), подходи за отстраняване на грешки в sidecar-ите, профилиране, настройка на mixer и написване на персонализиран mixer backend, настройка на tracing механизъм и неговата работа с envoy.
Всичко това ще разгледаме в следващите публикации. Питайте вашите въпроси, ще се постарая да ги осветя.
Източник: habr.com
