Make. Build. Break. Reflect.
1.3K subscribers
145 photos
3 videos
1 file
155 links
Полезные советы, всратые истории, странные шутки и заметки на полях от @kruchkov_alexandr
Download Telegram
#devops #sql #index

Индексы.

Сегодня слишком жарко и погулять не удалось.
А значит надо накидаться алкоголем и играть в стимдеку сделать что-то полезное для разминки ума.
Открыл в браузере папку с закладками "Почитать на потом" (думаю, она есть у каждого) и выбрал случайную ссылку:
https://use-the-index-luke.com

Думал, почитаю минут 10-15, но зачитался надолго с большим интересом.
По ощущениям, закрыл целый пласт знаний: от понимания, что такое индексы и как они устроены, до более сложных тем, вроде оптимизации запросов.
На сайте масса информации, я читал выборочно то, что было полезно для работы.
Особенно понравились разделы про структуру индексов и их использование в "WHERE".

Рекомендация всем, кто:
- не знает, что такое индексы
- слышал, что "если БД тормозит - смотри индексы", но не понимает, как это работает (как я 😁)
- хочет укрепить знания или закрыть пробелы

Ресурс подходит всем инженерам, независимо от роли - администратора баз данных, DevOps или разработчика.
Текст доступен даже новичкам, можно читать на английском или через автопереводчик браузера.
Разделов много, можно изучать всё подряд или выборочно, как я.

Обязательно к прочтению, если хочется разобраться в индексах.
Рекомендация 💯.

* предполагаю, что впереди меня ждет не одна всратая история, связанная с обновлёнными знаниями по индексам и анализу "что у меня на работе у коллег" 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍224👌1
#azure #finops #devops

Меня вдохновили одной историей-задачей от коллеги, но расскажу всё от своего имени, а что вы мне сделаете, заметки то мои 🤣
На мой личный взгляд это потрясающая работа сильного, профессионального и изобретательного инженера.

Была подзадача "перетащить часть проекта с Azure stack на Bare metal".
С платформой и стеком выбор был уже почти сделан, надо было лишь развернуть инфру и перетащить данные.
Инфру развернули за 0.0001мс - мы же все гитопсы теперь.
С данными вышла засада - их было 330+ терабайт. И это лишь в одном блобе. Блобов много.
Мы были не готовы к таким цифрам в bare metal и это пахло проблемами.
И капасити и скорость передачи данных в бар метал - это сколько недель ждать?
Решили вообще узнать - а все ли данные нужны?
Зашли к девелоперам по datawarehouse стеку, они сказали нечто типа "ну мы, конечно же, компания, специализирующая на данных, данных у нас ОЧЕНЬ много, но цифра не похожа на настоящую".
Это отличный пойнт, а значит время для анализа.
Базово ажур ничего не даёт по аналитике, либо за деньги, а потому надо всё включать.
Первым делом включили Inventory - специальный инструмент, позволяющий получать отчёт о всех данных внутри блоба. Запустили, сутки ждали, он сформировался в CSV файле, вроде около 150 мегабайт.

Ок, у нас есть миллионы строчек, но сами же мы не будем глазами считать.
Создаём локально базу данных PostgreSQL.
Затем создаём табличку типа (тут есть ошибки, но это не влияет на саму задачу)
https://gist.github.com/kruchkov-alexandr/9f1210db954c92b059113835e950562e
Запускаем DBeaver и импортируем CSV файл в это локальную базу данных PostgreSQL.

Данные по объектам в блобе, а значит пора мучать любимый AI ассистент SQL запросами, нечто типа
https://gist.github.com/kruchkov-alexandr/73096e1a8a78274944dcb3c02c45f090
Оба запроса собирают статистику по контейнерам blob, считая количество файлов и их суммарный размер в GiB, также выводят общий итог по всем контейнерам.

Возвращаемся к девелоперам, показываем статистику, анализ, все в шоке, срочный колл, разбор полётов.
Не буду опускаться в суть бизнес процессов, почему и где была логическая проблема, но в общем у нас был сбой
и данные дублировались. Трижды всё проверили, расписали план и двинулись дальше:
- удалили часть данных
- включили лайфсайкл полиси на 1 день
- выключили safe delete или как это называется
- что-то ещё, но я уже не помню

В общем на момент истории блоб весит 44 терабайта, удалено больше 280 терабайт.

Какие же потери мы понесли с момента бага с дублированием?
- чтение/перечтение данных каждый день
- операции
- хранение
Итого $3500+ в месяц. За один только блоб.
Просто три с половиной шутки за мусорную дату каждый месяц....

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

Да, компания специализируется на дате, её очень много, и само собой никто уже с огромными объемами не мониторил банальный сбой и дублирование / версионирование / сейфделиты / редубликацию трафика на ингрессе и так далее. Когда данных петабайты, особо не следишь где чего и сколько. Всем кажется, что это нормально.

Итоги:
- коллега я, крутой и мощщный синёр помидор, показал всем, как делать аналитику сотен миллионов объектов в блобе
- узнали о величайшем(нет) провале по мониторингу биллинга и размера даты
- на момент стори снизили косты на $3500+ в месяц 😭 Точная сумма будет известно потом, когда завершаться все работы по всем стораджам, а их не мало.
- отчасти сняли блокер по переносу даты в барметал (нет, но это другая история)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥51😁1
#azure #devops #entra #powershell

Мелкая компания из трёх суетливых инженеров при удаче вырастает до большой организации в 150+ человек.
Люди уходят и приходят, а хорошего процесса оффбординга Entra ID иногда нет.
Иногда удаляют/выключают аккаунты, иногда нет. Иногда просто создают и не пользуются.
Чистка аккаунтов это крайне важный элемент девопс процессов.
Рано или поздно приходит любой аудит и очистка аккаунтов необходима.

И вот аудит пришёл.
Именно тогда прилетают странные задачки, типа "причесать каталог юзеров".
Захожу, а там 200+ аккаунтов, 85% которых я вижу впервые.

Хорошо, моя идея в общих чертах такая:
- найти всех пользователей
- отсортировать тех, у кого аккаунт включён (accountEnabled)
- собрать ключевые данные: Display Name, UPN/Email, дата создания и, главное, дата последнего входа
- отфильтровать по порогу неактивности (например, более 60 дней)
- сформировать таблицу (CSV-файл) с колонкой для решения ("Действие")
- отправить файл руководству (коллегам/боссу/СТО) на согласование, чтобы избежать удаления важных служебных аккаунтов или аккаунтов инвесторов
- удалить/выключить пользователей согласно утвержденному списку.

Как же это сделать? Ведь Microsoft Entra ID не предоставляет таких данных в удобном виде *.
Да и az cli такого не предоставляет.
На помощь приходит PowerShell и модули.

Поехали пошагово:
- запускаю PowerShell с правами администратора
- проверяю есть ли права на выполнение скриптов
Get-ExecutionPolicy
Restricted

- если рестриктед, то надо включить(не забыть выключить)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
Y

- теперь мне надо установить модуль
Install-Module Microsoft.Graph -Scope CurrentUser

- импортирую модуль для этой сессии
Import-Module Microsoft.Graph.Authentication

- затем надо подключиться к Microsoft Graph с такими правами
Connect-MgGraph -Scopes "User.Read.All", "AuditLog.Read.All"

