Make. Build. Break. Reflect.
908 subscribers
115 photos
1 video
119 links
Полезные советы, всратые истории, странные шутки и заметки на полях от @kruchkov_alexandr
Download Telegram
#docker #troubleshooting #одинденьизжизни

Иногда нам всем нужна Лицензия на Убийство Костыль.
Как в одном из фильмов про Бонда.

Ситуация: резко к вам прибегают и говорят "У НАС ПРОБЛЕЕЕМА".
Нырнув внутрь "проблемы", понимаю, что 19 из 20 разных микросервисов на разных стеках начали ругаться на один из веб-сайтов партнёров. Что-то не так с сертификатом.
Проверяем изнутри пода
> curl https://*******.com/
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Проверяю локально - всё ок с сайтом(он не наш).
Ладно.
Лезем в гугл спрашиваем в чате девопс_ру чего есть ныне для анализа SSL.
Дали рекомендацию - https://www.ssllabs.com/
Проверяю сайт - ранг B, в целом всё ок, но есть вопросики.
Они обновили новый серт, у нового серта новый УЦ(я так понял).

Созвон с коллегами, говорю так и так, сайт чужой, проблема с ним, у нас вроде всё ок.
Однако бизнес не согласен со мной(и, наверное, прав на 100%).
Говорят "да, мы знаем, что проблема скорее всего не у нас. Да, мы поняли, что это надо им писать. Но у нас бизнес и денежки, Пока они(владельцы сайта-партнёра) отреагируют, у нас не ок работает НАШ бизнес.
А где НАШ бизнес - там проблема у нас. Возможно ли быстро решить нашими средствами эту проблему?
"
Чуток поэкспериментировал локально, за пять минут нашёл пару очевидных решений.
Спрашиваю лицензию на костыль, мне дают карт-бланш.

Ну ок, лицензия получена, пилим фиксы.
В одном имадже (где старые from имаджи)
FROM node:*****
...
# temporary fix for https://*****.com/
RUN wget https://sectigo.tbs-certificats.com/SectigoPublicServerAuthenticationRootR46.crt -O /usr/local/share/ca-certificates/sectigo-root.crt && update-ca-certificates
...

В другом имадже залепить, если ещё нет, и пересобрать
...
RUN update-ca-certificates
...

(показываю одним слоём, но вообще он был добавлен к один длинный run).
Да, было добавление ca-certificates, но не было команды на апдейт 🐒

И так далее.

Пересобираем, деплоим, проблема ушла.
Ура, бизнес ликует.

Выводы:
А кто тут виноват? Я не знаю.
Владелец сайта и новый УЦ?
Наши "устаревшие сервисы" со старым списком со старыми сертами?
Отсутствие регулярных пересборок имаджей и скачивание всех новых сертов?
Чёрт его знает.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍141🤡1
#одинденьизжизни

Факапы и сроки.

А вот мало когда мне удавалось в своей жизни спланировать сроки.
Задача А - 2 часа, задача Б - 2 дня.
Ну не, к сожалению, у меня так не работает.

Допустим задача "установить впн сервер".
Казалось бы простая задача. Возьми да установи.
Для начала мы сравниваем что есть на рынке, смотрим фичи(платные, бесплатные), потом спрашиваем бизнес чего он сам хочет, какие есть требования аудитов сейчас и в будущем. Количество сотрудников, кто будет пользоваться.
В общем составляем картину задачи. На это уходит время.
Все требования собраны, все софты сведены в табличку(опенсорс и платные).
По ходу принято решение руководства/коллег/заказчика/лида, что опенсорс не для нас, потому как если не будет того, кто это поддерживает, то такое решение никому не нужно.
Допустим выбираем два решения - потестировать.
Пока идём по плану времени на задачу.
Приступаем к тестам. тестируем оба решения на базовые вещи из требований - SSO, routing, monitoring, audit etc.
На это снова уходит время, уже начинаю отклонятся от плана.
Опустим требования, которые были от компании/коллег/заказчика, но в итоге выбрали совместными усилиями pritunl.
Ок, он так он.
Начинаю пилить боевую инфру - терраформ, днс, секьюрити груп и прочие компоненты для инсталляции.
Почти всё готово (базовая инсталляция, без настройки).
Несколько раз гоняю планы/апплаи, то сперва работало, то теперь не работает.
Начал ковыряться в логах - оказывается у встроенного certbot с ssl сертификатом есть ограничения.
https://letsencrypt.org/docs/rate-limits/#new-certificates-per-exact-set-of-hostnames
И следующая регистрация только через сутки🤦‍♂️
Ок, хочется настроить уже с нормальным сертом (+ ажур аппликейшн адрес), ждём сутки.
Пулл реквест не стал пилить, оставил на завтра, ушел спать.
Пришёл утром - сервера нет. Ночью была авария, коллеги с другого часового пояса делали срочные изменения инфры, перетерли стейт с моей ветки. Проблемы терраформа и одного стейта.
Ладно. Мержим с мастера, снова апплаим с ветки, настроили, с сертом уже проблем нет.
Однако всплыла другая проблема - при вводе лицензии мы видим, что у нас УЖЕ используется одна лицензия.
С удаленного сервера.
Ну типа и платить двое больше, пробуем поиграться с кнопочкой удаления лицензии, кнопка есть, а лицензия не удаляется из аккаунта.
Ладно, потом разберёмся. ПР, аппрув, мерж в мастер, всё раскатывается.
Хочу уже на "боевом" сервере начать вносить правки, но теперь активны две лицензии, и если введу в третий раз - будет третья лицензия и будет прайс х3.
Пишу имейл в саппорт, жду ответа.
Снова ждать.

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

