netes за netes’ом: Kyvernetria, Mansplainetes и Misogynetes готовы уничтожать ваш прод уже сейчас

—

от автора

Я считаю, что у каждого человека должен быть свой кубернетес, и твёрдо и непоколебимо иду к этой цели. Уже есть кубернетес для татар и кубернетес для любителей эксельки. А сегодня я представляю три новых Кубернетеса, и каждый со своим характером и особенностями.

Ну а что вы мне сделаете, у меня сотка кармы на Хабре и две подписки max в клоде, так что придётся ещё какое-то время меня тут потерпеть.

Итак, представляю вашему вниманию три новых Кубернетеса (сегодня будут Кубернетесы с гендерными особенностями):

  • Kyvernetria (a.k.a. Femenetes) — Kubernetes, который ведёт себя так, как в среднем отличаются женщины. Не по стереотипам, а по научным данным: каждая особенность проверена по первоисточникам.

  • Mansplainetes — kubectl с непрошеным экспертом. Он пересказывает вам ваши же команды, присваивает себе ваши успехи и на каждой ошибке запускает «детектор ПМС». После двух жалоб в HR его увольняют, и остаётся чистый kubectl.

  • Misogynetes — настоящее наказание для мизогинистов. kubectl ведёт себя ровно так, как мизогинист представляет себе женщин. Установите его тому самому товарищу.

Все три запускаются и работают. Ниже про каждый: сначала что это и чем он отличается, потом как это выглядит вживую, и в конце, для любителей, как это устроено внутри. Посвящается ведущим Kubernetes Community Podcast.

Если вам нужен свой особый Кубернетес со своим неповторимым характером, но вам лень думать, как именно он должен себя вести, оставляйте заказ в комментариях, возможно, мы его реализуем. И еще совсем скоро мы расскажем, как добавили архитектуру виртовского Оберона в qemu и KubeVirt и зачем это всё было сделано (это станет началом длинной серии статей по палеокомпьютингу).

Кстати, помимо юмористической составляющей во всех этих и предыдущих проектах Кубернетесов есть и исследовательская составляющая: мне и правда всегда интересно, а каким был бы Кубернетес, если бы обладал такими или такими особенностями? А был бы он лучше или хуже? А дало бы ему это какие-то дополнительные преимущества?

1. Kyvernetria: что это такое

Всё началось с простого вопроса: какие отличительные черты есть у женщин и мужчин в поведении, мышлении, речи и биологии, если не скатываться в стереотипы?

В психологии распределения женщин и мужчин почти всегда сильно пересекаются. Если различие («размер эффекта») равно 0,2, распределения совпадают примерно на 92%; если 0,5 — на 80%. То есть «в среднем» — это действительно в среднем, а про конкретного человека это не говорит ничего. В биологии различия заметнее. А часть различий объясняется средой не меньше, чем биологией.

Следующий вопрос был уже инженерный: а если бы Kubernetes был женщиной, каким бы он был? Можно было бы ответить набором стереотипов (и в одном из трёх сегодняшних проектов мы так и сделали). Для Kyvernetria правило другое: каждая особенность проекта опирается на опубликованное исследование. Если исследование подтверждает вывод слабо, соответствующая особенность также ослабляется или и вовсе выбрасывается.

Kyvernetria — не надстройка поверх обычного кластера, а собственная сборка Kubernetes: свои kube-apiserver, kube-scheduler, kube-controller-manager и kubectl. Ставится как обычный Kubernetes, через kubeadm, на виртуальные машины. Мы подняли её на четырёх VM и проверили каждую особенность вживую.

Название позаимствовали из греческого. Kubernetes — это κυβερνήτης, «кормчий». Женская форма того же слова — κυβερνήτρια, «правительница», в латинской транскрипции Kyvernetria.

2. Kyvernetria: чем она отличается и почему

Вот что умеет Kyvernetria:

