Есть у меня несколько проектов, которые начинались как шутка в чате про Kubernetes и почему-то не остановились. Например, Sheeternetes родился из спора о том, можно ли сделать оркестратор контейнеров в электронной таблице, и оказалось, что можно. Tatarnetes вырос из желания, чтобы kubectl заговорил по-татарски (и из татарских мемов). Kyvernetria попыталась честно ответить на вопрос, как выглядел бы Kubernetes, если бы его поведение строилось на подтверждённых наукой средних различиях между мужчинами и женщинами, а не на стереотипах. Ну а Mansplainetes и Misogynetes появились как сатира на тех, кто в такие стереотипы свято верит.

Всё это время проекты жили на уровне «работает, но у меня на ноутбуке». В эти выходные я наконец довёл их до нормальных релизов, и их набралось сразу семь. Расскажу, что в каждом нового и почему некоторые из этих шуток, к моему собственному удивлению, оказались полезными.

Небольшой дисклеймер: для это не просто шуточные проекты, я много думаю о том, как могла бы выгялдеть инфраструктуруа сегодняшнего и завтрашнего дня, каким мог бы быть Kubernetes, если бы его перепридумали сейчас с нуля и т.д. То есть лично для меня это серьезные эксперименты с UX/DX этих систем, проверка разных идей и концепций и попытка понять, какой могла бы быть (или все еще может быть) инфраструктура будущего.

Sheeternetes on-prem: оркестратор, которому больше не нужен Google

Напомню, как устроен Sheeternetes. Роль etcd в нём играет электронная таблица, в которой вкладки соответствуют деплойментам, нодам и подам, а агент на каждой машине раз в несколько секунд заглядывает в таблицу и запускает контейнеры, которые в ней хранятся (да, прямо в ячейках). Изначально всё это работало только поверх Google Sheets, и один из пользователей очень вежливо написал нам, что такая жёсткая привязка к одному вендору его смущает.

Возразить было нечего. Фонд, который громче всех говорит о вендор-нейтральности, не может держать всех своих пользователей в заивисимости от одной корпорации. Поэтому в первом релизе on-prem-версии кластер можно хранить в файле Excel, в документе LibreOffice или просто в папке с CSV-файлами. Последний вариант мне нравится больше всего, потому что такую папку можно синхронизировать через Syncthing или Nextcloud, и тогда у вас получается распределённое хранилище состояния кластера вообще без сервера.

SheetGate, или как достучаться до пода снаружи

До сих пор у Sheeternetes была неприятная особенность: всё, что вы в нём запускали, было недоступно снаружи. Контейнеры видели друг друга, а вот пользователь с внешнего контура до них добраться не мог. Новый релиз решает это следующим образом.

Сначала у деплоймента появилась ячейка с портами. Если написать туда 8080:80, контейнер будет опубликован на порту 8080 хоста, а если указать только порт контейнера, свободный порт хоста подберётся сам. Планировщик теперь считает занятые порты таким же ресурсом, как процессор и память, поэтому две реплики никогда не сядут на один и тот же порт одной ноды.

Далее как развитие идеи появился SheetGate, наш ответ Ingress и Gateway API. В таблице добавились вкладки со шлюзами и маршрутами. Вы пишете в строку хост, путь и имя сервиса, а Sheeternetes сам поднимает nginx, генерирует для него конфигурацию и перезагружает её без остановки, как только вы поменяли ячейку. Результат каждого маршрута записывается обратно в таблицу, так что по соседней колонке сразу видно, принят ли маршрут или сервис, на который он ссылается, не существует.

Шлюзы и маршруты в Sheeternetes вместе со статусами
Шлюзы и маршруты в Sheeternetes вместе со статусами
Те же маршруты прямо во вкладке таблицы
Те же маршруты прямо во вкладке таблицы

Снаружи это выглядит как самый обычный веб-сервер. Один и тот же адрес отдаёт разные приложения в зависимости от имени хоста или пути, а если сервиса, на который указывает маршрут, в кластере нет, шлюз честно отвечает ошибкой 502.

Запросы через SheetGate по имени хоста и по пути
Запросы через SheetGate по имени хоста и по пути

Первым, что мы вывели наружу через SheetGate, был, разумеется, DOOM. Его образ тоже хранится в ячейках таблицы, поэтому получилась красивая цепочка: таблица хранит игру, таблица планирует её запуск и таблица же решает, по какому адресу до неё можно добраться.

