Istio service mesh не так прост, по крайне мере, с ним тоже бывают проблемы. В этом посте я бы хотел затронуть две из них, с которыми посчасливилось встретиться.
Что такое Istio? Концептуальное определение — service mesh, но, согласитесь, от этого понятнее не становится. Если говорить кратко, то под Истио можно понимать инфраструктурный уровень вашей системы, который отвечает за все сетевые активности. Это и взаимодействие разных сервисов друг с другом, это и балансировка нагрузки, это и https терминирование, это и сбор различных логов, телеметрии и Distributed tracing. В общем, этот продукт умеет очень много.
Если вы не знакомы с архитектурой Istio, то можете прочитать https://blog.newrelic.com/engineering/istio-service-mesh/ — эту обзорную статью, или посмотреть хороший доклад Тупые сервисы в умных сетях: деплоим как ниндзя при помощи Istio service mesh —
Почему Istio стал таким популярным? Вероятно, это связано с тем, что микросервисная архитектура захватила рынок бэкенд разработки, а еще — kubernetes стал уже своего рода Commodity — он есть у всех.
Раньше люди, даже внутри k8s, благополучно использовали ingress в связке с nginx, но, со временем, аппетиты росли. Кроме балансировки нагрузки и обратного прокси хотелось всё большего. Так и появился Istio, заменив собой привычнй nginx (для reverse proxy используется sidecar прокси Envoy).
Давайте теперь перейдем к тем проблемкам, с которыми я уже встретился вместе с Istio. Сразу хочу сказать, что виноват я сам, так как обо всём написано в документации.
В Istio можно настроить Circuit breaker функциональность, вообще не меняя код приложений. Например, можно ограничить максимальное число соединений, которое может быть одновременно установленно к вашему приложению. Делается это примерно так:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 trafficPolicy: connectionPool: tcp: maxConnections: 100
Этой конфигурацией мы ограничиваем число соединений до 100. Соответственно, если будет больше, чем 100, соединения будут автоматически отбрасываться.
Какую я встретил тут проблему? Установил какое-то маленькое значение, и потом забыл об этом месте. В результате, в системе часть запросов попросту не доходило — и я не сразу понял почему. Проблема в том, что это действие нигде не логируется, в случае срабатывания Circuit breaker (либо, я не нашёл, где есть логи). Собственно, будьте вниманительны при настройке этого значения.
Как мы обсудили выше, Istio для того, чтобы управлять системой, в каждый POD ваших приложений дополнительно устанавливает Sidecar контейнер. Важная мысль — этот Sidecar контейнер тоже кушает ресурсы, причём, вполне неплохо. Поэтому, вы должны мониторить не только потребление RAM или CPU ваших приложений, но и всех сайдкаров.
Сколько памяти и процессора выделяется по умолчанию, можно посмотреть тут — https://github.com/istio/istio/blob/master/install/kubernetes/helm/istio/values.yaml#L152:
# Resources for the sidecar. resources: requests: cpu: 100m memory: 128Mi limits: cpu: 2000m memory: 1024Mi
Как вы можете видеть, лимиты не такие уж и большие. По крайне мере, эту память можно легко съесть и получить завершенный контейнер с причиной Out of memory (OOM).
Кроме того, до появления OOM клиенты будут видеть крайне странные спецэффекты. В случае HTTP-сервисов, клиенты будут получать различные коды ошибок — 500, 501, 502, 503. Причём, в access logs вообще не будет этих запросов. Поэтому, отлаживать такую ситуацию крайне сложно.
Категории: Программирование