Вот так задача в условные 8 часов превратилась в 20+ часов и ещё не закончена.
Не все 20 часов её делал, и трекать надо меньше, но финальный срок "когда впн будет готов для всех" сильно отличается от первоначальной оценки.

Не знаю как у других, но планирование у меня частенько хромает. Увы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍202😁1🤡1
#slack

Незаметно для меня(но, возможно, очевидно для всех остальных внимательных людей в мире), slack incoming WebHooks стал deprecated и больше не поддерживает добавление новых каналов.
Ни в одном из моих спейсов не даёт добавить себя ни в один из каналов.😭

Переходим на slack app.
Опять переписывать все интеграции и скрипты. 🤡
Please open Telegram to view this post
VIEW IN TELEGRAM
👀5🤡3👍1😈1🫡1
#aws

Абсурд и наркомания.

Однажды какой-то безопасник скажет.
Везде и всем всё запретить.
Задачу надо как-то выполнять.
Закрываем одно, второе, третье.
Наступает момент лютейшего бреда, когда тебе говорят ограничить доступ, оставить только для гитхаб раннеров.
Задачу надо как-то выполнять.
Ты идёшь и смотришь, а чего с пулом
curl -s https://api.github.com/meta | jq '.actions | length'
5265

Ух, пробрало, как сладко.
А потом читаешь
https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html
Оказывается на один уникальный порт в рамках одной секьюрити группы можно повесить лишь 60 правил.
Задачу надо как-то выполнять.
А это значит тебе надо создать примерно сотню SG, по 60 правил в каждом чтобы поддержать желание инфобезы/аудитора... Стоп-стоп, какой сюр, прекрати.
Задачу надо как-то выполнять.
На этом моменте тебя тошнит от бреда, ты пишешь аудитору/инфобезе "я не смогу это сделать, технически нельзя выдать доступ только для гитхаб раннеров и больше никому, вот пруфы".
Смело закрываешь таску и идёшь заниматься настоящей работой, а не Великими фантазиями Великих Всезапрещальщиков.

* Не знаю есть ли вообще решение, но мне проще порт нахрен закрыть, чем 5.3к рулсов куда-то запиливать.
14😁8👍3👎1🤡1
Ну что ж, время течёт, мир меняется.
Прекрасные пятничные новости и не менее великолепное будущее.
Внезапно.
Надеюсь я не поеду кукухой от bare metal, после многолетней привычки удобства клауд провайдеров.
🔥8👍3👎3🤬1😢1🤡1💔1
#aws #пятница #terraform

Магия "у меня локально всё работает".

Пишет мне мой приятель, у которого я какое-то короткое время менторил(а такое слово вообще есть?)
"Алекс, Алекс, спасити памагити, у меня беда".
Сегодня он вносил небольшие правки в терраформ.
Запустил план на дев, на стейдж, на прод - все ок.
Аппрув, мерж в мастер и.. а терраформ план и апплай перенакатывает ему виртуалку с ec2🐒
Я помог ему восстановить сервис(вне этой заметки, отдельная стори и причина звонка), а затем мы начали разбираться, а как так вышло то, эй.

Шарит экран, говорит вот локально с мастера делаю план на дев, стейдж, проде, - всё ок.
Выдохнув, спрашиваю, а что ты знаешь про version constraints у терраформа?
Ну он, конечно же, ничего не знал.
Скидываю ему пример
= X.Y.Z - точная версия: version = "= 4.0.0" (только 4.0.0).
>= X.Y.Z - минимум и выше: version = ">= 4.0.0" (4.0.0 и выше).
<= X.Y.Z - максимум и ниже: version = "<= 4.0.0" (до 4.0.0 включительно).
> X.Y.Z - выше указанной: version = "> 4.0.0" (4.0.1 и выше).
< X.Y.Z - ниже указанной: version = "< 4.0.0" (до 4.0.0, не включая).
~> X.Y - в пределах мажорной: version = "~> 4.0" (4.0.x, но не 5.0).
>= X.Y.Z, < X.Y.Z - диапазон: version = ">= 4.0.0, < 5.0.0" (4.x.x, но не 5.x.x).

Смотрим его код, а там есть
...
version = ">= 5.0"
...

Лезем в
https://github.com/hashicorp/terraform-provider-aws/releases/tag/v6.0.0
охреневаем от брейкинг чейнджев
Приятель пилит сам у себя все версии в лок, проблема решена.

Он проверял локально и провайдер брался из кеша - проблемы не видел.
В CI/CD при каждом запуске запускался terrafrom init, что подтянул ему новую версию, которая триггернула пересоздание виртуалки.

Дальше была проверка всего кода tflint, checkov и другими утилитами, нашли ещё 4 места, где версии были плавающими, поправили и это.

