Как я отлаживал одну очень странную ситуацию
Я.Облако: наш облачный провайдер, в котором и происходит все действие
Metabase: наш главный герой. Это такая BI-система, которая позволяет делать всякие красивые визуализации в реальном времени. Для получения этих самых данных она умеет подключаться к различным источникам
PostgreSQL: или просто PG. В представлении не нуждается. В нашей истории представлен как managed-сервис в виде облачного кластера
Kubernetes: он же k8s. Оркестратор, в котором крутится вышеозначенный метабейс
Итак, некоторое время назад наши дата-сатанисты попросили меня развернуть метабейс, потому что он им был нужен для каких-то темных дата-ритуалов. Я посмотрел, сложного ничего, говорю, будет сделано.
А мы, как раз, ввели в эксплуатацию еще один k8s-кластер как раз под всякие подобные штуки. Туда я его и решил затащить.
Пару слов о сетапе: в одном каталоге (назовем его app) облака расположен источник данных в виде нашего PG, там же есть кубернетес для всяких непродакшеновых нужд. В другом каталоге облака (назовем его infra) расположен еще один кластер k8s, который является целевым для нашего метабейса. Прямой сетевой связности между ними нет, но есть VPN в виде site-to-site ipsec StrongSwan
Так вот, метабейс умеет хранить свою служебную инфу либо в h2, это такая его встроенная БД на файлах, для продакшена не рекомендуется, либо в mysql или в PG. Для проверки я развернул его на h2 в app-кластере, подключил PG как источник данных, посмотрел, все ок. Отдал дата-сатанистам, они дали добро, все хорошо.
Ну в общем беру его я, готовлю уже продакшен-сетап, переношу его в infra-кластер, подцепляю к нему его собственный PG для хранения служебной инфы, проверяю коннект к другому каталогу, все отлично. Отдаю ds-команде и с чувством выполненного долга ухожу делать другие задачи
И буквально вот вчера, за окном пятница, приходят ко мне ребята из DS и говорят: беда, метабейс не видит схему данных. То есть к бд он цепляется нормально, но в ответ на попытку посмотреть схему, говорит буквально следующее:
Опачки. В понедельник уже должна быть презентация красивых визуализаций, а оно схему не видит.
При этом в метабейсе есть возможность сделать прямой запрос к БД и если там набрать буквальноSELECT * FROM table_name;
то все работает норм, данные возвращаются, все отлично. То есть таблички он видит, базу он видит, но почему-то не хочет показывать схему.
А надо сказать, что схему он показывает в виде таких больших кнопок с названиями таблиц и с помощью этих кнопок строятся дашборды. То есть без схемы этой совсем никак.
Ну и непонятно, конечно, почему он все-таки говорит, что таблиц нет, хотя они есть и он явно про это в курсе
Иду в настройки, делаю принудительный синк, одновременно смотрю в логи. Вижу, что синк запускается, но не заканчивается. Ну то есть там несколько этапов, один из них называется sync_metadata , это вот ровно оно и есть. Все остальные этапы помечены как started и finished, а этот нет.
Примерно минут через 40 это синк падает с ошибкойPSQLException: An I/O error occured while sending to the backend.
Несколько часов уходит на извращения с helm-чартом в самых разных вариантах, изменение уровня логирования (я теперь знаю очень много про log4j, я и раньше знал, но там много всего добавилось😁), адское гугление и чтение форумов. Проблема появляется у многих, но все предложенные решения не работают
Так, задета моя профессиональная гордость, оставить это я уже не могу.
Ко мне приходит светлая мысль, что что-то не так со служебным PG, так как я вижу, что туда попадает информация о бд (креды, IP и все вот это), но нет информации о схеме. При этом на тестовом сетапе с h2 все работало. Решаю сделать с h2 чтобы проверить. Разворачиваю метабейс в инфра-кластере с h2, и... хрен там, ничего не получается. Схемы нет. Я начинаю чувствовать, что схожу с ума
8 вечера, пятница, я сижу с блокнотом и прикидываю, что у нас есть:
- Все работает как надо, когда приложение и сервис в одном каталоге
- Все не работает как надо, когда они в разных. Но при этом сетевая связность есть в обе стороны и консольный клиент PG работает отлично
Внимательно смотрю на кластеры, в чем еще может быть разница? Агашечки, на апп-кластере стоит nginx как ingress-контроллер, а в инфра-кластер мы затащили Istio на посмотреть, насколько он хорош (очень хорош🤗). Так блин, неужели дело в этом? Собираюсь уже затаскивать nginx и в инфра-кластер, но тут решаю на шару прицепить к метабейсу БД из его же каталога как источник данных.
Voilà! Все работает хорошо, схема есть.
Так, значит дело не в бобине не в истио, почему-то метабейс не может пробиться в другой каталог. Причем проблема именно в нем, консольный клиент же работает нормально, вы помните? И схему показывает, и селекты дергает. А метабейс, судя по i/o error просто теряет коннект. Но почему он его теряет?! Почему он не выгребает данные сразу, как это делает psql?
Думаю про какие-то перемудренные таймауты постгреса (хотя какие, к херам, таймауты? Эти вмки если не в одной стойке, то в одном ДЦ точно), закапываюсь в доки по постгресу, ничего не помогает 🤷♂️ Схемы нет
Так, исключили проблемы с БД, очевидно, что метабейс не пролезает через ipsec, но блин, почему? Консольный клиент пролезает, а этот нет. Пишу тестовое приложение на джаве с тем же драйвером, который использует метабейс. Все ок, все работает. Приложение, в смысле. Метабейс — нет.
Пытаюсь понять, в каком еще юзкейсе можно смоделировать поведение, аналогичное метабейсу, но без его участия? Ну конечно, банальный полный дамп данных. Поднимаю jump-pod рядом с метабейсом, запускаю pg_dump ииии....
Да, детка! pg_dump тоже зависает и падает с таймаутом. При этом таки показав мне, на чем таки оно валится.
Уберите детей от экранов, валится оно вот на этом:
Да.. я бы тоже упал конечно. Подозрение с метабейса снято. Выглядит все это очень страшно, но таки делать с этим что-то надо. Решаю проверить все это добро у себя на локалке (у меня тоже поднят VPN до Яндекса, но уже не StrongSwan s2s, а банальный OpenVPN)
Все пролетает просто прекрасно. Значит дело не в VPN в принципе, а в конкретном ipsec-е, который соединяет наши два каталога. Время 22.30, я провел в этой отладке уже семь с половиной часов.
Иду прогуляться, чувствую себя идиотом. На пятом круге, навернутом вокруг дома ясно понимаю (💡), что именно надо попробовать! Залетаю домой и не раздеваясь бросаюсь к ноутбуку. Короткая команда на обоих концах туннеля, и...
Оргазм по сравнению с этим ощущением — жалкая пародия на удовольствие. Меня реально отпустило, гора упала с плеч, профессиональная гордость вернулась к привычным размерам)
Таки чтоже это была за команда?
MTU (или maximum transmission unit) это максимальный размер блока данных в байтах, который может быть передан через сетевой слой без фрагментации. Его чрезмерное увеличение влияет на производительность, а чрезмерное уменьшение вытворяет вот такие штуки с трафиком.
Дада, друзья :) IPSec откусывает немножко от MTU и в дефолтное свое значение 1500 трафик может и не пролезть. Я задрал с запасом до 1650 и все полетело. Вообще, MTU можно довольно точно рассчитать, но после 8 часов деьага я на это не способен. Я честно скажу, я пока не понимаю, почему именно этот поток данных не пролез в ipsec, почему все остальное работало норм, с этим я разберусь потом :) После 8 часов жесткой отладки я уже не способен на интеллектуальные упражнения
А сейчас самое главное, что проблема исправлена, можно спокойно закрывать ноут и ложиться спать. По горячим следам я написал эту заметку, потом обязательно дополню более подробным исследованием на тему MTU
Всем спасибо за внимание! Приходите ко мне в телеграм-канал @happy_devops, там еще много интересного :)