На этом этапе откроется браузер, надо пройти авторизацию
- пилим скрипт(можно даже построчно вводить)
$InactiveDays = 60
$DateCutoff = (Get-Date).AddDays(-$InactiveDays)

$Users = Get-MgUser -All -Filter "accountEnabled eq true" -Property Id, DisplayName, UserPrincipalName, SignInActivity, AccountEnabled

$InactiveUsers = $Users | Where-Object {
$_.SignInActivity -ne $null -and
$_.SignInActivity.LastSignInDateTime -ne $null -and
$_.SignInActivity.LastSignInDateTime -lt $DateCutoff
} | Select-Object DisplayName, UserPrincipalName, @{Name="LastSignInDate"; Expression={$_.SignInActivity.LastSignInDateTime}}

#mock
$InactiveUsers | Format-Table
$NeverSignedInUsers = $Users | Where-Object {
$_.SignInActivity -eq $null -or
$_.SignInActivity.LastSignInDateTime -eq $null
} | Select-Object DisplayName, UserPrincipalName, @{Name="LastSignInDate"; Expression={"Never Signed In (or before Apr 2020)"}}

$InactiveUsers + $NeverSignedInUsers | Format-Table -AutoSize

- на выходе получаю
DisplayName              UserPrincipalName          LastSignInDate
----------- ----------------- --------------
Ivan Petrov ivan.petrov@contoso.com 2022-03-15 10:45:12
Maria Sidorova (Guest) m.sidorova_ext@contoso.com 2021-11-20 14:02:55
Alexey Smirnov a.smirnov@contoso.com 2022-04-01 08:10:30
New Folder(1) test.user@contoso.com Never Signed In (or before Apr 2020)

- копирую, вставляю в Excel, добавляю новую колонку delete/don't touch
(или сразу пилить в CSV, как кому удобнее)
($InactiveUsers + $NeverSignedInUsers) | Export-Csv -Path "C:\Users\alexk\InactiveUsers_Audit.csv" -NoTypeInformation

- отправляю руководству
- получаю ответ, выключаю/удаляю ненужных юзеров
Задача закрыта, в каталоге порядок.

Так. А почему именно я делаю эту задачу?
А нечего было всем в рабочих чатах говорить, что винда лучшая операционная система.
Вот и сиди, пиши пош-скрипты 😭
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😁6
#aws #costoptimization #devops

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


Был случай: проект, всё на AWS, стартап.
Постепенно рос, изменялся, но изначально у всех всюду был root-доступ (а как иначе в стартапе из 4 человек?). Набирались люди, улучшались процессы, разграничивались доступы, всё заносилось в IaC.
В целом стоимость услуг AWS была сравнительно небольшой, от 2к до 5к долларов, и держалась года полтора-два.
Раунд за раундом, компания выросла, трафика и сервиса стало больше, увеличился и счет.
Затем начали оптимизировать затраты: внедрили RI, SP (Reserved Instances, Savings Plans) и другие методы.
Обвешали обычным алертингом и FinOps-инструментами вроде Cost Anomaly Detection.
Каждые 1-3 месяца проводились Cost Review meetings, на которых обсуждались траты, предстоящий рост и многое другое. Каждая, повторюсь, позиция в биллинге детально разбиралась и для каждого участника команды и руководителя была очевидна, понятна и разумна.

Всё вышенаписанное лишь для того, чтобы подчеркнуть, что ничего нестандартного тут не было, всё как у всех.

Каждый месяц счет всё рос и рос. Где-то разумно за Compute - воркеры в EKS, где увеличилось количество реплик.
Где-то за RDS, потому как и размер БД увеличивается, и инстансы примерно раз в полгода-год увеличивали, да бэкапы (snapshots) также увеличивают стоимость хранения.
Где-то CloudFront, потому как количество клиентов и трафика стало больше.

Приходили и письма от Cost Anomaly Detection: "сервис А увеличился на 20% - теперь 21 доллар", "сервис Б увеличился на 47% и теперь 11 долларов".
И такие письма приходили регулярно.
Визуально - всё разумно и понятно:
- увеличивается количество кастомеров
- увеличивается трафик и нагрузка
- немного растет стоимость услуг

Однако пришел момент, когда счет за услуги CloudFront вырос до умопомрачительной отметки в 1000 долларов в месяц.
На очередном Cost meeting поставили задачу проверить корректность настроек, везде ли правильно включено кэширование, заголовки и так далее.
Триггернулись лишь потому, что на старте компании платили порядка 30 баксов, спустя год 150, затем 400 через два года, а тут сразу $1000 - слишком большой скачок.

Задачу поручили мне, и я начал копать.
Признаюсь - я ничего на тот момент не понял.
Ну ALB, CloudFront да API Gateway.
Много ресурсов, разные.
Поверхностно изучил еще раз - да, вроде очевиден рост как клиентов, так и трафика и биллинга.
Отписался "да всё норм", закрываю таску.

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

Начал я повторно изучать, уже в процессе расписывая куда какой трафик идет, спрашивая разработчиков, смотря DNS, балансировщик, все файлы веб-страницы и многое другое.
Я это изучал лишь чтобы понять, как сейчас что работает, чтобы понять, как и на что мне надо заменить, чтобы снизить косты.

В процессе анализа для переноса архитектуры мне пришел неожиданный вопрос в голову:
а счет за CloudFront это с одного Distribution или с разных?
Начал включать аналитику и овервью.
Определились, что траты лишь с двух Distribution из 25.
Вопреки тому, что все думали изначально, что с 10-15.

Ок, копаю дальше, стало интересно, ведь именно у этих двух Distribution было несколько источников (Origins) и несколько правил поведения (Behaviors).
Мне же надо их на что-то менять, надо копнуть глубже.
👍9
#aws #costoptimization #devops

Затем я включил логирование (Standard log destinations) и положил все логи в S3 бакет.
Оставил на полдня, потом написал Bash-скрипт, который сделал простую выборку, например, top 20 requests by path с сортировкой по пути.
Тут меня ждало очередное удивление - в топе были не файлы S3, а балансировщик нагрузки (ALB) и поды Kubernetes🤡.
То есть, у нас топ трафика - это НЕ кэшируемый трафик! 🤬Через клаудфронт! 🤬
Написал еще пару скриптов - да, у нас внезапно в этой схеме просто трафик шел в EKS и пару мест.

Собрали консилиум с коллегами, рассказал о своей, находке, чтобы спросить "а зачем так?".
Ответ был очевидным типа "ну так было исторически, нам надо было как-то роутить трафик по пути, мы в своё время сделали это через клаудфронт, чтобы не поднимать ещё один балансер или Nginx".
"Пздц" - подумал я и пошёл дальше изучать.
Да, действительно так и оказалось - часть трафика, и это 98% от всего в клаудфронте, шло НЕ для кеша.
Просто в поды кубернетиса.

Быстро напилил альтернативное решение, пару днс записей, проверили на dev - всё работает ок, без клаудфронта.
Дальше стейдж, прод, никаких проблем.

Сижу пишу postmortem.
Понимаю, что надо сослаться на саппорт амазона, типа они негодяи не присылали кост аномали детекшн письма - но нет, присылали.
Думаю может не было реакции - нет, обсуждали повышения цен, даже текстов в чате.