Ну зато узнал что-то новое, чо.
Please open Telegram to view this post
VIEW IN TELEGRAM
👏15🤡6
#docker #aws

Я решил отказаться от долгих часов, проведенных за оптимизацией размера Docker-образов.

Несмотря на провокационный заголовок, который мог показаться кликбейтом, я действительно перестал уделять этому столько времени.
Хочу поделиться своими размышлениями - возможно, они окажутся правильными, а может, и нет.
Я не топлю, что мои размышления правильные, я лишь ими делюсь.
Давайте попробую обосновать свою позицию.
Все дальнейшие расчеты будут основаны на работе с облачными провайдерами, хотя, как мне кажется, на bare metal затраты могли бы быть ниже.

Выпущено миллиард книг, написано сотни утилит и опубликовано гигадзиллион статьей по теме оптимизации размера имаджа.

А зачем?

Вспомним основные причины оптимизации размера Docker-образа:
- Ускорение развертывания: Меньшие образы быстрее загружаются и передаются по сети.
- Экономия ресурсов: Снижение потребления дискового пространства и памяти.
- Безопасность: Уменьшение количества компонентов снижает уязвимости.
- Эффективность CI/CD: Ускорение сборки и доставки в конвейерах.
- Снижение затрат: Меньше данных для хранения и передачи в облаке.
и так далее.

Скачивание имаджа.
Когда в основном скачивается имадж:
- при скейле ноды
- при релизе
Есть ещё редкие случаи связок imagePullPolicy Always, скейлинге приложения и антиаффинити, но мы о не будем говорить, они редкие.
А сколько скачивается имадж?
Начиная с версии 1.30 кубера у нас есть метрика kubelet_image_pull_duration_seconds_sum и лейбл image_size_in_bytes (не сжатый!!!! размер) с 4 значениями ( 0-10MB, 10MB-100MB, 100MB-500MB, 500MB-1GB).
Мы говорим про средние имаджи, допустим в 900 мегабайт.
Построим график
avg(kubelet_image_pull_duration_seconds_sum{image_size_in_bytes="500MB-1GB"} / kubelet_image_pull_duration_seconds_count{image_size_in_bytes="500MB-1GB"})
(и для сравнения мелкие имаджи)
avg(kubelet_image_pull_duration_seconds_sum{image_size_in_bytes="100MB-500MB"} / kubelet_image_pull_duration_seconds_count{image_size_in_bytes="100MB-500MB"})

Скорость варьируется от 6 секунд до 16 секунд за последние 7 дней.

Я лично считаю это небольшой цифрой для добавления времени к релизу или скейлингу.
Нода или само приложение порой дольше проходит хелсчеки.
Специально ставил blackbox exporter + релейбл с путем до проб и навешивал на поды, чтобы рассчитать probe_duration_seconds. Пробы в среднем стартуют с 25 секунд.

Экономия ресурсов.
А сколько сейчас стоит в облаках ресурс дискового пространства?
Например у AWS так https://aws.amazon.com/ecr/pricing/
Ну или просто в биллинг можно залезть и посчитать сколько тратим в месяц на ECR.
В среднем за последний год тратим 35-50 долларов в месяц.
Диски для самих нод выходят так мало, что их почти не видно в прайсе
https://aws.amazon.com/ebs/pricing/

Ну то есть в самый пик на дисковое пространство тратим не больше 50 долларов в месяц.

Безопасность.
Я и согласен и несогласен.
Безопасность в последнее время перешла границы от разумного до параноидального бреда, лишь бы мы покупали решения от крупных вендоров и мастурбировали на CVE, которая вышла 0.000001мс назад.
Простые решения в виде "не добавлять ничего лишнего в имадж" + trivy вполне покрывают этот пункт для нас.

Да и уменьшение размера диска не гарантирует безопасность, лишь снижает вероятность инцидентов.
К сожалению в некоторых моих проектах невозможно использовать подходы с SBOM+distroless.
Разработчики пилят микросервисы, макросервисы, сейчас один только nodejs и python тянет за собой миллиард депенденси и отказаться от них невозможно, совершенно невозможно.
А этот софт в отличии от меня приносит деньги.

Эффективность CI/CD
Тот же пункт, что и пул имаджей с нод.
6-16 секунд для несжатых имаджей.

Снижение затрат
Тот же пункт, что и с костами для ECR, но тут за трафик.
Трата за трафик небольшая. Не больше 5 долларов в месяц.
👍91
#docker #aws

Итого, что мы имеем:

Средняя температура по больнице зарплата синёра это $4000-6000 (*ЕС, Россия, без США само собой), если верить словам приятелей моего круга общения и статьям в интернете и статистике, которую нашёл час назад, а значит в час, при 168 часовой неделе, это $23-35. Ну, наверное, самые крутые получают $50h.
Средняя время оптимизации докерфайла (постоянный запуск, смена слоёв, подгон под аппликейшн, убирание лишнего и так далее) это 2-3 часа в моей практике. Лишь за счёт долгого ковыряния.
То есть чтобы "сэкономить" бизнесу 5-10 долларов в месяц(!) за трафик сети и хранение и 3-5 секунд при деплое я потрачу $50-105. И это лишь на один имадж. 30 имаджей-микросервисов и всё, я потратил несколько тысяч долларов.