Мозаика из двух версий Kubernetes. У женщины две X-хромосомы, и в каждой клетке раннего эмбриона одна из них случайно «выключается». Все потомки клетки наследуют этот выбор, и тело получается как бы мозаичным. Поэтому болезни, записанные в X-хромосоме, у женщин встречаются намного реже: дальтонизм, например, бывает у ~8% мужчин и только у ~0,5% женщин. Если в одной X-хромосоме «поломка», соседние клетки работают на другой.

В Kyvernetria на управляющих узлах кластера работают две разные версии Kubernetes: 1.37 и 1.36. Какая версия достанется узлу, решается случайно при первой загрузке, и этот выбор сохраняется навсегда. Если в одной версии баг, узлы на другой продолжают работать. А если версия на узле раз за разом падает, узел переключается на другую, как гены, которые «ускользают» от выключения.

Так устроены управляющие узлы. Разная версия бывает только у kube-apiserver, остальные компоненты одинаковые. Почему так, объясняем в разделе «изнутри».

Схема мозаичного control plane

Схема мозаичного control plane. Каждый узел случайно получает свою версию apiserver: Xm (1.37) или Xp (1.36). Запрос к ресурсу, которого узел не знает, пересылается соседу

Иммунитет. У женщин в среднем сильнее иммунный ответ. Kyvernetria не пускает в кластер разное «чужеродное»: контейнеры с полным доступом к серверу, подключение к сети и дискам хоста, образы без указанной версии. Своё, то есть пространства имён, помеченные как свои, она пропускает.

И аутоиммунитет. Обратная сторона сильного иммунитета: аутоиммунные болезни у женщин встречаются примерно в 1,8 раза чаще. Kyvernetria тоже может напасть на что-то своё, например на сетевой плагин кластера, которому действительно нужен доступ к хосту. Для этого есть команда-диагноз: она находит отвергнутые компоненты, отличает «свои» от подозрительных и подсказывает, как вернуть к ним терпимость.

Без грубой силы. Физическая агрессия у женщин в среднем заметно ниже. Мгновенно убить работающий под Kyvernetria не даст. Вместо этого она предложит просто поговорить. Удалить его обычным способом, с корректным завершением, тоже можно.

Но можно не разговаривать. А вот косвенная агрессия у женщин и мужчин почти одинакова. Поэтому есть команда exclude: под продолжает жить и работать, но трафик к нему больше не идёт. Никто его не убивал, с ним просто перестали общаться.

Принудительное удаление работающего пода отклонено: «let’s talk first». А exclude убирает под из списка получателей трафика, и под при этом остаётся живым и готовым к работе:

NoBruteForce и exclude

NoBruteForce и exclude. Под исключён из общения, но не убит; include возвращает его обратно

Терпение. Доброжелательность у женщин в среднем выше. Kyvernetria даёт приложению на корректное завершение 5 минут вместо 30 секунд.

Память на события. Эпизодическая память у женщин немного лучше. Обычный Kubernetes хранит события один час, Kyvernetria — 30 дней. Команда remember рассказывает историю объекта: что с ним происходило, где жили его копии, включая те, которых уже нет.

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

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

Тревожность и спокойствие. Нейротизм, то есть склонность к тревоге, у женщин в среднем выше. Обычный Kubernetes молчит, пока ресурсы на узле не кончатся. Kyvernetria предупреждает заранее, когда занято 70%, и отдельно сообщает, когда кластеру полегчает. У ранней бдительности есть цена: предупреждений становится больше. Поэтому существует команда calm, которая сворачивает поток тревог в несколько групп и показывает, что действительно важно.

Мы поставили на рабочий узел с двумя процессорами два пода, которым нужно по 0,7 процессора. Kyvernetria забеспокоилась, когда было занято 83%, хотя ничего ещё не сломалось. Когда поды убрали, через минуту «отпустило»:

worry: Worried и Relieved

worry: Worried и Relieved. «Nothing is failing yet; I’m telling you early»

Человеческая речь. Женщины в среднем чаще используют «мы», «вы» и социальную лексику (правда, этот эффект небольшой), но слов при этом говорят не больше мужчин. Kyvernetria объясняет ошибки по-человечески: вместо 0/4 nodes are available: 4 Insufficient cpu она пишет «We couldn’t place shop/greedy yet: 3 nodes are short on CPU… We’ll try again as soon as something changes» — «мы пока не смогли разместить ваш под: узлам не хватает процессора, попробуем снова, как только что-то изменится».