Как так мы пропустили этот момент?
Подняли исторически все данные и за последние пару лет и только тогда картина полностью стала ясна.
- Изначально был временный костыль в одном из клаудфронтов - если путь /path1 то трафик отправлять в X, а если /-path2, то временно в Y.
- этого трафика была изначально мало и он вовсе попадал во free tier.
- затем его стало больше, стали платить 40 баксов, что было допустимо, затем 80 и так далее.
- пока не вырос до 1000 и 1250 долларов на момент кост инцидента.

Почему не обращали внимание раньше?
Потому что рост цены был медленным:
- кост аномали детекшн ловил рост цены примерно раз в неделю, и сумма каждый раз была небольшая
При постоянном медленном росте кост аномали детекшн начал отправлять всё реже и реже письма - это же очевидное поведение стало.
- все дефолт ссылки ведут на "cost and usage report" с коротким промежутком времени типа последние 30-40 дней
- на графиках и в письмах был небольшой рост - ну кто будет заниматься, если на прошлой недели мы платили 9 баксов день, а теперь 11 долларов в день, копейки же

Лишь взглянув на графики за полгода/год/два года/три года, стало ясно, что цена увеличивались постоянно.
Временный костыль начал в итоге вырабатывать 14 терабайт данных трафика.

Косяк девопса? Да.
Косяк костменеджера? Несомненно.
Косяк "временного решения"? Конечно.

Иногда, чтобы узнать, что проблема есть, надо нырнуть чуть глубже, чем "да вроде по делу списывают да не много же".
Иногда, чтобы узнать, что проблема есть, надо расширить графики больше, чем на две недели.

Суммарные потери последних 8 месяцев до этого кост инцидента - 4400 долларов.
Этот path в клаудфронте и не нужен был, просто поленились много лет назад сделать сразу нормально.
Please open Telegram to view this post
VIEW IN TELEGRAM
🫡14👏3😢21👍1
#kubernetes #devops

Последнюю неделю на работе игрался с KRO, AWS ACK и CrossPlane.
- https://github.com/crossplane/crossplane
- https://github.com/aws-controllers-k8s/community
- https://github.com/kubernetes-sigs/kro

Ну что я могу сказать.
Мне одновременно и очень понравилось - инструменты хороши.
Это потрясающие инструменты, выводящие инфраструктурную часть и операционную на совершенно иной уровень.
Не плохой, не хороший, он новый. Не буду приводить аналогий, это просто иной уровень для меня.
Да охрененный, если честно, буду честен.
И одновременно не понравилось - самостоятельно, в одиночку, в одно лицо, без помощи AI ассистентов я разобрался бы в лучшем случае через недели 3-4. Возможно бы и через месяц.

Сложность в том, что эти инструменты создают десятки уровней абстракций - от CRD в Kubernetes до специфических API провайдеров (AWS, GCP). Чтобы отладить ошибку, нужно пройти путь от kubectl describe до логов ACK controller, а потом до настоящего события в облаке. Рисуешь сперва диаграммы, зависимости, порядки деплоя - это колоссальная работа.

Вообще прикольно, конечно, один манифест и фигак, у тебя целые регионы, кластера, роли, рут таблицы, натгейтвеи и миллион сущностей в кубернетисах. Миллионы объектов и сущностей на сотнях уровней абстракций.
Круто. Мне понравилось.

Про KRO/ACK/CrossPlane я ещё напишу не одну глубокую техническую заметку/отзыв, а пока лишь общий отзыв - они хороши.
👍151👏1
Приветствую всех.

Поскольку все читатели здесь ради контента, а не моей биографии, сразу перейду к сути.
Этот блог - мои заметки на полях.
Почти не делаю репосты, пишу для души и лишь когда на это есть время/желание.
Обычно это 2-4 поста в неделю.

В основном делюсь:
- информацией, которую узнал только что (даже если она пятилетней давности, но я узнал её сейчас)
- лонгридами, байками или всратыми историями, без указания срока давности
- последовательным описанием моего процесса мышления на работе при решении задач

Интересные, на мой взгляд, сообщения я публикую с тегами:
- пример основных тем канала:
#aws #azure  #kubernetes  #troubleshooting  #costoptimization  #longread  #devops
- пример второстепенных категорий:
#terragrunt  #victoriametrics  #git #docker  #одинденьизжизни  #helm
- для того, чтобы на работе не поехать кукухой, у меня есть:
#пятница  #всратость  #байки

Сообщения без тегов это просто шутка-минутка или мысль, которая была актуальна лишь на момент написания.

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

Буду рад, если мои заметки помогут кому-то узнать что-то новое, избежать повтора чужих ошибок или просто улыбнуться.
На крайний случай, самоутвердиться за счёт моих факапов или незнания 🐒
Всем привет и желаю приятного чтения.
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍362👨‍💻1
#devops #security #nginx #tls #privacy

Тихо и незаметно (для меня) NGINX 1.29.4 официально добавил поддержку Encrypted Client Hello (ECH).
Для инженеров, которые следят за приватностью трафика, это важная новость.

Что такое ECH и почему это важно.
ECH - расширение TLS 1.3, которое шифрует полностью весь ClientHello, включая Server Name Indication (SNI).
Раньше SNI передавался открытым текстом: любой наблюдатель на сети видел, к какому домену вы коннектитесь, даже если содержимое соединения зашифровано. ECH устраняет этот пробел.


ECH использует два ClientHello:
- ClientHelloOuter - видимый, с "dummy" SNI
- ClientHelloInner - зашифрованный, с реальным SNI и другими параметрами

Шифрование происходит через HPKE (Hybrid Public Key Encryption).
Если сервер не может расшифровать inner, он завершает handshake с outer и сообщает клиенту актуальный ключ для повторной попытки.

Важные требования:
- DNS-over-HTTPS обязателен - без него публикация ключа в DNS небезопасна
- Частая ротация - рекомендуется ротировать ключи каждый час (как Cloudflare)
- HTTPS-записи -должны быть корректно настроены с параметром ech=

Для инженера это значит:
- провайдер или DPI-бокс не увидит, куда идёт трафик из вашей инфраструктуры
- метаданные перестают быть источником утечек
- комплаенс с требованиями privacy-by-design становится проще

Что уже работает:

- NGINX принимает директиву ssl_ech_file /path/to/ech-keys.pem
В контексте http/server - она указывает PEM‑файл с ECHConfig и ключами, необходимыми для включения TLS 1.3 ECH в shared‑режиме.
​- поддержка HTTP и Stream модулей
​- ротация ключей через несколько файлов и nginx -s reload - директива ssl_ech_file может указываться несколько раз для разных файлов, что позволяет операционно ротировать ECH‑ключи.
​- мониторинг через переменные $ssl_ech_status и $ssl_ech_outer_server_name - они дают статус обработки ECH

Чего мне пока не хватает для продакшена:
- стабильная версия OpenSSL с ECH
ECH поддерживается только в экспериментальном бранче feature/ech OpenSSL.
Хотя OpenSSL 3.5 LTS вышел в апреле 2025, ECH не вошел в основной релиз и требует сборки из специального бранча.
- отсутствие интеграции с инфраструктурой
Let’s Encrypt и другие CA пока не выдают ECH‑ключи через ACME‑протокол - механизм не стандартизирован. Обычные TLS‑сертификаты работают с ECH без изменений, но получить и автоматически обновить ECHConfig‑ключи придётся вручную.
Публикация ключей в DNS (через HTTPS/SVCB‑записи) требует ручного управления или кастомных скриптов.
- ограниченная поддержка клиентами
Хотя Chrome и Firefox поддерживают ECH, некоторые корпоративные библиотеки еще не обновлены.