Оптимизировать чтобы что? Только лишь потому, что это правильно?
Да, оптимизация размера имаджа это правильно, я согласен с этим тезисом. не оспариваю его ни в коем случае.
Как минимум это приятно для глаз инженера.
Стоит ли делать это? Да, но только в том случае, когда освободилось время от всех других задач по работе.
Приоритет у этой задачи один из самых низких на мой взгляд.
У меня сейчас нет времени, чтобы тратить деньги бизнеса на оптимизацию.
Безусловно если мне коллеги выкатят имадж на 5 гигабайт я брошу всё и займусь им.
Образы до 900 мегабайт считаю оптимизировать пока не надо.

В данный момент развития технологий в 2025 году(привет хелл депенденси питона и ноджс и все ML фреймворки), с ценами облачных провайдеров за трафик, реджистри и диск для нод, средней зарплатой инженера в час, считаю полностью нецелесообразным тратить часы на оптимизацию размера имаджа.
Бизнес не выигрывает ничего, во всяком случае наш.
В каком же случае оптимизация всё же нужна?
Когда важная каждая секунда при деплое и скейлинге и когда этого просто хочется.

* Данная заметка не является рекомендацией, не является советом, лишь поделился своими размышлениями.
16👌5💯1🤝1
Правило пяти.

Последние годы я выработал в себе привычку "правила пяти" - обновлять на новые версии только с 6 патча.
Сколько же я разных проблем находил: Argo CD, Apache Superset, Kubernetes, Debezium, Trino, Laravel и сотни их было.
И большая их часть именно в 1-5 патч версиях.

Теперь я стараюсь не спешить и не обновляться до новой версии сразу после релиза.
Даже в AWS EKS я две проблемы находил - с сетевым плагином с и ООМ metrics сервера.
Не знаю как у остальных, но конкретно меня правило пяти последнее время спасает, оберегая от новых багов на которые просто банально тратится множество времени для траблшутинга.
👍18😁5
#aws

Короткая, но важная заметка о предстоящих изменениях.

AWS CDK планируют собирать телеметрию.
Важно тем, у кого CDK и GDRP или подобное.

- https://github.com/aws/aws-cdk-rfcs/blob/main/text/0732-cdk-cli-telemetry.md
- https://github.com/aws/aws-cdk/issues/34892
👍31🤡1
#kubernetes #java

Считаю, что java великолепный язык, но он не подходит для работы в Kubernetes из коробки.

- Долгий холодный старт *
Да, есть современные фреймворки типа Quarkus или Micronaut, но у них есть и свои другие минусы по сравнению со спрингбут. Экосистема крайне малая.
- Большое жорево ресурсов при старте, но потом кушает совсем немного (при малом рпс).
Отсюда сложности расчётов "да сколько тебе ставить реквестов?".
Поставишь мало - как юсадж - ещё медленнее будет стартовать, поставишь много - оверкоммит ресурсов и кластер впустую простаивает.
В 2025 может решаться через новые альфа фичи https://kubernetes.io/docs/concepts/workloads/autoscaling/#in-place-pod-vertical-scaling , но я сам руками ещё не пробовал.
- размеры имаджей для джавы больше остальных рантаймов (аргумент высосан из практики 2-3 летней давности, когда крутил на базе OpenJDK, сейчас может ок). Просто мнение, его можно не считать.
- realtime/driven-event в связке HPA/KEDA это не про джаву (см. первый пункт *)
- исключительно на мой взгляд всратый GC, который, к тому же, может вызывать спонтанные OOMирания
Говорят, что переход на GraalVM может решить проблему, но не могу контр аргументировать, не было опыта.
- без опыта с джавой и кубером для первого старта это боль подстроить все десятки параметров, от метаспейс до размера кучи. Ты вынужден изучить все параметры, чтоб это хоть как-то стартовало в кубере.
Когда опыт есть конечно ок, поставил нужные параметры и полетело. Одно из самых сложных как по мне.
- логи, стактрейсы это стыд на 99999 строчек, нужен ультравайд монитор поставить вертикально, чтобы уместить весь аутпут. Обязательно вскроются проблемы с тем, что в системе логировании этот стактрейс будет разбит на отдельные строки, а не в одном сообщении и надо подстраивать. Ну почему бы не сделать сразу и нормально, ну камон?
- сложности с graceful shutdown
Честно говоря не помню почему, может есть специфика, может баг, а может мои кривые руки(скорее всего🐒), но спрингбут срать хотел на сигтерм от кублета.
POD висит 30 секунд, спрингбут закрывает контекст, а юзеры уже видят 503.
Когда с ним работал, решал эту проблему через терминейшн период 60 секунд, но это вообще неудобно при деплое, он очень долгий становится.
- отвратительно неудобное профилирование и снятие дампов в случае траблшутинга
Несколько раз надо было понять почему память течёт, как барышни на концерте Моя Мишель, вообще неудобно было. Может сейчас с этим проще.

Люблю ли я джаву? Да.
Готова ли она из коробки* к куберу? Нет.

* с популярным фреймворком спрингбут

Всё вышенаписанное не является истиной, лишь мнение одного инженера из 8 миллиардов человек на планете.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍133
#troubleshooting #одинденьизжизни