DOOM, образ которого хранится в ячейках таблицы
DOOM, образ которого хранится в ячейках таблицы

Пока мы это делали, нашёлся и настоящий, совсем не смешной баг. Сервер API обрабатывал запросы параллельно, и иногда один запрос читал файл таблицы в тот момент, когда другой её ещё дописывал. Однажды это даже обрезало демонстрационный файл. Теперь доступ к таблице идёт строго по очереди, а сохранение атомарное, через временный файл.

Tatarnetes: татарский kubectl дополняет, объясняет и говорит с таблицами

Tatarnetes состоит из трёх частей. Это ayda, обёртка над kubectl с татарскими командами, TatarOS, такая же обёртка над Talos, и дашборд в национальном стиле, с ковром на фоне и обязательными перерывами на чай. Все три вышли одновременно, и в каждом есть что показать.

Свежий апстрим, проверенный на настоящих бинарниках

Tatarnetes привязан к версиям Kubernetes и Talos, поэтому теперь мы рекомендуем использовать Kubernetes 1.37.1 и Talos 1.14.1. Обновляя версии, мы не стали просто менять цифры в файле, а скачали настоящие kubectl и talosctl и прогнали через них весь словарь. Выяснилось, что часть команд в апстриме переименованы или убраны ещё несколько версий назад, а некоторые наши татарские слова всё это время указывали в пустоту. Например, в Talos команды для дисков больше нет, а в kubectl с версии 1.35 команде exec обязательно нужен разделитель перед командой внутри контейнера. Но в новой версии словарь снова совпадает с реальностью, а на забытый разделитель ayda дает подсказку на татарском.

Автодополнение по-татарски

Самое приятное нововведение для тех, кто пользуется ayda каждый день (эй, татары, чего притихли? никто не поставил tatarnetes в прод?). Набираете «күр», нажимаете Tab и получаете «күрсәт», то есть «показать». Следующий Tab предложит тип ресурса, а ещё один подставит имя настоящего пода из вашего кластера. Работает в bash, в zsh и как дополнение плагина kubectl, причём в той письменности, которую вы выбрали: кириллице, латинице или арабице.

Автодополнение ayda: от «күр» до имени пода
Автодополнение ayda: от «күр» до имени пода

Отдельно пришлось позаботиться о том, чтобы Tab не зависал. Если кластер недоступен, ayda ждёт ответа не больше двух секунд и просто перестаёт предлагать имена, а не держит вас перед мигающим курсором.

Одна и та же команда в трёх письменностях
Одна и та же команда в трёх письменностях

Команда «аңлат»

Вторая новая команда называется «аңлат», то есть «объясни». Это татарский аналог kubectl explain, но с одной особенностью. Сначала ayda рассказывает, что такое ресурс, словами из татарского IT-глоссария, который мы собирали для проекта, а уже потом показывает настоящую схему полей из Kubernetes. Можно спросить и про конкретное поле, например про spec у пода.

Команда «аңлат»: сначала глоссарий, потом схема из Kubernetes
Команда «аңлат»: сначала глоссарий, потом схема из Kubernetes

Тут, правда, пришлось сломать обратную совместимость. Раньше слово «аңлат» означало describe, и тем, кто к этому привык (такие ведь есть?), а сейчас вместо этого нужно писать «сөйлә» или «тасвирла». Если по старой привычке набрать «аңлат» с именем пода, ayda не выполнит ничего неожиданного, а подскажет, какое слово теперь нужно.

Дашборд показывает живой кластер

До этого релиза дашборд Tatarnetes был красивой демонстрацией на выдуманных данных. Теперь его можно подключить к настоящему кластеру через kubectl proxy, и он покажет поды, ноды, сервисы, деплойменты и события. Токены при этом в браузер не попадают, дашборд разговаривает только с прокси на том же адресе. Для пустого кластера, отказа в доступе и потерянного соединения есть отдельные экраны на татарском и английском, а демонстрационный режим по-прежнему включается по умолчанию.

Живой кластер в дашборде Tatarnetes
Живой кластер в дашборде Tatarnetes

Перерыв на чай, конечно, никуда не делся, и во время него дашборд даже не обращается к кластеру. Заодно я заменил надпись на шамаиле, который показывается во время чаепития: теперь там написано «Хуш килдегез», то есть «добро пожаловать».

Перерыв на чай и новый шамаиль
Перерыв на чай и новый шамаиль

Два фонда наконец заговорили на одном языке