Как же это плюсы для для девопс-команд?
1) Privacy-focused сервисы🔥🔥🔥
server {
listen 443 ssl http2;
ssl_ech_file /etc/nginx/ech-keys.pem;
# Теперь SNI не виден провайдеру!
}


2) Мультитенант платформы
- скрываете имена клиентских доменов от внешних наблюдателей
- полезно при shared infrastructure с чувствительными данными

3) Корпоративные VPN-шлюзы 🔥🔥🔥
- скрываете конечные точки внутри корпоративной сети
- провайдер видит только коннект к VPN-шлюзу, не к конкретным сервисам

Что делал я для домашней лаборатории:
git clone -b feature/ech https://github.com/openssl/openssl.git
./config --prefix=/opt/openssl-ech && make && sudo make install

./configure --with-openssl=/opt/openssl-ech \
--with-http_ssl_module \
--with-stream_ssl_module
make && sudo make install

/opt/openssl-ech/bin/openssl ech_keygen -out /etc/nginx/ech-keys.pem

+ крайне важно не забыть добавить DNS публикацию ECH-ключей.
Ключи ECH не работают изолированно - их обязательно нужно опубликовать в DNS через HTTPS-записи (SVCB/HTTPS-тип).
Без этого клиенты не узнают, что сервер поддерживает ECH.
_443._https.example.com. IN HTTPS 1 . ech=AEj+DQBE..
314🆒3👍1🤯1
1.png
431.8 KB
#devops #git

Никакого рокетсайнса или, прости господи, лайфхаков, просто делюсь наблюдением.

Последние месяцы для работы со схемами/диаграммами вместо привычных ресурсов (draw.io excalidraw.com diagrams.mingrammer.com) перешёл на связку:
- любой AI ассистент, любая модель
- markdown файл https://www.markdownguide.org/
- mermaid фреймворк https://mermaid.js.org/

Поддержка mermaid в MD файлах уже достаточно давно, а основные инструменты - VSCode, GitHub, GitLab, Cursor умеют это отображать для человека и в IDE, и в веб-браузере.
В некоторых случаях надо ставить плагин, но в некоторых уже работает и так.

Как это работает:
- я прошу ассистента нарисовать некую схему. Схема может быть обычная flowchart, может быть state, sequence или что-то другое
- в основном README.md или CLAUDE.md появляется блок кода, который отлично лежит в md файле и при этом
- - схема видна в IDE через preview режим
- - схема видна в браузере на страницах GitHub/GitLab
- - схема понятна любой нейронке
- самое главное, это прозрачно и для меня и нейронка понимает что хочет, чтобы изменение кода было корректным
- ну и всё это в git репозитории

Рандомный пример промпта:
Нарисуй flowchart в mermaid, который показывает, как Pod с toleration scheduling'ится на tainted node в Kubernetes


Рандомный пример кода (в файлах формата *.md)
graph TB
subgraph "Node Pool"
N1[Node 1<br/>No Taint]
N2[Node 2<br/>Taint: dedicated=app:NoSchedule]
N3[Node 3<br/>Taint: dedicated=app:NoSchedule]
end

subgraph "Pods"
P1[Pod A<br/>No Toleration]
P2[Pod B<br/>Toleration: dedicated=app]
P3[Pod C<br/>No Toleration]
end

P1 -->|Can Schedule| N1
P1 -.->|Cannot Schedule| N2
P1 -.->|Cannot Schedule| N3

P2 -->|Can Schedule| N1
P2 -->|Can Schedule| N2
P2 -->|Can Schedule| N3

P3 -->|Can Schedule| N1
P3 -.->|Cannot Schedule| N2
P3 -.->|Cannot Schedule| N3

style N1 fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#1B5E20
style N2 fill:#FCE4EC,stroke:#E91E63,stroke-width:2px,color:#880E4F
style N3 fill:#FCE4EC,stroke:#E91E63,stroke-width:2px,color:#880E4F
style P1 fill:#E3F2FD,stroke:#2196F3,stroke-width:2px,color:#0D47A1
style P2 fill:#E3F2FD,stroke:#2196F3,stroke-width:2px,color:#0D47A1
style P3 fill:#E3F2FD,stroke:#2196F3,stroke-width:2px,color:#0D47A1

Результат на скриншоте (GitHub + Cursor IDE).
Сами промпт/схема просто рандомно-мусорная, лишь для примера.

Можно рисовать что угодно:
- схема инфры
- как работает хэндшейки бэкенда
- логика распределения подов по нод группам в кубере
- как работает самописный оператор
- sequence diagram, как микросервисы общаются при отказе базы
и так далее.

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

Мы итак многие инженерные вещи переусложнили.
Хочется хотя бы с диаграммами и схемами сделать всё проще.
5👍286
#devops

Просто делюсь последними находками.

- https://system-design.space/
Нечто типа русскоязычного справочника по system design.
Большой и объёмный. Начал почитывать, весьма годно.
За один присест всё не осилить, буду продолжать как книгу читать ближайшие месяцы.
Достойный аналог известному https://github.com/donnemartin/system-design-primer

Оцениваю как 9.5/10.

- https://endoflife.date/
А где-же, а где-же я смотрю когда что протухнет?
Не руками/глазами же смотрю на сайте каждого облака/ продукта/ компонента/ девайс/ операционка/ имадж/ фремворка/ либы.
Если надо глазами глянуть, то этот сайт просто топ.
Для обычных библиотек софта есть dependabot/Renovatebot (кстати, кто-то из них с этого же сайта берёт инфо).
А для всего остального этот ресурс.
Может даже у него MCP есть, но я не искал, я быстрее глазами найду, чем заряжать на это LLM.

Оцениваю как 9/10 (есть не всё).

- https://thenewstack.io/
Невероятно захватывающие и очень интересные мне истории, случаи, опыт, рассказы, postmortems.
DevOps, k8s, cloud и вот это вот всё.
Читаю те топики, что мне интересны, часть пропускаю (есть и маркетинг буллшит).

Оцениваю в 8.5/10.

- https://awesome-llmops.inftyai.com/
- https://github.com/InftyAI/Awesome-LLMOps
Неплохая таблица как у https://landscape.cncf.io/, но по LLM/LLMOps.
Курируемый список (awesome list) инструментов для LLMOps, он охватывает инференс, оркестрацию, RAG, агентов, fine-tuning и мониторинг LLM.
​Короче очередной неплохой awesome список.
В мире AI, когда каждый день всё меняется, это неплохой источник.
А надо быть в курсе всего этого, иначе уволят будешь не в теме.

Оценка 8/10.

- https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf?hsLang=en
Крутой мануал по скиллам. Сразу запилил себе кучу всего полезного.
Нет смысла рассказывать, что себе сделал, так как эта инфа устареет уже завтра, когда выйдет очередная новая модель и обновление курсора с новыми фичами.
Имеет смысл ознакомится и попробовать либо сейчас, либо сразу скипнуть.

- https://agentsmd.io/agents-md-best-practices
Бест практисы с AGENTS.md файлом.
Ровно как и предыдущая ссылка будет актуально лишь короткое время.
Имеет смысл ознакомится и попробовать либо сейчас, либо сразу скипнуть.