Процесс мышления трабшутинга. Опять.
Часть 1 из 2.

Прилетает алёрт "рестарт пода с опенсёрч".
Потом 2 пода, тут же все 5 мастер подов".
Бегу смотреть.

Захожу в кластер, переключаюсь в неймспейс, где опенсёрч (он у нас в куберентисах).
Смотрю
kubectl get pods |grep opensearch

Да, есть рестарты.
Есть 5 подов master, 5 подов warm nodes, 5 cold nodes, 2 dashboards.
Рестарты у всех 5 мастеров, у остальных рестартов нет.
Ок, а какая причина? ООМ? Ошибка приложения? Конфигурация?
kubectl get pod PODNAME -o yaml | grep -A4 -i reason

Показывает, что exit code 1, то есть ошибка внутри приложения, не со стороны самого кубернетиса.
Смотрю логи одного из мастеров опенсёрча
kubectl logs PODNAMEMASTER

Внутри весёлые и любимые всем портянки java stacktrace.
Переворачиваю свой ультравайд монитор вертикально и читаю что же за причина.
Ага, ругается на какой-то сертификат TLS, который протух.
notBefore=J***l  8 06:58:13 2024 GMT
notAfter=*** 8 06:58:13 2025 GMT

Переворачиваем монитор обратно в горизонтальное положение.
Смотрим какие есть сертификаты
kubectl get certificates | grep opensearch

Много сертров, часть с 365 дней(как бы намекает), часть 728, часть 180 дней.
Так, проблема в серте для опенсёрча, опенсерч мастер не стартует, сертификат надо обновить.
Не, ну а вдруг рестарт подов даст нам пересоздание сертов и секретов - делаем рестарт подов по лейблу.
Семь бед - один ресет.
kubectl get pod PODNAME -o yaml | grep -A8 -i labels
kubectl delete pod -l=opensearch.role=cluster_manager

После рестарта, снова рестарты пода есть. Ок, не помогло, ладно.

У меня очень слабый опыт с опенсёрч, а с опенсёрч в кубернетисах ещё меньше, да и ставил его не я.
Сперва разбираемся, как нам обновить серт:
- руками и чтобы быстро всё заработало
- что-то поправим в конфигах и оператор(если он есть) должен пересоздать серт
Смотрю все аннотации, название, даты и прочие атрибуты у сертификатов и secrets - нигде, ска, нет упоминания кто генерировал сертификат.
Пробовал даже нейронку спросить, он мне генерировал команды типа
kubectl get secret opensearch-cluster-http-cert -o jsonpath='{.data.tls\.crt}' -n service | base64 -d | openssl x509 -noout -issuer
issuer=CN = opensearch-cluster

на один из сертификатов, но они не особо помогли понять ишшуера/эмитента.

Ладно, смотрим в IaC и самом кластере какие у нас сущности есть в кубере:
- есть опенсерч кластер (чарт хелма)
- есть опенсёрч оператор
Смотрим а вообще должен/умеет ли оператор в этой версии генерировать/перегенерировать при протухщести сертификат?
Читаем дефолт вэльюс + наши вэльюс файлы(из git репозитория)
helm show values opensearch-operator --version 2.7.0 --repo https://opensearch-project.github.io/opensearch-k8s-operator

Ни слова про cert, ни слова про tls. Поиском нет ничего.
Ок, а что у нас в самом чарте опенсёрч кластера?
Уже в самом гите опенсёрч кластера в гите вижу вэльюс файл с
security:
tls:
transport:
generate: true
perNode: true
http:
generate: true

Идём в гитхаб, читаем документацию по нашей версии - да, сертификат должен
- генерироваться
- перегенерироваться при протухшести
Но этого нет 👎
Смотрим issues на github - находим несколько про то, что сущности certificate/secrets НЕ удаляются при протухшести.
Воркэраунд солюшн - удаление и секретов и сертификатов.
Please open Telegram to view this post
VIEW IN TELEGRAM
7🤯3
#troubleshooting #одинденьизжизни

Часть 2 из 2.

Собираемся удалять сертификаты..

Так, стоп-стоп, а почему у нас был алёрт по рестартам пода, но не было по протухшести сертификата?
Значит мы почему-то это не мониторим.
Пока время есть давайте настроим хоть какой мониторинг/алертинг, а то через года снова траблы будут постфактум.
Гуглим, читаем про метрики, но по факту для быстроты я просто добавил 1 endpoint в blackbox exporter
---
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMProbe
...
spec:
...
targets:
staticConfig:
targets:
......
- https://opensearch-cluster.NAMESPACE.svc:9200

Смотрим появился ли этот хост и проверяем в Grafana explore
probe_ssl_earliest_cert_expiry{} < time() + 30 * 24 * 60 * 60

Супер. Метрика пошла, мы видим за что зацепиться, пилим алёрт (а у нас его и не было, блллл 🐒)
- alert: SSLBlackBoxExporter
expr: probe_ssl_earliest_cert_expiry{} < time() + 30 * 24 * 60 * 60
...
annotations:
summary: "SSL `{{ labels.instance }}` is expiring in {{ .Value | humanizeDuration }}"

Алерт прилетает, всё ок, возвращаемся к сертификатам.
Не глядя удаляем все сертификаты, на которые была ошибка.
kubectl delete certificate  CERTNAME1 CERTNAME2 