А еще ayda теперь умеет управлять не только Kubernetes, но и sheeternetes-кластером в таблице, причём с помощью все тех же татарских команд. Если включить нужный режим, «күрсәт төеннәр» покажет ноды Sheeternetes, а новая команда «күчер», то есть «перенеси», переселит под на другую ноду. Всё, чего Sheeternetes не умеет, ayda честно отказывается выполнять и объясняет почему.

Ayda управляет кластером в таблице
Ayda управляет кластером в таблице

Так у двух междуранродных фондов появился общий язык, и это татарский.

Kyvernetria: как запускать новый сервис, если думать о нём как о ребёнке

Kyvernetria остаётся самым серьёзным из этих проектов. Это сборка Kubernetes, в которой каждый поведенчсеский паттерн основан на подтверждённых исследованиями сьтатистически значимых различиях между полами, причём каждое утверждение сверено с первоисточником и описано в отдельном документе. Того, что наукой не подтверждается, в проекте нет принципиально.

Этот релиз стал первым официальным релизом Kyvernetria, и в него вошли три новые фичи.

Gestation: резерв, роды и выхаживание

Главная из них называется Gestation. Это жизненный цикл запуска нового сервиса, построенный на метафоре беременности, родов и ухода за новорождённым. Я долго искал, как показать эту тему в Kubernetes, и в какой-то момент понял, что метафора ложится на вполне реальную проблему. Новый сервис особенно хрупок в первые дни после запуска, а в Kubernetes нет ничего, что вело бы его от «скоро запускаем» до «стабильно живёт».

Всё начинается с зачатия. Команда kyvctl conceive создаёт описание будущего сервиса с датой «родов» и заранее резервирует под него место. Делается это подами-заглушками с самым низким приоритетом: обычные поды их вытесняют, а автоскейлер видит, что ресурсов не хватает, и заранее добавляет ноды. Чем ближе дата родов, тем больше места держит кластер, примерно так же, как у беременной постепенно растёт объём крови.

Зачатие: кластер заранее держит место под будущий сервис
Зачатие: кластер заранее держит место под будущий сервис

Пока сервис «вынашивается», кластер проводит скрининг. Он проверяет, существуют ли секреты и конфиги, на которые ссылается сервис, есть ли у контейнеров проверки готовности, заданы ли ресурсы и поместится ли всё это в квоту. Всё это лучше узнать до запуска, а не в три часа ночи после него.

Скрининг нашёл отсутствующий секрет и пропущенные проверки
Скрининг нашёл отсутствующий секрет и пропущенные проверки

Роды происходят по команде kyvctl deliver. Заглушки освобождают место, и сервис разворачивается ровно туда, где его ждали. Через минуту и через пять минут кластер ставит новорождённому оценку по шкале Апгар, той самой, которой с 1953 года оценивают состояние младенцев. Пять признаков по два балла: готовы ли поды, не перезапускаются ли они, нет ли тревожных событий, готов ли сервис принимать запросы и не убивает ли его нехватка памяти. Если через пять минут у сервиса меньше семи баллов, кластер сам откатывает релиз на предыдущую версию.

Оценка Апгар: здоровый релиз и релиз, который пришлось откатить
Оценка Апгар: здоровый релиз и релиз, который пришлось откатить

Первые трое суток сервис находится под особой защитой. Его поды получают повышенный приоритет, который постепенно снижается, так же, как угасает материнский иммунитет у младенца. Есть запас по репликам, есть защита от случайного вытеснения при обслуживании нод, а алерты строже обычного. «Выписать» сервис из-под этой опеки можно, только назначив ему двух разных дежурных, основного и запасного. Это хорошая практика для эксплуатации, а ещё важная для проекта мысль: забота общая. Беременность и роды биологически остаются за матерью, но далее заботиться о ребёнке могут оба родителя, и исследования показывают, что мозг отцов тоже меняется от ухода за младенцем.

Сервис ждёт двух заботящихся, а потом выписывается
Сервис ждёт двух заботящихся, а потом выписывается

Последняя часть цикла самая тихая. Когда сервис выводят из эксплуатации, кластер навсегда сохраняет о нём маленькую запись: кто это был, когда родился и ушёл, кто о нём заботился и от чего он зависел. Это полезно при разборе инцидентов, когда нужно понять, что раньше жило под этим именем. А ещё это отсылка к микрохимеризму: клетки плода остаются в теле матери десятилетиями.

Память кластера о выросших сервисах
Память кластера о выросших сервисах

Стартовая доза и окно поддержки