Чуткость. Эмоции женщины в среднем распознают чуть лучше. У командной строки нет лица, на которое можно посмотреть, поэтому единственный доступный сигнал — повторение. Если вы третий раз подряд получаете одну и ту же ошибку, kyvctl предлагает остановиться и посмотреть, что вообще происходит с объектом.

Сопутствующие симптомы. Боль в груди — главный признак инфаркта и у мужчин, и у женщин. Но у женщин чаще бывают сопутствующие симптомы (одышка, слабость, тошнота), и именно поэтому их инфаркт чаще остается незамеченным. В Kyvernetria есть оповещения не только о нагрузке на процессор, но и о «сопутствующих симптомах»: медленно ползущей задержке API, скачках DNS, медленном диске под базой кластера.

В виде шпаргалки:

Что

Обычный Kubernetes

Kyvernetria

На чём основано

Управляющие узлы

все одной версии

мозаика двух версий, выбор случайный и навсегда

X-инактивация; дальтонизм у ~8% мужчин против ~0,5% женщин

Приём подов

пускает всё корректное

иммунитет отвергает «чужеродное»

более сильный иммунный ответ

…и побочка

диагноз аутоиммунитета

аутоиммунные болезни примерно в 1,8 раза чаще

Удаление пода

--force убивает сразу

«давай сначала поговорим»

ниже физическая агрессия

Неугодный под

удалить

exclude: жив, но без трафика

косвенная агрессия почти не различается

Время на завершение

30 с

5 минут

выше доброжелательность

События

1 час

30 дней, remember

эпизодическая память

Размещение подов

куда влезет

возвращает под «домой»

память на расположение предметов

Связи сервисов

неявные

отдельные объекты

интерес к людям, а не к вещам

Нехватка ресурсов

молчит, пока не кончится

предупреждает на 70%

выше тревожность

Ошибки размещения

0/3 nodes are available…

«We couldn’t place… yet»

больше социальной лексики

Мониторинг

процессор

процессор и «сопутствующие симптомы»

см. инфаркт

У каждой особенности в коде есть комментарий Models: со ссылкой на исследование.

Прежде чем написать первую строчку кода, мы проверили каждое утверждение по первоисточникам: мета-анализы, заявления Американской кардиологической ассоциации, данные FDA, ВОЗ и ОЭСР. Результат лежит в docs/RESEARCH.md: 36 утверждений, у каждого вердикт (подтверждено, подтверждено с поправкой, спорно, не подтверждено), исправленная формулировка и ссылки на статьи.

3. Kyvernetria вживую

Всё ниже снято на живом кластере: три управляющих узла и один рабочий, четыре виртуальные машины в облаке на Cozystack. Команды набирались в kyvctl — это kubectl из той же сборки, с добавленными командами Kyvernetria. Все обычные команды kubectl в нём работают как раньше.

Мозаика

Версии названы как хромосомы: Xm (материнская, Kubernetes 1.37) и Xp (отцовская, 1.36). Команда kyvctl mosaic показывает, как они легли на нашем кластере:

kyvctl mosaic на стенде

kyvctl mosaic на стенде. Два узла на 1.37, один на 1.36. 15 перезапусков у cp-2 — следы съёмки следующего кадра; после съёмки мы вручную вернули cp-2 на Xm

А вот «ускользание». Мы пять раз подряд убили apiserver на узле cp-2, и узел переключился на другую версию:

Escape на cp-2

Escape на cp-2. Пять падений за 10 минут на Xm, и cp-2 переключился на Xp

Иммунитет и аутоиммунитет

Образ без версии, лишние права, привилегированный отладочный контейнер — всё отклонено, с подсказкой, как пометить пространство имён в качестве «своего»:

Immunity отклоняет поды

Immunity отклоняет поды. Три попытки, три отказа

