Happy Devops — сообщество адекватных инженеров
СтатистикаСообщество адекватных инженеров | Все про DevOps и эксплуатацию. Культура, инструменты, подходы и решения Живо общаемся (чат): https://t.me/+eNGNnbY_2mVkZTEy По всем вопросам в бота: @HDFeedBackBot Web: https://happydevops.ru
- Последний пост
- 28 нояб.
- Последнее чтение
- 00:20
- Постов за неделю
- 0
- Всего постов
- 20
- Тип
- открытый
- Язык
- русский
- В каталоге с
- 16 авг.
- 1/24сутки в ленте
- —
- 1/48двое суток
- —
- 1/72трое суток
- —
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
⚡ Совместный карьерный митап от Звук и self, сообщества для поддержки айтишников. Как строить карьеру в турбулентные времена и экономический кризис 📌 Время и место 🔴30 ноября, с 15:00 до 21:00 🔴Poklonka Place, корпус Е1 Поклонная ул. 3 📌 Можно подробнее? Можно! Митап состоит из четырех частей: 1️⃣Серафима Чекулаева, Руководитель продуктов, ex-VK Музыка, Тинькофф, Яндекс; CEO self и карьерный ментор, расскажет, как выжить на рынке труда, который не беспокоит ваше выживание 💰 2️⃣Дальше – Карьерный форум с 12 экспертами из разных IT-направлений: teamlead, frontend, backend, ML&analytics, product При покупке билета в боте задай свой вопрос, выбери ментора среди экспертов и получи совет о том, что сейчас реально работает✨ 3️⃣ Будет организованный нетворкинг с другими участниками, можно будет обсудить текущую карьерную ситуацию и поделиться лайфхаками. Знакомства получатся без неловкости – ребята уже придумали за вас, как начать диалог💛 4️⃣А финальный диджей-сет от Звука поможет выдохнуть после насыщенного инсайтами дня под расслабляющий бит🎵 Честное слово, ивент будет эпохальный, сильно расстроитесь, если пропустите! И ребята тоже расстроятся, если вас не увидят, так что скорее залетайте и регайтесь!
🔥 База знаний тимлида: как въехать в процессы быстро и безболезненно! Подкаст Виктор Корейша и Андрея Синицыны. Секция: Hype Кому будет полезно: ➖Тимлидам, которые недавно вошли в новую команду или готовятся к переходу ➖ Инженерам, у которых всё держится в голове и пора с этим что-то делать ➖ Всем, кто хочет структурировать знания о людях и технологиях, не теряя в темпе ✅ О чем? Как собирать и систематизировать знания в удобных инструментах (например, Obsidian), чтобы понимать, как всё работает — от кода до коммуникаций. ⬇ Что вас ждет? ➖ Рекомендации по ведению личной базы знаний ➖ Как фиксировать не только техпроцессы, но и “социальную архитектуру” команды ➖ Инструменты и лайфхаки для заметок, которые реально работают ➖ Обсуждение Obsidian и подходов к организации данных 👀 Кто спикеры? Виктор Корейша — Руководитель направления Managed Services в Ozon. Андрей Синицын — адепт blameless culture, руководитель платформенного отдела в Ozon. Профи в эксплуатации, поклонник SRE и автор телеграм-канала HappyDevops. PRO IT Fest V 5–6 июля Санкт-Петербург, пр. Медиков, 3, корп. 5 Конгресс-центр «Ленполиграфмаш» Билеты Telegram-бот в котором можно получить скидку до -20%
Дорогие друзья, уже на следующей неделе, 23 апреля в Амфитеатре Санкт-Петербургского конгресс-центра Ленполиграфмаш состоится очередной [ Big Monitoring Meetup ] 12! Программа посвящена мониторингу и включает доклады по тематикам разработки, связи, менеджменту. BMM - площадка, где встречаются профессионалы и энтузиасты отрасли, чтобы обсудить современные тренды, обменяться опытом и найти новые решения для актуальных задач. Нетворкинг, дружеская атмосфера, способствующая открытому общению и обмену знаниями. Одной из главных ценностей нашей конференции является возможность установить прямой контакт между разработчиками и пользователями. Встречайте докладчиков двенадцатой конференции: Презентация "3D визуализация в мониторинге: модный тренд или рабочий инструмент?" — Андрей Никифоров. Генеральный директор [ ООО «ТРИТВИН» ] Дискаверинг и мониторинг сетевого оборудования в системе мониторинга Saymon, часть вторая. — Дмитрий Хандыго. Начальник отдела программных решений [ Inline Technologies ] Мониторинга много не бывает. Или бывает? А наследованного и самописного? — Михаил Еграмин. Главный инженер [ ООО «Сети ВЕБА» ] Мониторинг не ограничен потреблением. Как FinOps помогает не упустить контроль над инфраструктурой. — Гуляев Андрей. Руководитель развития продукта [ Инферит Клаудмастер ] Облачная система мониторинга радиовещания. — Александр Орлов. Менеджер [ ООО "Тракт-Софт" ] Мониторинг — это просто. — Вадим Исаканов. Старший инженер [ Платформа контейнеризации «Боцман» ] Если инциденты случаются - значит это кому-нибудь нужно? — Вероника Шапиро. Руководитель направления инфраструктурного мониторинга [ CLOUD.ru ] Не упустите шанс стать частью профессионального сообщества, получить новые знания и вдохновение для развития своих проектов! ✔️ Зарегистрируйтесь сейчас, количество билетов ограничено Подпишитесь на наш ТГ канал или ВК сообщество, чтоб не пропустить важные новости До встречи на конференции [ Big Monitoring Meetup ] 12!
Eventual Consistency: когда доступность важнее мгновенной согласованности Eventual consistency — модель согласованности, ставшая фундаментом современных распределённых систем. Ключевая идея проста: система гарантирует, что при отсутствии новых обновлений все реплики со временем придут к согласованному состоянию. В отличие от strong consistency, модель работает асинхронно. Узел может подтвердить запись до синхронизации с остальными репликами. Изменения распространяются по системе постепенно, создавая окно времени, когда разные клиенты могут видеть разные версии данных. Техническая реализация включает векторные часы, конфликт-резолверы и gossiping-протоколы для эффективного распространения изменений. Решение конфликтов обычно строится на принципе "последняя запись побеждает" или через более сложные механизмы слияния. Яркий пример — DNS-система. Когда меняется запись, обновления распространяются по DNS-серверам не мгновенно. Кто-то может видеть новый IP, кто-то — старый, но в течение TTL все системы синхронизируются. Другие примеры — CDN, социальные сети, большинство NoSQL баз. Преимущества очевидны: высокая доступность, низкая латентность, отличная устойчивость к сетевым разделениям. Система продолжает работать даже при потере связи между датацентрами. Кластеры легко масштабируются географически, поддерживая локальную запись с отложенной репликацией. Обратная сторона — борьба с аномалиями согласованности. Разработчикам приходится заранее продумывать, как система будет реагировать на конфликты данных, внедрять идемпотентные операции и проектировать UI с учётом возможных несоответствий. Выбор между eventual и strong consistency — всегда компромисс между доступностью и мгновенной согласованностью, между скоростью и надёжностью. Если ваше приложение может корректно функционировать без строгой синхронизации всех реплик — eventual consistency даст значительный прирост в производительности и отказоустойчивости. 🏴☠️ @happy_devops
Гонка за новым функционалом не должна превращать систему в «хрупкого гиганта». SRE-практики помогают определить «точку невозврата» и выстроить процессы поддержки SLA. Если вы хотите научиться проектировать устойчивые системы и оберегать их от неожиданных падений, секция «Reliability Engineering» будет для вас незаменима. Вторая часть докладов секции ⤵️, первая здесь 1) Blameless culture. Как правильно работать с инцидентами. Андрей Синицын (Ozon) Принцип старой школы: «у любой проблемы есть имя и фамилия». Слышали? Может, сами практикуете или бывали такими именем и фамилией? Из доклада вы узнаете, почему культура без обвинений более эффективна, почему это не про всепрощение и расслабон и как запустить такой подход у себя. 2) Как жить, когда у тебя N тысяч алертов в секунду. Кирилл Борисов (VK) Доклад про цикл жизни систем алертинга — от самого зарождения, когда только нащупываются подходы, до уже зрелой системы со своим собственным флоу. 3) Непрерывность как вид искусства. И почему доступности в 3,5 девятки вам достаточно. Глеб Тильтиков (МТС Диджитал) Глеб расскажет о реальном применении SRE-практик, на личном примере рассмотрит оправданное добавление ещё одной девятки и когда от заботы о «pets» нужно переходить к «cattle». 🖐️ Ждём вас 7 и 8 апреля в Москве на DevOpsConf 2025. ✅ Программа конференции и билеты на сайте
Strong Consistency: между производительностью и надежностью данных Strong consistency — ключевой принцип в распределенных системах, гарантирующий, что все узлы видят одинаковые данные в любой момент времени. При любом обновлении изменения мгновенно становятся видимыми для всех последующих операций чтения. Технически это достигается через линеаризуемость операций — все действия должны выполняться атомарно и по сути выстраиваться в единую временную линию. Синхронная репликация и двухфазный коммит гарантируют, что любое изменение будет применено ко всем репликам до того, как клиент получит подтверждение. Жизненный пример — банковские транзакции. Когда система переводит деньги между счетами, критически важно, чтобы все узлы системы видели актуальное состояние баланса. Рассинхронизация даже на секунду может привести к дублированию списаний или потере транзакций. На практике реализация strong consistency требует серьезных компромиссов. Задержки на синхронизацию увеличивают латентность, а при сетевых сбоях система может временно перестать принимать запросы на запись — цена за гарантию целостности данных. Альтернативы вроде eventual consistency предлагают лучшую производительность и доступность, жертвуя строгими гарантиями согласованности. Выбор между ними определяется теоремой CAP: нельзя одновременно обеспечить консистентность, доступность и устойчивость к разделению сети. К сожалению, универсального решения не существует. Критичные финансовые и медицинские системы выбирают strong consistency. Социальные сети и стриминговые сервисы предпочитают eventual consistency. Все зависит от требований конкретного проекта и цены потенциальной ошибки. 🏴☠️ @happy_devops
Друзья, я опять с вакансией Мне нужен руководитель команды Operations. Не, даже не так. Мне нужен охереть какой крутой лид в команду опсов. Я отдаю себе отчет, что человека, которого я ищу, на свободном рынке просто нет, такие люди не выходят в поиск, они меняют работу за полчаса, просто списавшись со знакомыми руководителями Но вдруг, вдруг... Вдруг кто-то из них читает мой канал и ищет работу, я верю в удачу, мазафака! Я — ваш знакомый руководитель, спишитесь со мной, а? 🥹 Итак, нужно возглавить команду очень крутых сеньоров-админов. Это не девопсы, это, скорее, ближе к SRE, прям очень ближе. Парни — огонь! Правда очень и очень крутые Тому, кто таки захочет за это взяться, обязательно нужна хорошая экспертиза в linux, сетях, высоконагруженных системах, хороший технический кругозор. В идеале, нужна хорошая экспертиза по kafka, etcd и vault. Но это в идеале. Если у вас такой нет, но вы понимаете, что такое bigtech, реальный хайлоад и сложные процессы, то приходите Я ищу в большей степени техлида. Мне нужен человек с экспертизой и со своим мнением, который сможет его обосновать и защитить, если понадобится. Менеджерских задач также будет некоторое количество, бэклогом, стратегией и командой все-таки тоже надо управлять. Для понимания немного сухих фактов: 🔘 У нас самый большой и нагруженный сетап кафки в РФ и один из самых больших в мире 🔘В пиках в высокий сезон мы видели цифры в 17М (семнадцать миллионов) сообщений в кафке в секунду. Кафка выдержала. Надо научить ее держать в два раза больше. 🟡Несколько раз в год мы отключаем один из ЦОДов на живом трафике и все должно работать как и работало. Мы настолько верим в себя, что можем позволить себе такие учения. 🔘Мы — платформенная команда и наши клиенты — это продуктовые разработчики и другие платформенные команды, это очень дотошные и требовательные заказчики 🔘Мы сами придумываем себе задачи и строим стратегию развития и делаем это хорошо 🟢У нас форкнутые версии волта, кафки и etcd, мы дописываем их сами. Ванильные уже не выживают на наших нагрузках 🟣В нашем проде более 5 000 микросервисов и больше 200 технических команд. Они все очень много используют наши сервисы Немного про нашу команду я писал вот в этом посте. Лида команды разработки я успешно нашел, спасибо, что спросили😊 Вакансия на Ozon.Job: https://job.ozon.ru/vacancy/rukovoditel-gruppi-operations-message-bus-paas-112995867/ Еще раз повторюсь: это прям челлендж-челлендж. Работы много, работа сложная, работа ответственная. Мне не подойдут вонаби-менеджеры, которые умеют хорошо говорить, но которые не делали ничего руками и не в состоянии пройти интервью по system design. Мне не подойдут люди, которые годик управляли маленькой командой в маленьком стартапе, у нас реально "большая вода", они просто не вывезут. Мне не подойдут люди, которые про хайлоад слышали только на "Хайлоаде". Только ветераны войн за аптайм, с горячим сердцем и холодной головой. Если чувствуете в себе силы пособеседоваться, то пишите мне на asinitsyns@ozon.ru Ну или перешлите вакансию знакомому лиду 〰️〰️〰️〰️〰️〰️〰️ 🗞 @boombah_in_da_house
Есть работа! Друзья, я ищу в одну из своих команд крутого тимлида, который возглавит команду разработки. Мы строим инфраструктуру для секретов (на базе Hashicorp Vault) и конфигураций (на базе etcd). Очень высоконагруженную инфраструктуру, все решения, про которые вы слышали, на наших нагрузках уже не работают и надо придумывать что-то новое. Сразу скажу, что работы очень много и это не продуктовая разработка. Наши заказчики — мы сами и это дополнительный челлендж: мы должны придумать и внедрить решения раньше, чем сервисам Озона станет плохо под нагрузками, это на 100% проактивная история, где нужно инженерное видение и готовность делать то, что раньше никто и никогда не делал. Рутина? Ну камон, ее нет как факта, каждый день — это новый вызов. Маркетплейс, инфраструктура ПВЗ, банк, тревел, фреш и еще куча всего — они все живут на нашей платформе Это high-severity сервисы, наш etcd предоставляет конфигурации для более чем 5000 микросервисов и failure is not an option, мы не можем позволить себе валяться, будет очень больно Мы форкнули Vault, потому что ванильный уже не подходит. Мы форкнули один из кусочков etcd и готовимся форкнуть его весь, потому что на наших нагрузках и требованиях ванильный не справляется. Мы разрабатываем свой etcd-operator для k8s, который позволит крутить etcd на огромном федеративном кластере Kubernetes, в нескольких ЦОДах и с сотнями тысяч деплойментов. Мы пишем низкоуровневые плагины для k8s на уровне common interfaces, чтобы обеспечить отказоустойчивость наших решений. Мы растем кратно год от года и то, что сработало в high-season в прошлом году, в следующем уже будет дремучим легаси Я гарантирую максимально интересные задачи, работу плечом к плечу с лучшими из индустрии и гордость за результат своего труда. Мы делаем очень много и про результаты мы рассказываем на конференциях, пишем статьи и контрибьютим в опенсорс. Если вы хотите принимать участие в публичной активности, то мы поможем подготовить доклады и выступить. Ребята из наших команд входят в программные комитеты многих конференций. Каждый месяц мы дарим топовый ноутбук за лучшую статью, у некоторых из ребят он уже не один Если вы давно хотели поработать со мной, то вот отличный шанс. Приходите сами или перешлите вакансию знакомому лиду😊 Почитать подробное описание и откликнуться можно на сайте Озона или через меня. Готов ответить на любые ваши вопросы (кроме тех, которые под NDA🙃) 〰️〰️〰️〰️〰️〰️〰️ 🗞 @boombah_in_da_house
Observability — это не просто модное слово. Вот реальный пример: платежный сервис внезапно стал отдавать 500-ки. Без правильно настроенной системы наблюдения придется потратить часы на поиск причины. RED метрики (Rate, Errors, Duration) в Prometheus сразу покажут масштаб бедствия: какой процент запросов падает, как растет латенси, сколько пользователей под ударом. Базовый дашборд в Grafana для каждого сервиса — три панели с RED метриками и алерты при отклонении от нормы. Distributed tracing через Jaeger раскроет полную картину. Один платёжный запрос проходит через auth-сервис (50мс), потом биллинг (200мс), и где-то между ними теряется. Раньше такой дебаг занимал часы, с трейсами — минуты. Structured logging решает проблему поиска. JSON-логи с метаданными в Loki позволяют мгновенно найти все события по конкретному requestId или userId. Один запрос в LogQL: {job="payment-service"} |= "error" | json | user_id=123456 — и вот она, причина сбоя. А теперь про SLO — тут начинается самое интересное. Типичная ошибка — взять с потолка цифры типа "99.9% успешных запросов". Звучит красиво, но это путь в никуда. SLO должны отражать реальный пользовательский опыт. Если юзер не заметит падения успешности до 95% — зачем держать планку на 99.9%? Ещё один подводный камень — измерение не тех метрик. Классика жанра: латенси базы данных 99.999%, а пользователи жалуются на тормоза. Оказывается, замеряли только время выполнения запроса, забыв про очередь коннектов к БД. История из жизни: один сервис гордился своими SLO по доступности, пока не выяснилось, что health-check проверял только живость процесса, а не работоспособность бизнес-логики. Правильные SLO рождаются из боли. Сначала инциденты, потом анализ их влияния на бизнес, и только потом — осмысленные цифры. Метрики, логи и трейсы помогают превратить этот опыт в конкретные показатели. И да, их придется регулярно пересматривать — бизнес не стоит на месте. 🏴☠️ @happy_devops
Коллеги, праздники прошли и мы снова на связи! Команда HappyDevops поздравляет вас с Новым годом, мы желаем вам пять девяток в аптайме, замечательных задач, новых вызовов и отщывчивых систем! Учитесь, растите и развивайтесь. Мы традиционно начинаем новую неделю и наша тема — мониторинг! Мониторинг трансформируется? На смену старой доброй связке RRD и Nagios пришло понятие observability, и она перевернула представление о том, как отслеживать здоровье систем. За последние пять лет инфраструктура выросла из детских штанишек. Микросервисы, контейнеры, serverless — всё это сделало классический мониторинг бесполезным. Нет смысла просто проверять CPU, память и диск. В распределённых системах баги живут на стыках сервисов, а корень проблем прячется в недрах асинхронного взаимодействия. Observability строится на трёх китах: метрики, логи и трейсы. Метрики показывают общую картину, логи рассказывают что случилось, а трейсы объясняют почему. И если мониторинг отвечал на вопрос "что сломалось?", то observability даёт ответ на "почему это случилось?". SLO (Service Level Objectives) стали новой валютой надёжности. Вместо бинарного "работает/не работает" появились чёткие метрики успеха. 99.9% запросов должны выполняться быстрее 200мс? Отлично, настройка алертов и отслеживание трендов решают эту задачу. Никакой магии — только точные цифры и понятные цели. В современном мире недостаточно знать, что сервис упал. Критично предвидеть проблемы до того, как они затронут пользователей. Observability становится третьим глазом инженера, позволяя заглянуть в самое сердце системы. На этой неделе разговор пойдет о каждом аспекте observability. От базовой настройки Prometheus до продвинутых техник трейсинга в Jaeger. Материал будет глубоким и детальным — держите свои дашборды наготове. 🏴☠️ @happy_devops
IaC Week: уроки управления большой инфраструктурой Масштабные проекты в Terraform раскрывают истинную сложность управления инфраструктурой. Недостаточно просто писать код — нужна целая система практик и процессов. Опыт реальных проектов показывает несколько критических моментов. Первый — изоляция компонентов через отдельные state-файлы. База данных живет отдельно от сети, сеть — отдельно от вычислительных ресурсов. Это не только упрощает откат изменений, но и защищает от каскадных сбоев при обновлениях. Второй — строгая система версионирования. Каждый модуль получает свой тег по semver, каждое изменение проходит через пайплайн с тестами. State-файлы хранятся в Object Storage с версионированием и репликацией между регионами. Третий — автоматизация всех рутинных операций. План изменений формируется автоматически, проверяется линтером и security-сканером, а после ревью деплоится в production без ручных действий. Человеческий фактор исключен везде, где это возможно. В итоге все сводится к базовому принципу: инфраструктурный код должен быть таким же надежным и поддерживаемым, как прикладной. Только тогда можно говорить о настоящем Infrastructure as Code. 🏴☠️ @happy_devops
Best practices для масштабных проектов: принципы здоровой инфраструктуры Успешные инфраструктурные проекты строятся не на конкретных технологиях, а на фундаментальных принципах. Масштабные системы требуют особого внимания к деталям и проверенных практик, которые помогают держать сложность под контролем. Стабильность таких систем обеспечивается сочетанием архитектурных решений, процессов и инструментов. Структура проекта начинается с четкой организации кода. Монорепозиторий с модулями разделяется на слои по уровню абстракции, что упрощает навигацию и поддержку: infrastructure/ ├── modules/ # Переиспользуемые модули │ ├── network/ # Базовая сетевая инфраструктура │ ├── compute/ # Compute ресурсы │ └── storage/ # Хранилища данных ├── environments/ # Окружения │ ├── prod/ # Production │ └── stage/ # Staging └── platform/ # Платформенные сервисы ├── monitoring/ # Мониторинг └── security/ # Безопасность Каждый модуль проходит через строгий процесс тестирования. Unit-тесты проверяют корректность отдельных компонентов, интеграционные — взаимодействие между ними. Автоматизированные тесты запускаются при каждом изменении: module "test_network" { source = "../../modules/network" providers = { yandex = yandex.testing } environment = "test" subnets = { "a" = ["10.0.1.0/24"] "b" = ["10.0.2.0/24"] "c" = ["10.0.3.0/24"] } } resource "test_assertions" "network" { component = "network" check "subnets_created" { description = "Проверка создания подсетей" condition = length(module.test_network.subnet_ids) == 3 } check "network_connectivity" { description = "Проверка связности подсетей" condition = can(module.test_network.test_connectivity) } } Для крупных проектов критична система ограничений и политик. Terraform Sentinel защищает от нарушения корпоративных стандартов и автоматически блокирует небезопасные изменения: policy "enforce_mandatory_tags" { enforcement_level = "hard-mandatory" rule "check_tags" { source = "./rules/tags.sentinel" } } import "tfplan/v2" as tfplan mandatory_tags = ["project", "environment", "owner", "cost-center"] check_resource_tags = func(resource) { tags = resource.change.after.labels return all mandatory_tags as tag { tags contains tag } } Отдельный акцент делается на мониторинг и наблюдаемость. Каждое изменение инфраструктуры должно оставлять след в системе. Метрики, логи и алерты формируют полную картину состояния инфраструктуры: resource "yandex_monitoring_dashboard" "terraform" { name = "terraform-changes" chart { title = "Infrastructure Changes" metrics { name = "terraform.apply.success" aggregation = "COUNT" } metrics { name = "terraform.apply.failure" aggregation = "COUNT" } } alert { name = "High Rate of Failed Changes" condition = "rate(terraform.apply.failure[1h]) > 3" severity = "critical" } } 🏴☠️ @happy_devops
Автоматизация развертывания: Пайплайны Terraform без компромиссов Когда инфраструктурой занимается команда, ручной запуск terraform apply превращается в потенциальную катастрофу. Даже небольшая ошибка может привести к непредсказуемым последствиям, особенно в масштабных проектах. Полноценный CI/CD для инфраструктурного кода становится не просто удобством, а необходимостью. Автоматизация пайплайнов снижает риск человеческого фактора, ускоряет развертывание и обеспечивает прозрачность процессов. Структура базового пайплайна Типичный пайплайн для Terraform включает четыре ключевых этапа: 1. Линтинг — проверка стиля и выявление ошибок в коде. 2. Валидация — гарантирует, что конфигурация корректна и соответствует стандартам безопасности. 3. Планирование изменений — создаёт план, который можно проверить перед применением. 4. Применение — финальный этап, на котором изменения внедряются в инфраструктуру. Пример базового пайплайна на GitLab CI: variables: TF_ROOT: ${CI_PROJECT_DIR}/terraform TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state stages: - validate - plan - apply fmt: stage: validate script: - cd ${TF_ROOT} - terraform fmt -check -recursive - tflint --config=.tflint.hcl validate: stage: validate script: - cd ${TF_ROOT} - terraform init - terraform validate - checkov -d . --framework terraform Двухступенчатый процесс для безопасности Для минимизации рисков используется двухступенчатый процесс: 1. Планирование: план изменений публикуется в Merge Request для ревью. 2. Применение: изменения внедряются только после проверки и подтверждения. plan: stage: plan script: - cd ${TF_ROOT} - terraform plan -out=plan.tfplan artifacts: paths: - ${TF_ROOT}/plan.tfplan expire_in: 1 week apply: stage: apply script: - cd ${TF_ROOT} - terraform apply plan.tfplan dependencies: - plan rules: - if: $CI_COMMIT_BRANCH == "main" when: manual Защита секретов и управление доступом Безопасность — ключевой аспект. Секреты передаются через защищённые переменные CI/CD, а временные credentials с ограниченным сроком действия предотвращают компрометацию: before_script: - vault kv get -field=YC_TOKEN secret/terraform > token.json - export YC_TOKEN=$(cat token.json) - vault token revoke -self after_script: - rm -f token.json - unset YC_TOKEN Расширение пайплайна: от документации до тестирования Чтобы обеспечить максимальную надёжность, пайплайн можно дополнить: 🔘 Автоматической генерацией документации с помощью terraform-docs, чтобы новые разработчики быстрее понимали структуру. 🔘Проверкой security best practices через tfsec, что помогает выявить уязвимости ещё на этапе разработки. 🔘Постдеплойными тестами, например проверкой доступности сервисов или соответствия стандартам: tests: stage: test script: - cd ${TF_ROOT}/tests - go test -v ./... - inspec exec compliance -t yc:// dependencies: - apply rules: - if: $CI_COMMIT_BRANCH == "main" Идемпотентность как основа надёжности Одной из главных задач в автоматизации развертывания является идемпотентность: повторный запуск пайплайна на одном и том же коммите должен приводить к идентичному результату. Для этого важно правильно работать с артефактами и кэшировать необходимые данные. Автоматизация развертывания с помощью CI/CD для Terraform — это инвестиция в стабильность, безопасность и эффективность вашей инфраструктуры. Пайплайны, построенные по принципу идемпотентности и безопасности, помогают не только сократить время на рутинные задачи, но и минимизировать риски. 🏴☠️ @happy_devops
Управление состоянием в Terraform: разделяй и властвуй ⚡️ Состояние инфраструктуры в больших проектах становится узким местом при масштабировании команд и сервисов. Remote state решает проблемы с блокировками и конкурентным доступом, но требует продуманной структуры. Главный принцип — разделение state-файлов по четким границам ответственности. В основе грамотного управления состоянием лежит принцип разделения state-файлов по логическим границам. Каждый state-файл описывает независимый компонент инфраструктуры. Такой подход уменьшает риск конфликтов при параллельной работе нескольких команд: # network/main.tf terraform { backend "s3" { bucket = "terraform-states" key = "network/terraform.tfstate" endpoint = "storage.yandexcloud.net" } } # databases/main.tf terraform { backend "s3" { bucket = "terraform-states" key = "databases/terraform.tfstate" endpoint = "storage.yandexcloud.net" } } Для обмена данными между состояниями используется data source terraform_remote_state. Сетевые настройки из одного state становятся доступны другим компонентам. Это позволяет избежать жесткой связанности между модулями и упрощает поддержку кода: data "terraform_remote_state" "network" { backend = "s3" config = { bucket = "terraform-states" key = "network/terraform.tfstate" endpoint = "storage.yandexcloud.net" } } resource "yandex_mdb_postgresql_cluster" "postgres" { name = "prod-postgres" environment = "PRODUCTION" network_id = data.terraform_remote_state.network.outputs.network_id config { version = "15" resources { resource_preset_id = "s3-c2-m8" disk_size = 100 } } } При работе с секретами state-файл шифруется на уровне Object Storage через KMS. Ключ доступа выдается только членам инфраструктурной команды. Дополнительный уровень защиты обеспечивает audit log всех операций с state-файлом: terraform { backend "s3" { bucket = "terraform-states" key = "secrets/terraform.tfstate" endpoint = "storage.yandexcloud.net" kms_key_id = "abjhq8c9gct5pd5klm7p" access_key = var.storage_access_key secret_key = var.storage_secret_key } } Отдельное внимание стоит уделить резервному копированию state-файлов. Настройка репликации бакетов между регионами защищает от потери данных при отказе основного региона. А регулярные бэкапы позволяют восстановить состояние на любой момент времени. 🏴☠️ @happy_devops
Версионирование инфраструктуры: практики безопасных изменений 📦 Современная инфраструктура требует продуманного подхода к версионированию. Неконтролируемые изменения в Terraform приводят к простоям сервисов и потере данных. Правильно выстроенное версионирование позволяет избежать этих проблем. Базовый уровень версионирования — git-тэги для каждого модуля с семантическим версионированием. Мажорная версия растет при несовместимых изменениях, минорная — при добавлении фич, патч — при исправлении ошибок: module "web_cluster" { source = "git::https://github.com/company/tf-modules.git//web-cluster?ref=v2.3.1" cluster_name = "prod-web" instance_count = 5 zone_id = "Z2FDTNDATAQYW2" } История изменений state-файла хранится с помощью версионирования S3. По умолчанию Terraform сохраняет только последнюю версию, поэтому версионирование включается на уровне бакета с правилами очистки старых версий: resource "aws_s3_bucket" "terraform_state" { bucket = "company-terraform-state" versioning { enabled = true } lifecycle_rule { enabled = true noncurrent_version_expiration { days = 90 } abort_incomplete_multipart_upload_days = 7 } } Отдельные ветки для каждого окружения с изолированными pipeline'ами позволяют тестировать изменения безопасно. Новые версии модулей проходят проверку в staging перед деплоем в production. При обнаружении проблем revert коммита автоматически возвращает предыдущую версию через CI/CD. Критичные изменения требуют blue-green deployment. Новая инфраструктура разворачивается параллельно с действующей, трафик переключается постепенно. В случае проблем быстрый откат происходит через DNS: resource "aws_route53_record" "www" { zone_id = aws_route53_zone.primary.zone_id name = "www.example.com" type = "A" alias { name = var.environment == "blue" ? aws_lb.blue.dns_name : aws_lb.green.dns_name zone_id = var.environment == "blue" ? aws_lb.blue.zone_id : aws_lb.green.zone_id evaluate_target_health = true } } 🏴☠️ @happy_devops
IaC Week: Управляем инфраструктурным кодом как профессионалы Эта неделя посвящена полной перезагрузке подходов к Infrastructure as Code (IaC). Мы разберём, как эффективно версионировать инфраструктуру, управлять состоянием, автоматизировать развертывание и внедрять лучшие практики для масштабных проектов. А начнём с главного вызова — как держать Terraform под контролем, когда проект разрастается до гигантских масштабов. Когда инфраструктурный код выходит из-под контроля Крупные проекты неизбежно сталкиваются с проблемой масштабирования инфраструктурного кода. В одном из наших кейсов код вырос до 50 тысяч строк. Это быстро привело к проблемам: потере структуры, сложностям в управлении и росту риска ошибок. Решение пришло через переосмысление подходов к управлению инфраструктурой. Workspace'ы: отказ от копирования конфигураций Первым шагом стало использование workspace'ов для изоляции окружений. Вместо устаревшего копирования terraform.tfvars мы перенесли все переменные в код. Такой подход упрощает управление и снижает вероятность ошибок: workspace_config = { production = { instance_type = "t3.large" min_size = 3 max_size = 10 environment = "prod" backup_retention = 30 } staging = { instance_type = "t3.small" min_size = 1 max_size = 3 environment = "stage" backup_retention = 7 } } locals { config = workspace_config[terraform.workspace] } Теперь изменения для каждого окружения четко определены, а переключение между ними стало безопасным и простым. Надёжное хранение состояния Для хранения state-файлов мы выбрали S3 с включённым версионированием и блокировками через DynamoDB. Это предотвращает одновременное изменение state и защищает данные от случайных повреждений. Более того, мы добавили репликацию бакета в другой регион, чтобы обезопасить инфраструктуру даже в случае полного сбоя одного из регионов AWS: terraform { backend "s3" { bucket = "terraform-state-company" key = "infrastructure/terraform.tfstate" region = "eu-west-1" dynamodb_table = "terraform-locks" encrypt = true versioning = true replication_configuration { role = "arn:aws:iam::123456789012:role/service-role/s3-bucket-replication" rules { status = "Enabled" destination { bucket = "arn:aws:s3:::terraform-state-backup" region = "eu-central-1" } } } } } Этот подход обеспечил безопасность и восстановление инфраструктуры в любых непредвиденных обстоятельствах. Модули и автоматизация: простота в управлении Чтобы упорядочить код, мы приняли стратегию: "один сервис — один модуль". Все повторяющиеся компоненты вынесли в переиспользуемые модули. Это значительно упростило поддержку и добавление новых фич. Для автоматизации развертывания мы внедрили CI/CD pipeline: 🔘 Форматирование и линтинг: проверка стиля кода. 🔘 Проверка плана изменений: гарантируем, что никакие изменения не попадают в production случайно. 🔘 Документация: с помощью terraform-docs мы автоматически генерируем документацию, что помогает новым разработчикам быстро вникнуть в проект. Infrastructure as Code — это не просто способ автоматизации, это мощный инструмент управления инфраструктурой. Использование workspace'ов, надёжного хранения состояния, продуманной модульности и автоматизации делает инфраструктурный код масштабируемым, понятным и устойчивым. Эти практики не только упрощают текущую работу, но и создают прочный фундамент для будущего роста проектов. 🏴☠️ @happy_devops
Отказоустойчивость базы данных проверяется не в момент настройки репликации, а в момент аварии. И часто в самый неподходящий момент — посреди ночи или во время пиковой нагрузки. Поделюсь реальными историями и разбором полетов. Типичный сценарий: праздничная распродажа, нагрузка на пике, и тут primary-база падает. Автоматический failover звучит заманчиво, но реальность сложнее. В одном проекте автофейловер сработал при кратковременном сетевом сбое, поднял новый primary, а когда связь восстановилась — в системе оказалось два мастера. Итог: split-brain и потерянные транзакции. Теперь в критичных системах используем ручной failover с Patroni. Конфигурация выглядит так: scope: postgres-cluster namespace: /db/ name: postgres1 restapi: listen: 0.0.0.0:8008 connect_address: 10.0.0.1:8008 postgresql: listen: 0.0.0.0:5432 connect_address: 10.0.0.1:5432 data_dir: /data/postgres bin_dir: /usr/lib/postgresql/14/bin parameters: max_connections: 100 shared_buffers: 4GB wal_level: replica hot_standby: "on" Каскадная репликация помогает снизить нагрузку на primary. Вместо десяти реплик, висящих на мастере, строим дерево: пара реплик первого уровня раздает WAL остальным. В PostgreSQL это настраивается через primary_conninfo: -- На реплике первого уровня primary_conninfo = 'host=10.0.0.1 port=5432' -- На реплике второго уровня primary_conninfo = 'host=10.0.0.2 port=5432' Географически распределенные системы добавляют веселья. Латенция между дата-центрами может достигать сотен миллисекунд. Синхронная репликация в таких условиях убивает производительность. На практике работает схема с локальным кластером в каждом регионе и асинхронной репликацией между регионами. Мониторинг репликации — отдельное искусство. Следим за метриками через Prometheus: - job_name: 'postgres_exporter' static_configs: - targets: ['10.0.0.1:9187'] metrics_path: /metrics params: query: - 'pg_replication_lag' - 'pg_wal_activity' И обязательно тестируем failover. Регулярно. По графику. С записью времени переключения и подробным разбором каждого случая. Только так можно быть готовым к реальной аварии. Из последних кейсов: база на 12TB с репликацией между континентами. Переключение на другой континент занимало 40 минут. Ускорили до 5 минут через комбинацию логической и физической репликации: основные таблицы реплицировали физически, а небольшие справочники — логически. 🏴☠️ @happy_devops
Репликация данных — основа отказоустойчивости в современных системах. База данных без реплик похожа на сервер без бэкапов: всё работает отлично, пока не случится катастрофа. А потом становится поздно. Primary-Secondary архитектура — самый распространённый подход. Primary принимает все изменения и пересылает их на реплики. Secondary работают на чтение и готовы подхватить нагрузку при отказе мастера. Звучит просто, но дьявол в деталях. Синхронная репликация гарантирует, что данные попали на реплику до подтверждения записи. Транзакция не завершится, пока secondary не ответит "данные у меня". Надёжно, но медленно — каждая запись ждёт ответа от реплики. В PostgreSQL это выглядит так: ALTER SYSTEM SET synchronous_commit TO 'on'; ALTER SYSTEM SET synchronous_standby_names TO 'replica1'; Асинхронная репликация работает в фоне. Primary подтверждает транзакцию сразу, а secondary догоняют когда смогут. Быстро, но есть риск потери данных при падении мастера. MongoDB по умолчанию использует асинхронную репликацию: {w: 1, j: true} // Ждём запись только на primary {w: 'majority', j: true} // Ждём запись на большинство нод Multi-master репликация позволяет писать в любую ноду кластера. Звучит заманчиво, но порождает проблему конфликтов. Две ноды могут одновременно изменить одни и те же данные. Галера-кластер для MySQL решает это через сертификацию транзакций — узлы договариваются о порядке изменений. Отставание реплик — главная метрика здоровья репликации. В PostgreSQL следим за lag в pg_stat_replication, в MongoDB — за replication lag в rs.status(). Если реплика отстает больше определенного порога — пора разбираться в причинах. Мониторинг критичен. Нужно следить не только за отставанием, но и за статусом WAL (Write Ahead Log) архивов, свободным местом на дисках реплик и состоянием сетевого соединения между узлами. Один пропущенный WAL сегмент — и придется переинициализировать реплику с нуля. А еще репликация требует внимательной работы с транзакциями. Длинные транзакции на primary мешают очистке WAL, а значит, растет нагрузка на диск и сеть. И секционированные таблицы тоже могут преподнести сюрприз — операции с партициями должны реплицироваться атомарно. 🏴☠️ @happy_devops
Переход на партиционированные таблицы в боевой системе похож на замену колес на едущей машине. Один неверный шаг — и вся система встанет. Разберем, как провести миграцию безопасно и что делать с гигантскими объемами данных. Вот реальный кейс из практики. Таблица с данными о транзакциях весила 4 ТБ и росла на 50 ГБ в день. Запросы за последний месяц работали быстро благодаря индексам, но исторические отчеты могли считаться часами. Решение — партиционирование по месяцам. Первый шаг — создание структуры: CREATE TABLE transactions_new ( id bigint, created_at timestamp, amount decimal, -- другие поля ) PARTITION BY RANGE (created_at); -- Создаем партиции для каждого месяца CREATE TABLE transactions_2024_01 PARTITION OF transactions_new FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); Дальше начинается самое сложное — перенос данных. Прямой INSERT SELECT на таких объемах заблокирует таблицу на часы. Правильный путь — батчинг с параллельной обработкой: -- Функция для переноса данных за один день CREATE OR REPLACE FUNCTION migrate_day(day_start date) RETURNS integer AS $$ BEGIN RETURN WITH moved AS ( DELETE FROM transactions WHERE created_at >= day_start AND created_at < day_start + interval '1 day' RETURNING * ) INSERT INTO transactions_new SELECT * FROM moved; END; $$ LANGUAGE plpgsql; -- Запускаем параллельно для разных дней SELECT migrate_day(day) FROM generate_series('2023-01-01'::date, '2024-01-01', '1 day') day; Во время миграции критично следить за нагрузкой на диски и CPU. Утилита pg_stat_progress_copy показывает прогресс операций. А автовакуум будет очищать старые версии строк, не давая таблице разрастаться. Отдельная история — обслуживание партиций. Старые данные можно архивировать, перенося целые партиции на медленные диски: -- Перемещаем старую партицию на другое табличное пространство ALTER TABLE transactions_2023_01 SET TABLESPACE cold_storage; -- Отключаем автовакуум для старых партиций ALTER TABLE transactions_2023_01 SET (autovacuum_enabled = false); Для автоматизации рутины помогает расширение pg_partman. Оно создает новые партиции заранее и может автоматически архивировать старые: SELECT partman.create_parent( 'public.transactions', 'created_at', 'range', 'month', p_premake := 3 ); И последнее: партиционирование требует изменений в приложении. Запросы без указания партиционного ключа будут сканировать все партиции. А значит, нужно научить ORM всегда добавлять created_at в условия поиска. 🏴☠️ @happy_devops
MongoDB, PostgreSQL и Elasticsearch предлагают разные подходы к партиционированию. И дело не только в терминологии — каждая база данных реализует его по-своему, со своими преимуществами и ограничениями. В PostgreSQL после версии 10.0 появилось декларативное партиционирование. Создаём основную таблицу, указываем стратегию разделения, и база сама распределяет данные по дочерним таблицам. Партиции наследуют структуру родительской таблицы, но могут хранить данные на разных табличных пространствах. Под капотом PostgreSQL использует ограничения и триггеры для маршрутизации данных. MongoDB строит партиционирование на концепции шардинга. Каждый шард — отдельный сервер или набор реплик. Данные распределяются по шардам на основе ключа. Интересная фишка — зоны шардинга. Можно связать диапазоны ключей с конкретными шардами и тем самым контролировать, где живут данные. Балансировщик следит за равномерным распределением нагрузки. В Elasticsearch партиционирование встроено изначально. Каждый индекс разбивается на шарды, которые распределяются по узлам кластера. Количество шардов задаётся при создании индекса и не меняется, но можно использовать шаблоны индексов для автоматического создания новых индексов по времени или другим критериям. ClickHouse особенно интересно подходит к партиционированию аналитических данных. Он хранит партиции как отдельные директории на диске, что упрощает работу с ними. Можно замораживать старые партиции, перемещать их на другие диски или даже сервера. А встроенная система материализованных представлений автоматически поддерживает агрегаты по партициям. Главный подводный камень во всех базах — запросы, которые работают с несколькими партициями. PostgreSQL приходится объединять данные из разных таблиц, MongoDB собирает результаты со всех затронутых шардов, а Elasticsearch балансирует нагрузку между узлами. Чем больше партиций затрагивает запрос, тем сложнее его выполнить. И везде есть свои тонкости при работе с индексами. В PostgreSQL индексы создаются отдельно для каждой партиции. MongoDB требует, чтобы ключ шардинга был частью всех уникальных индексов. А в Elasticsearch количество шардов влияет на размер индекса в памяти. На практике выбор стратегии партиционирования часто диктуется не только техническими, но и организационными требованиями. Команда может быть более опытна в работе с одной из баз данных, или инфраструктура лучше подходит для определённого подхода. 🏴☠️ @happy_devops