Видим новые пересоздались(оператором, которые прочитал про пересоздания наш конфиг кластера).
Делаем рестарт подов мастеров
kubectl delete pod -l=opensearch.role=cluster_manager

и.. и ничего - та же ошибка.
Ладно, удаляем все серты, которые TLS и которые для опенсёрча.
Удалили, рестарт подов мастера и.. и та же ошибка TLS.

Ладно, мы же уже опытные инженеры, смотрим а что у нас с secrets?
kubectl get secrets

и видим, что секрет не был пересоздан.
Ну, скорее всего баг - удаляем и secrets и certificates( естественно только те, что связаны с TLS, другие секреты мы не удаляем), серты пересоздаются, секреты пересоздаются, делаем рестарт подов мастера и..
и снова та же ошибка.
Смотрим внутри мастер пода
kubectl exec -it -- bash 

- да, серт новый монтируется.

Чего мы имеем:

- у нас НЕТ сертификатов со старым сертом
- у нас НЕТ секретов со старым сертификатом
- в под мастеров монтируется новый серт
- у нас уже есть алерт ❤️
- НО у нас есть ошибка TLS при старте мастеров

Ну ведь магии не бывает, может быть эээммммээ может соседние поды - warm + cold +dashboards имеют проблемы с сертом?
Смотрим на рестарты - рестартов у них нет.
Смотрим в логи, блл, стактрейс, java и снова переворачиваем монитор вертикально 🐒 - та же ошибка с сертом, но рестартов уже нет.
Странная фигня, но ладно, публикуем в slack канале ЩА ЛОГИ БУДУТ НЕДОСТУПНЫ ПАДАЖИТЕ
и рестартим ВСЕ поды всего опенсёрча по общему лейблу
kubectl delete pod -l opster.io/opensearch-cluster=opensearch-cluster

Происходит рестарт всех 17 POD-ов и.. и проблема ушла.

Итог:
- у нас появился алерт по протухшести на будущее (есть другие, на nginx контроллеры, но тут, внутренний ресурс по 9200 не было 🤡)
- опенсёрч сволочь такая на java, у него под капотом какая-то магия, с протухшим сертом мастера делают рестарт, а остальные нет и серт нужен всем (я хз для чего, да мне и не интересно) и рестарт всем для перемонтирования
- мы разобрались чуток и можно списать время в трекер джиры
- научились мастерски крутить монитором как рулём авто
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥26
#helm #devops

Валидации, проверки, линтеры.
Как много мы о них говорим, но и как это иногда важно.

У меня есть helm chart.
После изменения любых параметров или темплейтов я его проверяю.
- unit tests (ооооооочень редко и не всем нужно)
helm unittest ./helm-chart

- linter
helm lint helm-chart

Дальше публикация и куда-то релиз.
helm package helm-chart


Чарт готов, чарт проверен в пайплайне и пре-коммит хуками.

А что с values файлами на стороне приложений?
У меня же есть прекрасные коллеги с ровными руками.
Они могут в values файлах своих репозиториев при использовании нашего общего чарта допустить ошибку.
Ну так бывает, все ошибаются.
Могут написать "true" вместо true, могут не там сделать indent или вообще половину indent(1/3).
Которые при любых проблемах обвиняют девопсов 😮🫵😮.
Как быть тут?

На помощь мне приходит schema validation.
То есть на базе template мы генерируем schema.yaml файл, по которому будет идти сравнение values.yaml файлов у коллег.

Для начала я потренируюсь на кошках и возьму классный чарт отличного продукта
https://github.com/cloudnative-pg/charts
Клонирую его себе
git clone git@github.com:cloudnative-pg/charts.git


Затем мне надо написать схему.
Буду ли я просить нейронки?
👎Да пошли они в хер, с ними голова вообще перестала работать.🐒
Буду ли я сам писать схему?
Да щас 🤣.

Иду в awesome helm репу, ищу есть ли чего у нас там для скима валидейшн.
https://github.com/cdwv/awesome-helm
Нахожу поиском там генератор (второй депрекейтед)
https://github.com/dadav/helm-schema
Читаю - всё ок, отлично подходит под мою задачу.
Качаю, распаковываю и так далее
wget https://github.com/dadav/helm-schema/releases/download/0.18.1/helm-schema_0.18.1_Linux_x86_64.tar.gz
tar -xvf helm-schema_0.18.1_Linux_x86_64.tar.gz
chmod +x helm-schema
sudo cp helm-schema /usr/local/bin/


Теперь иду в свой склонированный cnpg репозиторий
cd ~/GIT/INTERNET/cnpg/  #(у вас путь другой будет само собой)

и просто запускаю бинарь
helm-schema

Результатом будет json файл(ы) в каждом чарте.
Один из файлов выглядит так
https://gist.github.com/kruchkov-alexandr/dc4cf3e4ac9af5719fb435d42e1873e6

Чарт есть, генератор схема валидейшн есть, схема есть.
Осталось научиться проверять.

У меня есть три основных варианта использования схемы:
- подсунуть комментарии-аннотации в values.yaml
- в VSCode мышкой клацнуть на схему и сам vscode будет подсвечивать ошибки
- команда в терминале в CICD