- https://github.com/metalbear-co/mirrord
Очень интересная задумка. Конечно же у него есть аналоги, но мне понравилась эта реализация.
Потыкал на лабораторном кластере с go-шным и php стеком - прикольно!
В отличии от telepresence/gefyra/nocalhost невероятно низкий входной порог и буквально в три клика развернуть.
Простота в наше переусложнённое время дорогого стоит.
Однозначно лайк, надеюсь они не умрут через полгода.

Оценка 10/10.


Было ещё много прочитанного, изученного, но в общем и целом это, скорее, белый шум, чем что-то, чем хочется поделится.
10👍20🔥16
#devops #troubleshooting

Из всего невообразимого и бесконечного потока, любимого и одновременно ненавистного всеми, AIAIAIA со всех углов, мне больше всего понравились skills.
Вообще ничего больше не впечатлило за последние года два - как скиллы.
Ну да, ну эйая, ну вайбкодинг. Это даже все бабушки знают и слышали.

Но, господи, как же скиллы охрененно работают в траблшутинге.

Вот пишу я это и понимаю, что скиллы сейчас - топ артефакт в работе девопса и SRE.
Во всяком случае, как я это использую - прям рекомендация 1000000 из 1.
Я готов прыгать от счастья, осознавая сколько времени они мне экономят.

Если вы не знаете как их использовать - попробуйте.
Начните с любого простого примера.

Как использую у себя в двух словах:
- создал несколько SKILLS.md файлов (на самом деле у меня их иерархия, уже 29 скиллов)
- замапил скиллы для Cursor IDE. Можно и в Claude Code, скиллы будут работать и там и там, просто путь разный
- в скиллах и основном ридми файле описал структуру проекта(ов)
- - где ArgoCD (UI, API, git repos)
- - какой нейминг у кластеров кубернетис (AKS, EKS, GCP), нейминг неймспейсов
- - где вообще все гит репозитории и иерархию
- - адрес гитлаба и зеркало, локальные склонированные репозитории
- - что контекст переключается локально через kubectl
- - есть утилиты kubectx, jq и многое другое
- указываю все ключевые адреса репозиториев и ендпойнтов (виктория метрикс, виктория логс, алертменеджер, гитлаб и многое многое другое)
- если где есть сверхтяжелая авторизация, то говорю используй port-forward на внутренние service, там авторизации нет

В общем указал все, что надо для траблшутинга.

Как происходит процесс с моей стороны:
- прилетает алерт
- я копирую текст алерта в агент-ассистент (сейчас у меня курсор)
- жду
- агент смотрит что за кластер, неймспейс, под, контейнер
- лезет в гит, смотрит таймлайн когда кто что релизил, когда коммитили и где менялись какие версии или конфиги
- лезет в нужный кластер кубернетиса, смотрит в нужном неймспейсе, под, логи, дескрайб, ивенты кубера
- при необходимости лезет в логи виктория логс, метрики виктория метрикс (прям через curl)
- если надо, то лезет в арго
- если надо, то лезет в гит репозитории бекенда и фронтенда
- строит гипотезы, проверяет, уточняет
- при сомнениях что-то сам проверяет (ну типа если ему кажется, что проблема нехватки нод - нехватка ip адресов, то иди и проверь метрики сети в AWS и EKS CNI)
- если надо, лезет с рид правами в azure, gcp, aws cli
- выводит мне удобный формат по инциденту и вариант(ы) решений

С вероятностью 90 процентов это точный результат.

Чрезвычайно убого замазанные примеры на скриншотах.

Дальше я уже либо сам чиню, либо передаю другим командам, если дело в них.

Это только кажется, что это сложно, непонятно, магически. Нет.
Только представьте себя на месте агента: знаешь на 99 процентов структуру всей инфры, проектов, процессов.
Ты же как-то сам логически идешь по траблшутингу? Вот так и агент.

Да, это потребовали изначально колоссальной работы, скиллы постоянно обновляю и добавляю новые, но это просто топ находка последних трех, не побоюсь этого слова, лет.

Алерт - копипаст - ждешь пару минут (автоаппрув или каждую команду аппрув) - ответ и решение(гипотезы).


- - -

А вот теперь грустная правда этого позитивного отзыва по скиллам.
Честно говоря это первый артефакт моей работы, который я не хочу отдавать коллегам или боссам.
Скиллы это просто сильвербаллет в 2026 и я буду тянуть до последнего, делясь с командами.

На полном серьезе не хочу шарить на команду 🚬
Даже если кто из команды это читает.
Господи, кому я вру, если скажут - отдам уже завтра.☔️

Я ведь ровно так же понимаю, что написав свои 100500 скиллов, которые уже сейчас, на сотнях алертов и десятке инцидентов на 100 процентов точно дали ответ и удобный аутпут для команд, можно пошарить самостоятельному агенту или условному мидлу с зарплатой три копейки.
И я вылечу на помойку.
Вот такая грустная правда.

Скиллы - это прекрасно.
Скиллы - это главный мой артефакт работы в 2026.
Скиллы - это грустно, они на 10000 процентов подсократят работы нам, инженерам.☔️
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥236🤡3🫡1
#devops #certificate

Простая напоминалка (в том числе и себе) на 2026-2027 годы про TLS‑сертификаты.

Надеюсь, все избегут инцидентов с "протухшими" сертификатами в продакшене:
сроки жизни постепенно режут, и первая большая итерация начинается уже сейчас.

Кратко по таймлайну (публичные TLS, CA/B Forum):
398 > 200 дней (с марта 2026) > 100 дней (с 2027) > 47 дней (с 2029).

Параллельно сокращают сроки повторного DCV, к 2029 остаётся до ~10 дней на переиспользование проверки домена.

CA (официальные анонсы и FAQ):
- DigiCert - переход на 199‑дневные сертификаты:
https://knowledge.digicert.com/alerts/public-tls-certificates-199-day-validity
- DigiCert - FAQ по срокам валидности:
https://www.digicert.com/faq/tls-ssl-certificate-validity
- Sectigo - про риски и 200‑дневную валидность:
https://www.sectigo.com/blog/200-day-ssl-certificate-expiration-risk
- GlobalSign - 199‑дневные сертификаты с марта 2026:
https://www.nicsrs.com/blog/globalsign-199-day-ssl-certificate-validity-2026

ACME / Let’s Encrypt и короткоживущие серты (думаю такое у многих):
- Let’s Encrypt: с 90 до 45 дней, общий план:
https://letsencrypt.org/2025/12/02/from-90-to-45.html
- Разбор перехода на 45‑дневные серты:
https://www.certkit.io/blog/45-day-certificates
- Let’s Encrypt: 6‑дневные и IP‑сертификаты (интересно в контексте мира с 47 днями):
https://www.helpnetsecurity.com/2026/01/20/lets-encrypt-6-day-tls-certificates
https://letsencrypt.org/2026/03/11/shorter-certs-certbot

Инструменты и автоматизация:
- cert-manager (релизы, где можно отслеживать поддержку коротких сроков, ACME и т.д.):
https://cert-manager.io/docs/releases/