Сильный иммунитет первым делом напал на сетевой плагин нашего же кластера (flannel): ему нужен доступ к сети хоста. Для статьи мы повторили это с незнакомым агентом. Про flannel диагноз поставлен, что это «своё», а про неизвестный агент честно пишется foreign? («чужой?»). Решение остаётся за человеком: после метки все четыре пода поднялись.

kyvctl diagnose autoimmune

kyvctl diagnose autoimmune. Иммунитет отвергает агента, диагноз не уверен, метка «свой» возвращает терпимость

Память

События хранятся 30 дней. Проверили прямо в базе кластера, etcd: у события выставлен срок жизни 2 592 060 секунд, то есть 30 дней и одна минута.

TTL события в etcd

TTL события в etcd. Срок жизни события в etcd

kyvctl remember превращает события в историю объекта:

kyvctl remember

kyvctl remember. История StatefulSet: где жили копии и что с ними происходило

Память на места. Мы трижды подряд удалили все три копии приложения, и каждая вернулась на свой узел:

PlaceMemory возвращает поды домой

PlaceMemory возвращает поды домой. Девять удалений, девять возвращений домой. Случайно такое получилось бы с вероятностью около 0,2%

Связи

Связи хранятся как объекты кластера, и kyvctl рисует их графом:

Relationships

Relationships. Кто с кем общается в пространстве имён shop

Тревожность и спокойствие

А calm сворачивает час тревог в короткий список:

kyvctl calm

kyvctl calm. 69 предупреждений за час сводятся к 14 группам; первая — следы съёмки «ускользания»

Оповещения. Под нагрузкой на процессор сработало NodeCPUSaturated; остальные три правила («сопутствующие симптомы») загружены и ждут своего часа:

Алерты Kyvernetria в Prometheus

Алерты Kyvernetria в Prometheus. Оповещения Kyvernetria в Prometheus

Речь и чуткость

Ошибка размещения: сначала по-человечески, а в скобках исходный текст Kubernetes, чтобы не сломать тех, кто ищет по нему в логах.

Человеческий FailedScheduling

Человеческий FailedScheduling. Поду нужно 64 процессора, а их нет ни на одном узле

А это чуткость: на третьей одинаковой ошибке kyvctl предлагает остановиться и посмотреть историю объекта.

kyvctl замечает повторение

kyvctl замечает повторение. «That’s 3 times in the last few minutes. Let’s step back instead of retrying»

4. Kyvernetria изнутри

Если вам вдруг интересно, как это собрано и что ломалось по дороге.

Сборка

Первое требование было жёстким: «не ставить что-то там поверх кластера, а чтобы сразу была такая сборка Kubernetes». Поэтому Kyvernetria — это набор правок к исходному коду Kubernetes, как у k3s или Talos.

kubernetes/overlay/   новый код: проверки подов, плагин планировщика, контроллеры, kyvctlkubernetes/patches/   8 небольших правок в файлах Kubernetes: подключение и новые настройки по умолчаниюhack/apply.sh         исходники Kubernetes → исходники Kyvernetriahack/build.sh         сборка бинарей, образов и релизаx-inactivation/       обёртка, которая выбирает версию на узле

Правки в самом Kubernetes намеренно минимальные: регистрация плагинов, новые значения по умолчанию и одна строка в планировщике. Вся логика живёт в отдельном каталоге. Один и тот же набор правок ложится на v1.37.0 и v1.36.4, так и получаются две «хромосомы».

Kubernetes очень добросовестно проверяет свои настройки по умолчанию. После того как время на завершение поменялось на 5 минут, а в планировщике и контроллерах появились новые компоненты, упали десятки тестов самого Kubernetes. Логику тестов мы не трогали, специальный скрипт меняет только ожидаемые значения. Один тест даже предупреждает прямым текстом:

Defaults for PodTemplateSpec changed. This can cause spurious rollouts of workloads on API server upgrade.

То есть перевод существующего кластера на Kyvernetria перезапустит все приложения.

CI проверяет обе поддерживаемые версии: скачивает исходники Kubernetes, применяет правки (и проверяет, что повторное применение ничего не меняет), собирает все бинари, гоняет наши тесты и тесты всех затронутых пакетов Kubernetes, проверяет скрипты и правила оповещений.

