Service Mesh¶
Service Mesh - инфраструктурный слой, который берёт на себя общение сервис-сервис: маршрутизацию, retry, mTLS, метрики. Делает он это через прокси рядом с каждым сервисом, в коде сервиса этой логики нет.
Зачем: раньше retry, timeout, circuit breaker и discovery жили в библиотеках внутри сервиса (Netflix OSS: Hystrix, Ribbon, Eureka-клиент). Библиотека своя под каждый язык, и обновлять её надо в каждом сервисе. Mesh выносит эту логику из процесса в прокси, одинаковый для всех языков.
Как устроено¶
- Data plane - прокси рядом с каждым сервисом, через него идёт весь входящий и исходящий трафик. Классически это sidecar-контейнер с Envoy в каждом поде. У Linkerd свой прокси на Rust
- Control plane - раздаёт прокси политики, маршруты и сертификаты. В Istio это
istiod, конфиг он отдаёт прокси по xDS API
Сервис думает, что зовёт http://orders, а на деле упирается в локальный прокси. Прокси и делает mTLS, retry, timeout
и маршрутизацию.
под orders под payments
+----------------------+ +----------------------+
| app --> proxy | -- mTLS --> | proxy --> app |
| (Envoy) | | (Envoy) |
+----------------------+ +----------------------+
^ ^
+---------- control plane -----------+
(политики, сертификаты, маршруты)
Mesh опирается на service discovery: control plane берёт список живых инстансов из registry
(в Kubernetes - из EndpointSlice) и раздаёт его прокси. Discovery отвечает, где живёт сервис, mesh - как до него
дойти.
Sidecar - общий паттерн вспомогательного контейнера рядом с основным (Burns и Oppenheimer, 2016). Прокси меша - лишь один его случай.
Без sidecar. Прокси на каждом поде стоит памяти и CPU, поэтому появились режимы без sidecar. В Istio ambient mode ztunnel на каждой ноде держит L4 и mTLS, а L7-политики обрабатывает отдельный waypoint-прокси. Cilium делает mesh на eBPF в ядре и одном Envoy на ноду для L7.
Команды:
kubectl get pods # READY 2/2 - в поде app и sidecar-прокси
istioctl proxy-status # получили ли прокси конфиг от control plane
linkerd viz stat deploy # RPS, доля успешных запросов и латентность по сервисам, снятые прокси
Что даёт¶
- mTLS между сервисами. Взаимная аутентификация по сертификатам, ротация без участия сервиса. Это identity, а не authz: mTLS доказывает, кто звонит, но не что ему можно (см. Безопасность).
- Retry, timeout, circuit breaking. Политикой в конфиге, а не библиотекой в каждом сервисе (см. Устойчивость).
- Канареечные и weighted-маршруты. «5% трафика на v2» правится в конфиге меша (см. Деплой-стратегии).
- Observability. Прокси видит весь трафик и отдаёт метрики и спаны по каждому хопу (см. Наблюдаемость).
Mesh ведёт трафик между сервисами (east-west). Вход снаружи (north-south) держит API Gateway, у Istio для этого есть свой ingress gateway.
Цена и когда окупается¶
- Сложность. Control plane, инъекция sidecar, CRD политик - ещё одна большая система в эксплуатации.
- Латентность. Каждый вызов проходит через два прокси. Обычно это единицы миллисекунд, но они есть.
- Ресурсы. Sidecar на каждый под, память и CPU умножаются на число подов.
Mesh окупается на десятках сервисов, когда нужен mTLS везде и единые политики retry и timeout без правки кода. На трёх сервисах накладные расходы не окупятся: те же retry и timeout дешевле прописать библиотекой.
Технологии¶
| Технология | Как устроен | Когда брать |
|---|---|---|
| Istio | Envoy-sidecar или ambient mode, control plane istiod |
Нужны сложные политики трафика |
| Linkerd | Свой лёгкий прокси на Rust | Нужны в основном mTLS и метрики, важна простота |
| Consul service mesh | Envoy-sidecar, registry и mesh в одном продукте | Сервисы и в Kubernetes, и на виртуальных машинах |
| Cilium Service Mesh | eBPF в ядре, без sidecar | Cilium уже стоит сетевым плагином Kubernetes |
| Kuma | Envoy-sidecar, проект CNCF от Kong | Kubernetes и виртуальные машины, несколько кластеров |