Хорошие обзоры по общему таймлайну 398 > 47 дней и подготовке:
- Гайд по адаптации к 47‑дневным сертификатам:
https://www.centralnicreseller.com/47-day-ssl-certificates-validity-adaptation-guide-for-businesses
- Обзор сокращения сроков и влияния на процессы:
https://www.eginnovations.com/blog/ssl-tls-certificate-lifetimes-to-reduce-to-47-days

Эпоха "раз в год продлил и забыл" заканчивается.

Владельцам приватных внутренних УЦ в изолированных контурах можно пока расслабиться 😬 - эти правила касаются именно публичных TLS.
Please open Telegram to view this post
VIEW IN TELEGRAM
😢8👍4🙏41
#devops #github

GitHub объявил, что с 24 апреля 2026 года данные взаимодействий Copilot (prompts, ответы, сниппеты и контекст) начинают использоваться для обучения моделей по умолчанию, если пользователь явно не отключит это в настройках для тарифов Copilot Free/Pro/Pro+.
https://github.blog/news-insights/company-news/updates-to-github-copilot-interaction-data-usage-policy/

Как и водится в маленьких инди компаниях, даже сроки они не стали соблюдать, залепили раньше, нарушая сроки объявленого дедлайна. Сейчас 7 апреля и у меня уже стоит эта галочка.
Возможно уже и данные коллектят, кто знает, верить уже тяжело.

Кто-то может, конечно, возразить, что "галочка включена != сбор данных", но я не очень согласен с этим.
Галочка стоит, текст честно написан, значит так оно и есть.
Allow GitHub to collect and use my Inputs, Outputs, and associated context to train and improve AI models.


Кто еще боится в век AI утилит лишиться приватности или заставляют условия работы в компаниях, спешите снять галочку:
- Идите по ссылке на свой профиль https://github.com/settings/copilot/features
- Settings -> Copilot -> Features -> Privacy -> Allow GitHub to use my data for AI model training,
9
#opensource #alertmanager #devops

Новости opensource мира.

У продукта Alertmanager есть неприятная недоработка.
Все уведомления в Slack он отправляет двумя сообщениями:
- проблема (firing)🔴
- проблема решена (resolved)🟢

Наверняка видели.

В мире шумных уведомлений даже этого много.
По сути 100 алертов порождают 200 сообщений (после их решения), что не очень удобно.
API самого Slack позволяет изменять сообщения, но алертменеджер не умел в это.

Это происходит прежде всего потому, что алертменеджер не хранит стейт алертов, чтобы "запоминать" куда слать обновление по алерту.

При этом аналоги умеют менять сообщение (меняя красный firing на зелёный resolved):
- grafana oncall / IRM
- pagerduty

С появлением GenAI инструментов я захотел исправить эту досадную оплошность, сделал форк алертменеджера, локально всё потестировал и примерно с полгода гонял у себя - работает идеально. (Март 2025)

Затем осмелился и запилил пулл реквест:
https://github.com/prometheus/alertmanager/pull/4682 (Ноябрь 2025)

Не скрою, пользовался GenAI, но основная идея была моя.
Я на 90% понимаю изменённый код и поведение.

После вялого обсуждения другие, более активные участники, реализовали это в два пулл реквеста:
- https://github.com/prometheus/alertmanager/pull/4899 (Январь 2026)
- https://github.com/prometheus/alertmanager/pull/5007 (Февраль 2026)

Само собой после этого мой PR не имеет смысла, я закрыл его. (Февраль 2026)

Вчера, 8 апреля 2026 выпущен новый релиз v0.32.0.
https://github.com/prometheus/alertmanager/releases/tag/v0.32.0

Теперь алертменеджер умеет хранить стейт алертов для слака и менять сообщения - что очень удобно. 🎉

Всех, кто использует алертменеджер, поздравляю.
Можете обновлять и радоваться меньшему количеству сообщений и меньшему шуму алертов.

---
Но вам же интересно глянуть, как это работает перед обновлением прода?

Нужен Bot Token Slack (xoxb-...) со скоупами chat:write и chat:update.
Важно: работает только с токеном, не с webhook URL.

Положить конфиг в /tmp/am-test/alertmanager.yml
global:
resolve_timeout: 1m

route:
receiver: slack
group_by: [alertname]
group_wait: 10s
group_interval: 10s
repeat_interval: 12h

receivers:
- name: slack
slack_configs:
- send_resolved: true
api_url: https://slack.com/api/chat.postMessage
http_config:
authorization:
credentials: xoxb-YOUR-BOT-TOKEN
channel: '#your-channel'
update_message: true # <-- вот эта опция
title: '{{ .GroupLabels.alertname }} - {{ .Status | toUpper }}'
text: |
{{ if eq .Status "firing" }}🔥 *{{ .Alerts.Firing | len }} alert(s) FIRING*{{ else }} *All alerts RESOLVED*{{ end }}

{{ range .Alerts }}• {{ if .Annotations.summary }}{{ .Annotations.summary }}{{ else }}{{ .Labels.alertname }}{{ end }}
{{ end }}
color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'


Запустить alertmanager v0.32.0 через Docker:
mkdir -p /tmp/am-test

docker run -d \
--name am-test \
-p 9093:9093 \
-v /tmp/am-test/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
-v /tmp/am-test/data:/alertmanager \
prom/alertmanager:v0.32.0


Стрельнуть алертом:
curl -X POST http://localhost:9093/api/v2/alerts \
-H 'Content-Type: application/json' \
-d '[{
"labels": {"alertname": "TestAlert", "severity": "warning"},
"annotations": {"summary": "This is a test alert - will resolve in the same message"}
}]'


Подождать ~10–15 секунд - в Slack появится сообщение с 🔴.

Зарезолвить:
curl -X POST http://localhost:9093/api/v2/alerts \
-H 'Content-Type: application/json' \
-d '[{
"labels": {"alertname": "TestAlert", "severity": "warning"},
"annotations": {"summary": "This is a test alert - will resolve in the same message"},
"endsAt": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}]'


Подождать ~10 секунд - то же самое сообщение изменится на 🟢.
Нового сообщения не будет!

Поздравляю всех с таким мелким, но приятным обновлением.
🔥462
#devops #ai #mcp #skills #troubleshooting

MCP, скиллы, ИИ, *уи.


Последние месяцы отказываюсь от MCP серверов.
Прям вот по минимуму оставляю и только от безысходности.
Slack, Linear, Jira, Grafana, VM (Victoria metrics), VL (victoria logs) и так далее.
Им замены мало, без них сложно.

Все MCP для Kubernetes, GitHub, GitLab - все это очень плохо работает в боевых условиях.

Распишу основные минусы из моего опыта:

- трата токенов
Вопреки описанию "да просто мсп сервер ничего не жрет в фоне", это лукавство.
Жрет токены и это видно по логу и трате их по обычным запросам.
Постоянно включать/выключать их я пробовал, но это банально неудобно даже если повесить скиллы/алиасы на это.

- они навайбкожены
Давайте быть честными - больше половины этих серверов это вайбкод вайбкода и работает он ровно так же.
Никаких гарантий, что ИИ агент идет четко по REST API/gRPC, из моей практики они просто хаотично по всем ендпойнтам лезут в надежде найти ответ на вопрос/задачу.