Мне больше нравится последний вариант автоматизации.
Немного душноты:
- команда helm template генерирует(рендерит) YAML манифесты.
- если есть файл JSON со схемой, то helm template проверяет ещё и схему!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
#helm #devops

Поехали проверять.
helm template alexk-test charts/cluster/

Всё ок, нет проблем, куча манифестов срендерилось.
Теперь иду в файл charts/cluster/values.yaml
и меняю
  endpointCA:
create: false

на
  endpointCA:
create: "false"

Снова запускаю и получаю ошибку
helm template alexk-test charts/cluster/
Error: values don't meet the specifications of the schema(s) in the following chart(s):
cluster:
- recovery.endpointCA.create: Invalid type. Expected: boolean, given: string


Отлично, у меня есть
- мой чарт/чарты
- автоматическая генерация схемы путем pre-commit и/или CICD команды схемы для чарта до релиза чарта
То есть когда мы что-либо меняем в своём чарте, то у нас и автоматическая проверка идёт и автоматически генерируется и в гите обновляется схема.

Дальше я свой общий pipeline для приложений коллег добавляю шаг helm template и он до релиза проверяет values.yaml файлы пользователей и коллег.

Так, а что у нас с GitOps ArgoCD подходом?
Ведь мы там не используем helm в чистом виде и нет понятия релиза.
Читаю документацию
https://argo-cd.readthedocs.io/en/stable/user-guide/helm/
Ура, под капотом ArgoCD использует как раз helm template, а значит мы при syncing увидим не просто ошибку, а ошибку в каком конкретно месте у нас ошибка.

Итог:
- в самом чарте появилась схема, к тому же она автоматически обновляется при каждом изменении чарта
- при использовании helm для релизов в моём pipeline я добавляю helm template для проверки корректности values.yaml файлов разработчиков
- в случае работы с ArgoCD у меня так же проверяется схема, снижая количество человеческих ошибок
- и со стороны чарта и со стороны репозиториев разработчиков есть pre-commit hooks (если на них забивают🐒)

Поздравляю - мы снова добавили какую-то очередную хероту автоматизацию и валидацию 🤣
Please open Telegram to view this post
VIEW IN TELEGRAM
9🔥61
#бытовое #мамкинпират

Совсем недавно маленькая инди-компания YouTube внедрила автоматический перевод на английском языке.
То есть открываешь видео на чувашском/русском/боснийском/испанском - а у тебя по-умолчанию дорожка звука с автоматической озвучкой на английском.

Это фича маленькой инди-компании, которая не умеет в тестирование, поломало функционал 99.999% всех сайтов, которые позволяли скачать видео в один клик, вставив ссылку.
Ведь теперь все видео качаются лишь с дорожкой на английском🤦🏻‍♂️.

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

На помощь к нам приходит проект
https://github.com/yt-dlp/yt-dlp

- устанавливаем депенденси (нужно для склейки аудиодорожки и видео)
apt install ffmpeg 

- качаем саму утилиту
wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp

- делаем исполняемым бинарь
chmod +x yt-dlp

- смотрим какие доступны дорожки на нашем файле
./yt-dlp -F https://www.youtube.com/watch?v=123456

- качаем видео в 1080р, отдельно оригинальную дорожку и мержим в один файл mp4
./yt-dlp -f "bestvideo[ext=mp4]+bestaudio[language=ru]/best[ext=mp4]" --merge-output-format mp4 https://www.youtube.com/watch?v=123456

- едем в поездку без связи, наслаждаемся видео и оригинальной дорожкой

———
Ни в коем случае не призываю нарушать авторские права авторов видео, условия предоставления сервисов от самого YouTube. Инструкция лишь для ознакомления.
Конкретно мне не хотелось платить ютубу, когда есть необходимость скачать лишь1-2 длинных видео для просмотра оффлайн в дороге без связи, а всё остальное время я онлайн и мне нет необходимости в платном сервисе, к тому же подписке.

———
5🔥5
#aws #tampermonkey

Мне очень нравятся shortcuts сервисов AWS.
Однако очень бесит, что они стали длинные и мне не очень удобно "листать" вправо/влево в избранном или вводить в строке поиска.
Хочется короткий текст для линков для быстрого перемещения.
Мог поправить через динамику, но у AWS очень строгий CSP.
Давайте попробуем фиксануть без CSP.

Я уже не в первый писал про плагин для браузера tampermonkey.
- ставим, если ещё нет https://www.tampermonkey.net/
- добавляем и включаем новый скрипт
- код крадём у меня и кастомизируйте под себя https://gist.github.com/kruchkov-alexandr/525a5166b7a55e2982b1015ba77a3456 (строчки 12-47)
- сохраняем скрипт
- обновляем страницу с AWS console
- радуемся мелким приятностям (скрин)

Переименование только в шапке и только на https://*.console.aws.amazon.com/*.
Всё остальное это не аффектит.
🔥7
#aws #devops #EKS #IRSA

На одном проекте пришла задача избавиться от IAM-кредов в подах и перейти на роли.

Есть три давно созданных EKS-кластера. Я написал Terraform-код: полиси, роль, policy attachment, service account, OIDC и всё остальное. Поправил Helm-чарт, добавив service account. Прокатил изменения по всем кластерам - всё ок.