Две другие фичи скромнее. Первая решает старую проблему контейнеров, у которых не указаны запросы ресурсов. В размеченных пространствах имён Kyvernetria даёт им небольшую стартовую дозу процессора и памяти. Идея взята из фармакологии: при одинаковой дозировке женщины чаще получают передозировку, и исследователи советуют начинать с меньшей дозы и подстраивать её по результатам. Явно заданные значения кластер при этом никогда не трогает.

Вторая новинка, команда kyvctl support, показывает, сколько ещё будет поддерживаться каждая версия Kubernetes, которая работает в кластере. Kyvernetria поддерживает версию на тридцать дней дольше апстрима. Команда возвращает ошибку, если версия выходит из поддержки, поэтому её можно поставить проверкой в CI.

Сколько ещё будет поддерживаться кластер
Сколько ещё будет поддерживаться кластер

Mansplainetes и Misogynetes: кластер, который хочет, чтобы его выслушали

Обе сатирические обёртки над kubectl теперь ставятся одной командой через krew, так что их можно подарить коллеге, не объясняя, как собирать Go.

Установка Mansplainetes через krew
Установка Mansplainetes через krew

Напомню, о чём они. Mansplainetes ведёт себя как коллега, который пересказывает вам ваши же команды и присваивает ваши успехи. Misogynetes устроен как наказание для мизогинистов: kubectl в нём ведёт себя так, как мизогинист представляет себе женщин.

Не про гвоздь

Главная фича Misogynetes сделана по мотивам известного ролика It’s Not About the Nail. В нём у девушки гвоздь во лбу, а она хочет, чтобы её просто выслушали, и очень обижается, когда собеседник пытается этот гвоздь вытащить.

Теперь кластер сам следит за своими подами и прибегает к вам в терминал поделиться проблемами, даже если вы ничего не спрашивали. Правильный ответ тут один: misogynectl ага. Пока вы это не сказали, кластер будет напоминать о себе во время ввода каждой команды, и с каждым разом всё настойчивее.

Кластер сам прибегает рассказать о проблемах
Кластер сам прибегает рассказать о проблемах

Если вместо этого сразу кинуться чинить, например удалить упавший под, команда не выполнится, а кластер обидится, что вы его не слушаете. Настоите на своём, и команда выполнится, но следующие ответы будут подчёркнуто короткими.

Попытка починить вместо того, чтобы выслушать
Попытка починить вместо того, чтобы выслушать

А если выслушать, окажется, что всё прошло само. Это, кстати, чистая правда: в Kubernetes контроллеры чаще всего действительно справляются без нашего участия, а ручное «лечение» нередко только мешает.

Выслушали, и всё наладилось само
Выслушали, и всё наладилось само

Нам надо поговорить

На действительно серьёзные проблемы, вроде упавшей ноды или деплоймента без единой живой реплики, кластер не говорит ничего конкретного, кроме «нам надо поговорить». На вопрос, что случилось, он сначала ответит «ничего», потом «всё нормально», и только с третьего раза выдаст подробную сводку инцидента с командами, которыми можно посмотреть детали. Шутка здесь только в задержке, сама информация всегда точная.

«Нам надо поговорить» и сводка инцидента с третьего вопроса
«Нам надо поговорить» и сводка инцидента с третьего вопроса

Кокетство

Ещё одна новая черта касается ревности. Время от времени кластер как бы невзначай рассказывает, что к нему заходил helm, что argocd опять его синхронизировал и что они вместе раскатились. Цель понятна: чтобы вы поревновали и не чувствали себя уникальным. На вопрос, кто это был, кластер сначала отвечает, что никто, просто друг, и только со второго раза выводит настоящий список таких просто друзей.

Кластер хвастается вниманием других администраторов
Кластер хвастается вниманием других администраторов

Естественно, всё это берётся из настоящих данных кластера, из записей о том, какой инструмент и когда менял объект. Поэтому за таким кокетством прячется вполне себе полезная фича: видно, кто трогал ваш кластер, кроме вас.

Весь сценарий целиком
Весь сценарий целиком

Что дальше

Все семь релизов уже на GitHub, у каждого есть собранные архивы, а Tatarnetes, Mansplainetes и Misogynetes теперь легко ставятся через krew. Если вам захочется поучаствовать, в Sheeternetes и SNCF много задач для новичков, от клиента на Лиспе до коннекторов к облакам, а в Tatarnetes переводы можно присылать без единой строчки кода.

Ссылки на проекты: