Фото Brian McGowan, Unsplash.com
Мы использовали Istio в продакшене почти два года, но больше не хотим. Я расскажу, чем мы недовольны и как выбрали другую service mesh.
Начнем с начала.
Зачем вообще нужна service mesh?
- Она мониторит трафик между микросервисами, включая схему взаимодействия и коды статусов HTTP между ними.
- Она позволяет добавлять mTLS, то есть шифрованный HTTP-трафик между сервисами.
Получается, всего две функции. Зато какие полезные.
Многие service mesh предлагают дополнительные фичи, например, разделение трафика, повторные попытки и т. д. Как по мне, не самые нужные функции. Во всяком случае для sidecar-proxy. Их часто используют не по назначению, чтобы закрыть проблемы, которые требуют другого решения.
Сложно ли использовать service mesh?
Да. Вы набьете немало шишек, пока не поймете, что:
Service mesh пока стабильно работает только для HTTP-трафика
Я работал с Istio и Linkerd, и обе вроде как должны поддерживать много разных протоколов, но на деле не все так радужно. Поддержка некоторых протоколов баз данных в Istio очень нестабильна в зависимости от версии. Linkerd не справляется с AMQP. И обе выдают странные ошибки для HTTPS. Видимо, написать прозрачный сетевой прокси не так-то просто. Пока я доверил бы service mesh только HTTP. С другой стороны, мне и не нужны другие протоколы для взаимодействия между сервисами Kubernetes.
Сетевые вызовы контейнера приложения не работают, если не запущен sidecar-прокси
Очень неприятная проблема, из-за которой я и считаю, что service mesh подходят не для всех сценариев. Если контейнер приложения запустится до sidecar-прокси, он не сможет выполнять запросы, для которых настроен sidecar-прокси.
Были какие-то разговоры о нативных sidecar в Kubernetes (чтобы помечать контейнер в поде как sidecar, который должен запускаться первым делом). Ожидалось, что они появятся в версии 1.20, но в итоге предпочтение отдали фичам, которые охватывают максимальное количество вариантов использования.
Обходные решения, конечно, есть, но тогда service mesh не будет полностью прозрачной для разработчика — придется менять код или деплой.
Init-контейнеры и cronjob не могут использовать service mesh
Почему? Контейнер прокси в service mesh никогда не завершает работу, а значит контейнеры init и cronjob никогда не выполняются до конца. В первом случае контейнер приложения так и не запустится, а во втором — время ожидания cronjob истечет и задание завершится ошибкой.
Для этого, вроде, тоже есть обходные пути, но я ни одного годного не встречал.
Использую ли я service mesh?
У меня получалось успешно использовать их в кластерах в продакшене и стейджинге в двух случаях: sidecar-прокси отслеживают только HTTP-трафик и mTLS настроен как необязательный (при этом условии под за пределами mesh может общаться с подом в mesh).
Я не использую service mesh в кластерах для ревью — запускать ревью приложений в service mesh слишком хлопотно.
Почему я удалил Istio?
Главная причина — его было очень сложно использовать. На изучение Istio у меня ушло примерно столько же времени, сколько на изучение Kubernetes.
Мне понадобилось несколько недель на конфигурацию Helm-чарта для деплоймента Istio (обычно я укладываюсь в один день).
Для Istio нужно слишком много CRD (Custom Resource Definition). Я стараюсь избегать их, чтобы не попадать в зависимость от вендора. У меня ушло много времени и сил, чтобы разобраться с CRD для основных ресурсов, вроде Gateway, VirtualService и DestinationRule, а в документацию приходилось заглядывать гораздо чаще, чем хотелось бы.
Если честно, я побаивался Istio. Это же огромная единая точка отказа. Самое ужасное у нас случилось, когда один из разработчиков неправильно назвал секрет Kubernetes с секретом TLS для шлюза. Все шлюзы сломались и потянули за собой весь кластер. Был такой баг, из-за которого Istio, не найдя нужный секрет, просто не настраивалась и переставала работать совсем. Мы чуть с ума не сошли, пока искали ошибку, — в логах на нее вообще ничего не указывало. Это не единственный случай, когда Istio полностью отказывает. Обычно это связано с передачей конфигурации в прокси Envoy. В документации это называется Break Glass Configuration (аварийная конфигурация).
Наконец самое важное — в Istio отказались от Helm в пользу собственной утилиты командной строки istioctl
… а потом снова вернули Helm. Я не хочу деплоить сорок с лишним инструментов поддержки на кластерах кучей разных методов, поэтому я расстроился, когда они прекратили поддержку Helm, который используется у меня в каждом втором инструменте. Еще больше я огорчился, когда все вернули назад и мне пришлось снова все восстанавливать, чтобы проапгрейдиться до последней версии Istio.
Почему я вообще выбрал Istio?
Когда Kubernetes только появился, у него было три главных конкурента — Mesos, Nomad и Swarm, но все очень быстро поняли, что Kubernetes победит.
Никогда не слышал, чтобы кто-то использовал Mesos (нелегко им пришлось без поддержки крупной корпорации), но знаю, что они сильно повлияли на оркестрацию контейнеров.
Swarm использовали чаще, но только потому, что он «проще», чем Kubernetes. Лично я не верил в успех этого проекта — за простотой на самом деле скрывался недостаток функционала. В Kubernetes все тоже несложно, если им не сильно пользоваться.
Nomad пока никуда не делся и, в принципе, неплохо работает с оркестрацией процессов прямо на серверах. Если вам нужна только оркестрация контейнеров, очень рекомендую Kubernetes.
В общем, когда появилась Istio, все было примерно так же. У неё был только один конкурент — Linkerd (который лично у меня почему-то ассоциировался со Swarm), при этом Istio тоже была детищем Google. Вот её я и выбрал.
А потом service mesh начали появляться, как грибы после дождя, — сначала AppMesh от AWS, потом Maesh от Traefik, потом Azure Open Service Mesh (название, видимо, намекает на то, что Istio упорно не входит в CNCF) и service mesh от Nginx. И это еще не все. Обычно для создания service mesh вендоры (например, Kuma и Consul Connect) используют прокси Envoy.
Явного победителя я тут не вижу.
Что я использую сейчас?
Сравнив несколько service mesh, я остановился на оригинале — Linkerd. Остальные варианты либо пытаются привязать меня к вендору, либо делают не то, что я хочу (например, Maesh добавляет прокси к ноде, а не к поду).
Что мне нравится в Linkerd:
- Она поддерживает деплои с Helm (правда, я использую модифицированную версию Helm и немного кастомного кода, чтобы избежать конфигурации вручную извне).
- С ней просто работать. Нужно только одно CRD, а Helm-чарт было легко освоить.
- У неё приятный дашборд. Istio использует Grafana/Promethus и Kiali. Linkerd тоже использует Grafana/Prometheus, а еще специальный кастомный дашборд, который легко использовать.
- Они написали собственный прокси на Rust (в версии 2). Сначала я засомневался, ведь Envoy так популярен, а потом понял, что так Linkerd стала только динамичнее. Envoy разросся до огромных размеров и пытается поддерживать очень много вендоров, а Linkerd вольны делать со своим прокси что захотят, и это серьезно ускоряет разработку. И все написано на Rust! Круто же?
- Они входят в CNCF. В отличие от Istio.
- Linkerd выбрали правильный подход. Istio сначала хватили лишнего с разными деплойментами, которыми нам приходилось управлять, а теперь перешли на единый деплоймент. Linkerd с этого начали. Другие деплойменты у них тоже есть, но не основные. Они добавляют новые фичи, но заботиться нужно только о главном деплойменте.
Что мне не нравится в Linkerd?
Всего одна мелочь, и та скорее про маркетинг — они заявляют, что service mesh можно установить и настроить всего за пять минут. Но, как вы понимаете, service mesh вряд ли можно назвать почти готовым решением. У Linkerd те же проблемы, что и у остальных, например, отсутствие нативных sidecar или ненадежная обработка других протоколов, кроме HTTP.
Заключение
Может быть, однажды мы перестанем заморачиваться выбором service mesh — как сейчас мало кто знает, какую оверлейную сеть он использует с Kubernetes. Каждая service mesh внедряет SMI (Service Mesh Interface), так что когда-нибудь, будем надеяться, service mesh станет просто нативным ресурсом в Kubernetes. Принятие открытых стандартов — первый шаг в этом направлении.
Мне не нравится, что Istio нет в CNCF, и объяснения Криса Дибоны (Chris DiBona) в Kubernetes Podcast меня не переубедили.
Linkerd входит в CNCF, и если они не будут ничего усложнять, я планирую пока остаться с ними.
Жду с нетерпением, когда в Kubernetes появится нативное решение для sidecar.