На DEV я убрал IAM-креды из секретов, чтобы CDK перешёл на роль - всё ок. Сто раз всё проверил: секреты почистил, аппликейшены передеплоил, в AWS-консоли видно, что роль используется, IAM-креды - нет. Удалил IAM для DEV - всё работает. Повторил на STAGE - тоже всё ок.

И тут прод. Удалил креды - и всё рухнуло к чертям. Поды начали использовать роль ноды 🤡, у которой, естественно, нет доступа ко всем ресурсам AWS. Вернул креды, откатил, прод поднял, получил по щщам и начал дебажить.

Сто раз перепроверил Terraform-код - всё идентично. Проверил OIDC, IRSA, роли - всё совпадает, проблем нет. Но почему-то на проде поды не берут нужную роль.

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

Проверил mutatingwebhookconfigurations:
dev
kubectl get mutatingwebhookconfigurations | grep pod-identity-webhook
pod-identity-webhook

stage
kubectl get mutatingwebhookconfigurations | grep pod-identity-webhook
pod-identity-webhook

prod
kubectl get mutatingwebhookconfigurations | grep pod-identity-webhook
hui

Кто-то (или что-то) когда-то как-то удалил pod-identity-webhook на проде. Как так вышло - история умалчивает, это останется тайной. Жаль только часов дебага, когда я матчил код, роли, OIDC и IRSA, не подозревая, что мутейшн хука просто нет. 🚶‍♀
Что делает этот вебхук? (текст украден из чата кубера):
- Добавляет переменные среды:
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount
AWS_ROLE_ARN (значение берётся из аннотации к SA)

Добавляет в волумы:
- name: aws-iam-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
...
- mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
name: aws-iam-token
readOnly: true

И всё. Дальше куб сам выписывает SA-токен с aud: sts.amazonaws.com.

Принял быстрый фикс:
Установил cert-manager (если его не было):
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml

Склонировал и развернул:
git clone https://github.com/aws/amazon-eks-pod-identity-webhook
cd amazon-eks-pod-identity-webhook
make cluster-up IMAGE=amazon/amazon-eks-pod-identity-webhook:latest

Проверил логи:
kubectl logs -n default -l app=pod-identity-webhook

Запустил тест:
kubectl run irsa-test --image=amazon/aws-cli -n production --overrides='{"spec":{"serviceAccountName":"new-sa"}}' --command -- sh -c "aws sts get-caller-identity && sleep 3600"

Получил:
{
"UserId": "54252523:botocore-session-2345452354",
"Account": "2345452345",
"Arn": "arn:aws:sts::234534524:assumed-role/expected-new-role/botocore-session-345235"
}

Ура, теперь поды используют новую роль. Убил тестовый под. Удалил IAM-креды, накатил снова - всё ок.
Задача решена.🎉

.....
Прошло пару дней.
.....

Сижу, значит, пишу этот текст-заметку, пока не забыл, и задумался: неужели такое возможно в 2025? Зачем? Зачем, мистер Андерсон, вообще руками что-то ставить в кластер, kubectl apply -f??

Читаю за утренним кофе документацию, пока жена не видит:
- https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html
- https://docs.aws.amazon.com/eks/latest/userguide/pod-id-agent-setup.html
Дошёл до:
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_pod_identity_association
.
..
...
Прочитал, промолчал, набычился, посмотрел на пол, закатил глаза, надел kubectl apply -f клоунский нос 🤡 и отправил пост в телеграм.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁16👍2😨2
#github #devops

Заметка капитана очевидности.

Когда мне надо что-то найти для задачи/работы, но "я пока не знаю что", то я начинаю запрос с awesome.
Иногда ищу в Google, иногда сразу на GitHub.
99.9% результата поиска в Google всё равно ведёт в GitHub.

Это может быть что угодно:
- алёрты alertmanager
https://samber.github.io/awesome-prometheus-alerts/
- хуки гита
https://github.com/compscilauren/awesome-git-hooks#readme
- cheat sheets гита
https://github.com/arslanbilal/git-cheat-sheet#readme
- утилиты Kubernetes
https://github.com/vilaca/awesome-k8s-tools
https://github.com/ksoclabs/awesome-kubernetes-security
https://github.com/magnologan/awesome-k8s-security
https://github.com/calvin-puram/awesome-kubernetes-operator-resources
- системные утилиты
https://github.com/luong-komorebi/Awesome-Linux-Software
https://github.com/cuongndc9/awesome-linux-apps
- чего-то для баша
https://github.com/awesome-lists/awesome-bash
- фреймворки go
https://github.com/avelino/awesome-go
- правила для Cursor IDE
https://github.com/PatrickJS/awesome-cursorrules
- либы питона
https://github.com/uhub/awesome-python
- платные и бесплатные статуспейджи, селдфхостед и менеджед
https://github.com/ivbeg/awesome-status-pages
- MSP
https://github.com/guardzcom/awesome-msp
- для Helm
https://github.com/cdwv/awesome-helm
- MCP сервера
https://github.com/punkpeye/awesome-mcp-servers

Список почти бесконечный.
Утилиты, книги, плагины, tips&tricks, темплейты.
🔥193