- функционал обрезан. Самый главный и основной минус.
Очень часто натыкался на то, что CLI утилита продукта имеет 99.9% функционала UI, а MCP от силы 60-70% по моим наблюдениям и оценке.
Пример на скриншоте.
Контекст скриншота: обучаю скилл/агента трабшутить упавшие пайплайны гитлаба, и mcp тут не подходит, он даже не может смотреть лог джобы, лол. 😬 Пришлось переписать на glab cli.

- происхождение сомнительное
Большинство MCP‑реализаций сейчас - сторонние, не от официальных вендоров, и часто не строго следуют контракту API или gRPC.
Я пробовал делать "доверительные списки", даже обращался к https://archestra.ai/mcp-catalog, но результат все равно для меня сомнительный.

Мне этого хватило, чтобы со временем отключить почти все MCP сервера там, где есть альтернатива - CLI tool + Skills.
Тут нет речи о том, что MCP - говно.
Тут речь лишь о том, что если есть CLI tool, то MCP не нужен.

Есть glab + TOKEN? MCP GitLab не нужен.
Есть gh + TOKEN? MCP GitHub не нужен.
Есть kubectl + auth? MCP Kubernetes не нужен.
И так далее.

Из плюсов подхода Skills +CLI tool:
- трата меньше токенов
- больший функционал, чем у MCP

Я пробовал заменить MCP VM/VL на "cURL + Skills", это работает и работает отлично, но трата токенов выше примерно на 18-22% по моим графикам и данным. Нерационально, поэтому оставил MCP MV/VL.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍143
#ai #devops

Совершенно ожидаемо и неожиданно одновременно Nvidia выпустила бесплатные эндпойнты к популярным LLM моделям.
https://build.nvidia.com/models?filters=nimType%3Anim_type_preview&orderBy=weightPopular%3ADESC

А давайте-ка глянем, так ли оно.

- прошел регистрацию (мой gmail аккаунт)
- прошел верификацию (номер телефона НЕ РФ, другие страны не проверял само собой)
- выбрал рандомную модель
https://build.nvidia.com/moonshotai/kimi-k2-instruct
- нажал view code
- нажал в окошке generate API key
- скопировал код к себе локально в файл 1.py , добавил context простой вопрос про хокку
from openai import OpenAI

client = OpenAI(
base_url = "https://integrate.api.nvidia.com/v1",
api_key = "nvapi-m3_bqO98rY-а-зачем-вам-мой-токен-BAMIGI-tLbz3VQ20MpwyTbU-"
)

completion = client.chat.completions.create(
model="moonshotai/kimi-k2-instruct",
messages=[{"role":"user","content":"Write a haiku about infrastructure as code."}],
temperature=0.6,
top_p=0.9,
max_tokens=4096,
stream=True
)

for chunk in completion:
if not getattr(chunk, "choices", None):
continue
if chunk.choices and chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")

- установил пакет опенаи (если нет)
pip3 install openai

- сохранил код и запустил его
python3 1.py

Lines of code define
bridges spun from pure intent—
infrastructure breathes.


Работает! 🎉

Забирайте себе и тренируйтесь с разными моделями бесплатно. ❤️

- - -
Update для самых быстрых и невнимательных.

Не забывайте, что там:
"Privacy. Your input and output will be recorded to provide you with this trial experience and to improve NVIDIA products and services, including AI models, in accordance with our Privacy Policy.
Do not upload any confidential information or personal data unless expressly permitted. Your use is logged for security, fraud or abuse monitoring and shared with third party service providers for this purpose. If the demo necessarily requires the input of personal data, logging for product development purposes will be turned off."
8
#terraform #AWS #IaC #devops

Все мы живём в привычках.
Как однажды научили - так и делаем, словно котики, повторяющие одно и то же всю жизнь.

Учили поднимать руку, чтобы постучать в дверь.
А можно стучать кистью, не поднимая руку.
Мелочь, но никто не задумывается, потому что "так делается".

Когда у нас с супругой появилась посудомоечная машина, я внимательно читал инструкции - и от самой техники, и от капсул.
Тогда были капсулы со специальным покрытием, которое нужно было срывать перед загрузкой.
Потом она купила новые капсулы с плёнкой, которая растворяется от воды сама, и положила их в старую коробку - удобная была.
Я об этом не знал.
И каждый раз, словно дурачок, аккуратно срывал плёнку перед загрузкой.
Ну скажем сильно больше одного дня я так делал) Сильно больше)
Ведь меня так научили. Да и коробка - та же самая.

Вот так и в нашем айти.

Когда меня учили Terraform и в проекте были накликанные руками ресурсы, объясняли процесс примерно так: пишешь код ресурса, потом идёшь на registry.terraform.io, находишь нужный ресурс, листаешь вниз до секции Import - там написано в каком формате передавать ID (у каждого ресурса свой синтаксис, угадай с первого раза).
Потом идёшь в AWS консоль за нужным ARN или именем ресурса. Возвращаешься, запускаешь команду:
terraform import aws_iam_role.eks_node_role eks-node-role-production

Делаешь план, убираешь дрифт. Следующий ресурс - снова на сайт, снова читаешь синтаксис, снова в консоль за ARN:
terraform import aws_iam_role_policy_attachment.eks_worker_node_policy \
eks-node-role-production/arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy

И так для каждого накликанного ресурса, по одному.

Ну я как обезьянка и повторял.
IAM роль? terraform import.
Политика? terraform import.
Node group? terraform import.
Пять ресурсов - пять итераций, пять заходов на сайт.

Оказывается, с Terraform 1.5 (лето 2023, и да, я снова не знал 🚬) есть блок import прямо в коде.
Без отдельных команд.
Без итераций.
Без "а я точно не забыл что-то запустить".
import {
to = aws_iam_role.eks_node_role
id = "eks-node-role-production"
}
resource "aws_iam_role" "eks_node_role" {
name = "eks-node-role-production"
...
}