Мозаика: первая версия и её ошибка

Каждый образ управляющего компонента несёт обе сборки за обёрткой x-inactivation:

/usr/local/bin/kube-apiserver      x-inactivation/usr/local/bin/kube-apiserver.Xm   Kubernetes v1.37.0 + Kyvernetria/usr/local/bin/kube-apiserver.Xp   Kubernetes v1.36.4 + Kyvernetria

При первой загрузке узла обёртка случайно выбирает Xm или Xp и записывает выбор в /var/lib/kyvernetria. Все последующие запуски наследуют его. Тесты первой версии сразу же поймали гонку: три компонента стартуют одновременно, и второй успевал прочитать пустой файл между созданием и записью. Теперь выбор пишется во временный файл и публикуется через link(2), который не срабатывает, если файл уже существует.

В первой версии на выбранную версию переходил весь узел: apiserver, controller-manager и scheduler вместе, «как одна хромосома». Проверка признала это блокером. Правила совместимости версий Kubernetes требуют, чтобы controller-manager и scheduler были не новее любого apiserver в кластере, а не только того, с которым они говорят. Кроме того, API начинал зависеть от того, какой apiserver ответил. Мы убедились в этом вживую:

  • Поле maxUnavailable у StatefulSet в 1.36 выключено, а в 1.37 включено. В двух запросах из трёх поле сохранялось, в третьем молча терялось.

  • ClusterTrustBundle в 1.37 уже стабилен, а узел на 1.36 отвечал на него 404.

Мозаика сейчас

  • controller-manager и scheduler всегда на 1.36;

  • по узлам различается только kube-apiserver;

  • apiserver 1.37 запускается с --emulated-version=1.36: он притворяется версией 1.36, поэтому API и набор включённых функций у всех одинаковые, а отличается только сам код;

  • включена пересылка запросов между apiserver разных версий (--peer-ca-file).

Процессы control plane на трёх нодах

Процессы control plane на трёх нодах. На каждом узле controller-manager и scheduler — Xp; apiserver на Xm-узлах притворяется версией 1.36

После этого StatefulSet, созданный через любой из трёх apiserver, ведёт себя одинаково, а ClusterTrustBundle одинаково отсутствует у всех.

Пересылку запросов проверили отдельно. На время теста подняли у cp-1 эмуляцию до 1.37, и он начал отдавать ClusterTrustBundle. Запрос к cp-3, который такого ресурса не знает, ушёл к соседу:

apiserver_rerouted_request_total{code="200",group="certificates.k8s.io",resource="clustertrustbundles"} 2apiserver_rerouted_request_total{code="201",group="certificates.k8s.io",resource="clustertrustbundles"} 1

Ускользание

В биологии гены ускользают от выключения по одному, и у нас «ускользать» может только kube-apiserver. Считаются только настоящие падения: ненулевой код выхода или смерть от сигнала в первые две минуты после старта. Пять таких падений за 10 минут переключают узел на другую версию. Это возможно не чаще раза за загрузку узла и раза в сутки, и выключено на время обновления кластера.

Первая версия считала любые перезапуски, включая правку конфигурации и падения из-за etcd. Рецензент смоделировал пинг-понг: controller-manager уводил узел на Xp, через секунду scheduler возвращал его на Xm, и так без конца. Теперь есть тест на 1000 чередующихся падений, и он не даёт ни одного переключения. Повторная серия падений в ту же загрузку узла тоже ничего не переключает:

x-inactivation[kube-apiserver]: crashed with 137 after 6s on Xm: the node already escaped once since it booted; no escape

А главное свойство случайного выбора такое: после полного сброса и переустановки кластера каждый узел сохранил свою версию.