import {
to = aws_iam_role_policy_attachment.eks_worker_node_policy
id = "eks-node-role-production/arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}
resource "aws_iam_role_policy_attachment" "eks_worker_node_policy" {
role = aws_iam_role.eks_node_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}


Запускаешь обычный terraform apply - он сам всё импортирует.
Это в коде, видно в PR, и при потере стейта не нужно вспоминать, что и как импортировать.
Документация прямо внутри конфига.

Import block не избавляет от необходимости знать ID формат, он просто убирает CLI-танцы.
Важно: import block выполняется только если ресурса нет в state.
После успешного импорта его можно удалить - он больше не нужен.

А если совсем не хочется писать конфиг руками - можно ещё и сгенерировать его через
terraform plan -generate-config-out=generated.tf


Так и живём.
Срываем саморастворяющуюся плёнку с капсул, хотя давно этого делать не нужно.
Please open Telegram to view this post
VIEW IN TELEGRAM
18🫡4👍2👏2
#devops #linux #security

Только-только отгремели два LPE
- https://copy.fail/
- https://github.com/V4bel/dirtyfrag

Не успели донести ещё до продакшна изменения-фиксы, так уже третья проблема прилетела.
- https://github.com/v12-security/pocs/tree/main/fragnesia

Какой ад, если честно 🤦‍♂️🤦‍♂️🤦‍♂️

Чот всё как-то проклято с этими LPE.
Ведь точно не последняя будет с такой-то волной интереса и доступностью AI агентов и ассистентов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
#kubernetes #kubelet #devops #observability

Я, конечно, понимаю, что сейчас все вокруг ИИ агент-нейтив супер синёры и все всё знают, так что заметка для обычных инженеров, которые ещё чего-то не знают.

Свежая статья от LearnKube про то, откуда на самом деле берутся метрики в Kubernetes
- https://learnkube.com/kubernetes-metrics-cadvisor-kubelet-cri 🔥🔥🔥

По мне так прям годная разборка пайплайна метрик кубера: kubelet > cAdvisor > CRI.
Не маркетинговая жыжа инфоцыган, а прям пошагово на minikube с containerd, с командами, выводами, /sys/fs/cgroup/ наизнанку.

О чём в двух словах:
- как кублет на старте решает, cgroup v1 или v2 у ноды, и какой cgroup driver брать (systemd vs cgroupfs)
- как QoS класс пода (Guaranteed/Burstable/BestEffort) определяет, в какой слайс он улетит. С трейсом от UID пода в API до .scope юнита на диске
- что такое пауз-контейнер и почему у тебя у каждого пода два скоуп юнита, даже если контейнер один
- четыре эндпоинта кублета и чем они отличаются, типа:
- - /metrics/cadvisor - контейнерные метрики в прометей формате от cAdvisor
- - /stats/summary - JSON по нодам/подам/контейнерам/волюмам
- - /metrics/resource - лёгкие cpu/memory, на это сейчас смотрит metrics-server 0.6+
- - /metrics - внутренняя кухня самого кублета (kubelet_runtime_operations_duration_seconds и тд)
- зачем ваще сделали фичу PodAndContainerStatsFromCRI - чтобы кублет тащил статы пода/контейнера прямо из рантайма через gRPC, а не гонял cAdvisor по cgroup-фс второй раз
- что произойдёт с твоим /metrics/cadvisor если её включить (спойлер: пздц контейнерные метрики оттуда исчезнут, останется только machine-level)
- про KubeletCgroupDriverFromCRI (я честно скипнул, пипец нудятина про рантайм драйвера)

Кому полезно:
- SRE/DevOps/SysAdmin, кто прометиусом/викторииметрикс скрейпит /metrics/cadvisor и думает, что всё ок навсегда. Включат гейт, обнаружат пропавшие метрики и сюрприз-сюрприз 😬
- тем, кто сидит на кластерах с cgroup v1 - пора планировать миграцию, иначе 1.35 встретите со сломанным кублетом
- тем, кто хоть раз получал баг репорт "у нас метрик нет на /metrics/cadvisor" и не понимал откуда они вообще должны прилетать
- начинающим, кто хочет понять физику процессов, а не "ну вот стоит прометеус и метрики откуда-то есть"
- шизикам-любителям полазить по /sys/fs/cgroup/kubepods.slice/, потому что половина статьи это именно ssh + ls -la 😀

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

Никакого AI, сорян, чисто инженерный документ для инженеров про кубы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3212🫡2
#troubleshooting #terragrunt #devops #всратость

Очередная всратая история про Tailscale.

Была задача: заменить один легаси Tailscale узел нормальной HA парой.
Два EC2 в Auto Scaling Group, два AZ, автоматическая ротация auth-key через Lambda + Vault.
Красиво, надёжно, как в книжках и доке написано.

Задеплоили, новые ноды поднялись, анонсируют маршруты, всё выглядит отлично.
Убрали легаси (просто потушили).

Через некоторое время в слаке:
- "а почему внутренний адрес ArgoCD отдаёт 403? э!"

Начинаем смотреть чо там: ДНС не резолвит внутренние имена, весь туннель работает, TCP через /16 ходит нормально, но стоит обратиться по FQDN к любому внутреннему сервису - тишина.
dig +short internal-service.company.example.com
;; connection timed out; no servers could be reached

Ну окей, DNS сломался, а почему.

В AWS VPC есть такая штука - AmazonProvidedDNS. Это встроенный резолвер, который живёт по адресу <CIDR_VPC_BASE>+2.
Если мой VPC это 10.72.0.0/20, то резолвер сидит на 10.72.0.2.
Через него работает сплит-днс: внутренние имена идут в приватные Route53 зоны, всё остальное - наружу.

Чтобы это работало через Tailscale-туннель, клиенты должны уметь достучаться до 10.72.0.2.

Легаси-нода анонсировала два маршрута: 10.72.0.0/16 (широкая подсеть) и 10.72.0.2/32 (конкретно этот адрес резолвера).
Новые ноды анонсировали только один маршрут 10.72.0.0/16.

Как оказалось (спасибо нейронкам, документации и коллегам) tailscale работает по принципу Longest Prefix Match (LPM): при выборе маршрута побеждает самый специфичный:
- запрос к 10.72.0.2 шёл через легаси, потому что у неё был /32 - он длиннее /16.
А потом легаси потушили. И tailscale не переключился на /16 новых нод.

Это не баг, кстати, а документированное поведение, написанное прямо в KB-1019:
"Tailscale does not fall back to a less-specific route when the subnet router for a more-specific route goes offline.
Tailscale drops traffic to 10.0.0.1 rather than falling back to subnet router A's 10.0.0.0/16 route."

Я, конечно, как и коллеги, прочитали это уже после. Ну всё как обычно.

Для работы HA failover у tailscale вообще требуется, чтобы обе ноды анонсировали идентичные префиксы - широкий /16 не является фолбэком для /32 - это просто другой маршрут.

Итого: DNS-резолвер 10.72.0.2 видел только легаси через /32, новые ноды с 10.72.0.0/16 для tailscale были вообще не кандидатами на трафик к этому конкретному адресу. Убрали легаси - адрес пропал из таблицы маршрутов. DNS умер и всё, издец.

TCP до других адресов в 10.72/16 работало нормально - там /32-специфики не было, оба маршрута от новых нод были равнозначными, failover сработал.

Фикс простой: каждая нода должна явно анонсировать <VPC_CIDR_BASE>+2/32.

В terra модуле добавили вычисление адреса резолвера через cidrhost(var.vpc_cidr, 2) и автоматически подклеиваем его как /32 к списку advertised_routes.
Плюс в tailscale ACL нужна отдельная запись в autoApprovers.routes под этот /32 - общий /16 его не покрывает, там тоже exact match 😬.

locals {
vpc_dns_resolver = cidrhost(var.vpc_cidr, 2)
advertised_routes = distinct(
concat(var.advertised_routes, ["${local.vpc_dns_resolver}/32"])
)
}


Теперь при любой замене ноды все HA-пиры анонсируют и /16, и /32 резолвера - файловер работает корректно, ДНС не падает.

Мораль тут банальная, но всё равно немного обидная: читай документацию до деплоя, а не после инцидента.

Мы предполагали, что Tailscale при отсутствии /32 анонсера переключится на покрывающий /16.
Вроде логично же - подсеть включает адрес, значит маршрут есть, но у tailscale другая логика: /32 и /16 - это разные маршруты, не уточнение одного другим, фоллбек намеренно не делается, потому что иначе можно случайно отправить трафик не туда.

Один 32-битный префикс, пропущенный при проектировании нового модуля - и несколько часов дебага всей командой*.

* я только коммиты смотрел, читал доки тейлскейла, AWS по VPC и слушал на митосе как ребята траблшутят.

- - -
В следующий раз, когда мне захочется поныть про "тупые" вопросы о сетях и подсетях на собесе, просто вспомню, как один /32 положил нам DNS 😬
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍8🤡1