Съёмка «ускользания» для этой статьи нашла ещё один баг, и на этот раз не в нашем коде. Пока apiserver на cp-2 падал, сам узел cp-2 выпал из кластера, и с него выселили под. Хотя два других apiserver работали. Причина в kubeadm: начиная с 1.35 он всегда направляет kubelet управляющего узла на apiserver этого же узла, и выключить это нельзя. Для обычного кластера это разумно, а для Kyvernetria падающий apiserver — штатная ситуация перед переключением. Теперь установщик после kubeadm join направляет kubelet на локальный балансировщик, который видит все три apiserver (PR #5). При повторной серии падений узел всё время оставался в строю.

Небольшая оговорка: две сборки разные, но не независимые. В классическом эксперименте Knight и Leveson (1986) 27 независимо написанных версий программы прогнали на миллионе входов, и общих отказов оказалось намного больше, чем предсказывает независимость. А с эмуляцией версия 1.37 работает по правилам 1.36, и разница остаётся только в коде.

Что нашли и починили в остальных особенностях

  • Иммунитет проверял только создание подов. Через kubectl debug --profile=sysadmin можно было добавить привилегированный отладочный контейнер, а через kubectl set image поменять образ на :latest. Оба обхода закрыты и проверены. И важный момент: иммунитет — не 100% защита. Любой, кто может ставить метки на пространство имён, может от него отказаться, так что штатный Pod Security он не заменяет.

  • «Давай поговорим» не давал удалить даже поды, которые ещё не запустились. Kubernetes сам ставит им нулевое время на завершение, и проверка принимала это за грубую силу. А через механизм вытеснения (kubectl drain --grace-period=0) её можно было обойти. Оба случая закрыты.

  • Память на места устраивала шторм записей. При больше чем 16 узлах контроллер постоянно переписывал Deployment. А память хранилась на всё приложение сразу, и новые копии стягивало туда, где уже жили соседи. Теперь у StatefulSet память хранится для каждой копии отдельно (0=kyv-w-1,1=kyv-cp-3,2=kyv-cp-1), а копии Deployment при масштабировании до 8 разошлись по всем четырём узлам.

  • Связи считались минуты процессора. Первая версия компилировала регулярное выражение на каждую пару «приложение × сервис × строка» каждые 30 секунд. Переписали на индекс:

    BenchmarkGraph (500 services × 500 workloads × 20 texts)before: 102.2 s/op, 122.5 GB allocatedafter:   16.5 ms/op,   9.8 MB allocated
  • calm склеивал разные поды. Группы собирались по имени пода, и apiserver’ы трёх узлов kube-apiserver-kyv-cp-1/2/3 сливались в одну группу: номер узла принимался за номер копии. Теперь группы строятся по реальному владельцу пода (PR #5).

  • Человеческий текст ошибки обрезал исходный. При длине больше 1024 байт первой обрезалась часть Kubernetes в скобках, и обещание сохранить её для поиска нарушалось. Теперь сокращается человеческая часть.

  • Чуткость предлагала вспомнить не то. Сначала совет звучал как kyvctl remember /Users/…/kubeconfig: команда принимала путь к конфигу за имя объекта (PR #2). Потом — kyvctl remember etcdctl --cacert=/etc/…: за объект принималась команда, которую запускали внутри контейнера (PR #5). А история ошибок хранила командные строки вместе с токенами. Теперь в ней только хэши.

Дорога к живому стенду

Отдельный жанр — баги окружения. Их было много, и почти все поучительные.

  1. bash 3.2 на macOS. Сборочные скрипты Kubernetes требуют bash 4.2 или новее, поэтому сборку переписали на прямой go build.

  2. kind с тремя управляющими узлами на ноутбуке. etcd не успевал записывать на виртуальный диск, kubeadm не укладывался в таймауты, а рабочему узлу не хватило inotify. Позже kind прогнали на отдельной VM в облаке, и там он поднялся целиком.

  3. Docker на Mac с процессором ARM не экспортирует образы под amd64. Мы убрали Docker из сборки образов совсем и собираем их через crane: к официальному образу дописывается слой с нашими бинарями.

  4. GNU tar. Первая сборка образов на Linux упала: у GNU tar другие флаги, чем у tar на macOS. PR #3.

  5. Угон DNS. Наши VM живут в облаке на Cozystack и спрашивают DNS по адресу 10.96.0.10. Мы выдали сервисам Kyvernetria ту же подсеть 10.96.0.0/16, и kube-proxy перехватил этот адрес: узлы перестали резолвить имена. Теперь по умолчанию 10.112.0.0/16.

  6. pkill -f в ssh убивает сам себя, потому что шаблон совпадает с командной строкой самой ssh-сессии.

  7. Диск. Три копии исходников Kubernetes и кэш Go дважды съели весь диск. Один раз сборка упала молча, не оставив ни строчки в логе.

Обновление живого кластера и 27 потерянных запросов

Один образ несёт обе версии, поэтому наивное обновление с (1.37, 1.36) на (1.38, 1.37) меняет обе сразу. На какое-то время рядом оказались бы apiserver 1.36 и 1.38, а это запрещено. В OPERATIONS.md описана процедура из семи шагов, на каждом из которых правила совместимости соблюдаются.

Описать процедуру мало, её надо пройти. Kubernetes 1.38 ещё не вышел, поэтому мы сдвинулись на шаг назад: перенесли правки на 1.35.8, собрали старый релиз (1.36 + 1.35), поставили на него кластер и обновили его до текущего. Всё это время на рабочем узле раз в секунду читали и писали в API.

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

  1. Каждый перезапуск apiserver терял запросы: 27 из 1031. Apiserver при остановке сразу закрывал соединения, а балансировщик ещё до 9 секунд слал ему запросы. Теперь apiserver при остановке сначала 15 секунд сообщает, что уходит, и продолжает отвечать, а балансировщик проверяет его каждую секунду. После этого шесть перезапусков подряд — 0 ошибок из 182.

  2. Ошибка в конфиге при установке вызвала серию падений, и узел переключил версию. Бесполезно: у второй версии та же ошибка. Теперь на время установки переключение выключено.

  3. Процедура предписывала запустить полный установщик слишком рано, и kubelet обновился бы раньше apiserver. Добавлен режим «только образы».

  4. Пересылка запросов между apiserver требует отдельного флага при эмуляции версии старше 1.36, иначе apiserver не стартует. Оговорка в документации.

Всё это было пофикшено.


5. Mansplainetes

Что это такое

После Kyvernetria мы решили сделать проект, где кластер ведет себя как липкий сексист. Так появился Mansplainetes.

mansplainctl — это kubectl с коллегой, которого никто не звал, но он пришел со свлим важным мнением и комплиментами:

  • Пересказывает вашу же команду перед выполнением: «Well, actually, get is for getting things. Think of pods as little boxes, but for the cloud».

  • Поправляет произношение слова Kubernetes, хотя вы и не произносили его вслух.

  • Присваивает ваши успехи. Команда сработала — «Told you». Вы повторили то, что уже работало, — «Glad you finally came around to my idea».

  • Винит ваши эмоции, когда что-то упало, и запускает «детектор ПМС». Детектор срабатывает всегда, но в следующей строке этот нетес признаётся, что виноват он сам: это он написал права по памяти, выдал просроченный токен или указал вам не то имя.

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

  • Увольняется по рзультатам жалоб. После первой жалобы в HR-департамент его переводят поддерживать старый Jenkins, и приставания прекращаются. Объяснять он продолжает, «потому что HR говорит, что это просто его стиль». После второй жалобы его увольняют насовсем, и остаётся чистый kubectl.

Как это выглядит

mansplainctl

mansplainctl

Представление при первом запуске, «Told you», повтор команды как «его идея», детектор ПМС и rollout, термин для которого он «практически изобрёл».

Жалобы на mansplainctl

Жалобы на mansplainctl

Приставания, первая жалоба (объяснения остались, приставания кончились), вторая жалоба — и это просто kubectl.


6. Misogynetes

Что это такое

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

  • «Всё нормально». Ошибку kubectl он прячет за «Everything’s fine. 🙂». Что случилось на самом деле, выясняется только с третьего вопроса misogynectl what: сначала «Nothing», потом «You know what you did».

  • Обижается. В обиде половина команд получает «Do what you want. 🙂», и ничего не происходит.

  • Ждёт извинений, причём за что-то конкретное. «Прости» без объяснений не работает («Sorry for what?»). Извинение не за то — тоже не проходит. Цветы приятны, но ничего не меняют. Помогает только извинение за какое-то то самое.

  • «Те самые дни». Четыре дня из 28 всё то же самое, только громче и с эмодзи. На каждой команде в эти дни стоит приписка «His words, not hers» — «это его слова, а не её».

  • Цитаты и капризы. В обычные дни — «глубокие» цитаты и «Not now.».

При первом запуске проект объясняет, что это и для кого:

Misogynetes: `kubectl` that behaves exactly the way misogynists think women behave.It was built as a punishment for them. If it feels accurate, that's the point, and it's on you.What the evidence says about women, on average and with sources: https://github.com/tym83/kyvernetriaTo apologize: `misogynectl sorry for <what you did>`. To make it stop: `MISOGYNETES=off`.

Ссылка ведёт в Kyvernetria неслучайно: там у нас перечень подтвержденных наукой фактов.

Как это выглядит

misogynectl прячет ошибку

misogynectl прячет ошибку

Ошибка спрятана за «Everything’s fine», настоящая причина выходит только на третий «what».

misogynectl ждёт извинений

misogynectl ждёт извинений

«Do what you want» и ничего не происходит; извинение работает, только если назвать, за что.

misogynectl в «те самые дни»

misogynectl в «те самые дни»

Приписка «His words, not hers» стоит на каждой команде в эти дни.


8. Что осталось непроверенным

  • Оповещение о ползущей задержке API сравнивает задержку с тем же часом вчера, поэтому сработать оно может только через сутки работы кластера. Оповещения о DNS и диске считаются на живых данных, но до срабатывания мы их не доводили.

  • Обновление проверено на паре (1.36, 1.35) → (1.37, 1.36). Для этого правки переносили на 1.35 вручную. Официально поддерживаются только 1.37.0 и 1.36.4.

  • Пока не реализованы:

    • запросы ресурсов по умолчанию с поправкой на различия в том, как организм усваивает лекарства;

    • настройка под длительную нагрузку, с опорой на меньшую утомляемость;

    • более глубокие проверки здоровья как модель маскировки симптомов;

    • раннее принятие экспериментальных API вместе со строгими правилами меток, по данным о том, что языковые изменения чаще начинают женщины;

    • более длинный срок поддержки.

  • Kyvernetria — не сертифицированный Kubernetes. С иммунитетом и пятью минутами на завершение она не пройдёт проверку на совместимость. Kubernetes — зарегистрированная торговая марка The Linux Foundation, а наш проект с CNCF не связан никак.


9. Итоги и ссылки

Из одного вопроса выросли три проекта, и у каждого своя роль:

  • Kyvernetria показывает, что даже в шутке о различиях можно держаться данных: каждая особенность опирается на источник, а то, что источники не подтверждают, остаётся за бортом.

  • Mansplainetes шутит над тем, кто всё объясняет: он всегда неправ, и его в итоге увольняют.

  • Misogynetes возвращает мизогинисту его же стереотипы, упакованные в kubectl.

Инженерная часть при этом настоящая:

  • две версии Kubernetes в одном кластере с соблюдением правил совместимости;

  • восемь правок в Kubernetes и десятки обновлённых тестов;

  • живой кластер из четырёх VM в Cozystack;

  • обновление между версиями, после исправлений — без потерянных запросов.

  • Kyvernetria: https://github.com/tym83/kyvernetria (исследования — docs/RESEARCH.md, эксплуатация — docs/OPERATIONS.md)

  • Mansplainetes: https://github.com/tym83/mansplainetes

  • Misogynetes: https://github.com/tym83/misogynetes

Всё под Apache 2.0.

P.S. Нароминаю, что можно оставить заявки на свой Кубернетес, а фантазии о том, как он должен себя вести, мы возьмем а себя. Больше Кубернетесов хороших и разных!

ссылка на оригинал статьи https://habr.com/ru/articles/1086438/