REVERT
Основная проблема откатов релизов - миграции.
Дело в том что после накатывания релизом сначала выполняются миграции которые меняют схему базы.
Но в дальнейшем, если релиз проблемный то просто откатом кода может не обойтись, так как старая версия может быть несовместимой с новой схемой. Основное решение тут - писать не ломающии миграции и тестировать откат релиза на тест стенде.
Ну и сами миграции, в момент исполнения, должны быть транзакционными. Что бы в момент их исполнения можно было быстро откатить при ошибке.
Основная проблема откатов релизов - миграции.
Дело в том что после накатывания релизом сначала выполняются миграции которые меняют схему базы.
Но в дальнейшем, если релиз проблемный то просто откатом кода может не обойтись, так как старая версия может быть несовместимой с новой схемой. Основное решение тут - писать не ломающии миграции и тестировать откат релиза на тест стенде.
Ну и сами миграции, в момент исполнения, должны быть транзакционными. Что бы в момент их исполнения можно было быстро откатить при ошибке.
👍1
LOCK
Для того что бы более менее застраховать себя от ломающих обновлений транзитивных зависимостей глубокого уровня есть lock файлы.
Обычно все эти вложенные зависимости скачиваются из соответствующих репозиториев языка. Мы можем разово все собрать, проверить что все работает как надо, и зафиксировать вообще все в lock файле. И тогда при следующей установке мы точно получим все те же версии зависимостей что и при рабочей сборке.
В чем отличие от обычного файлы с списком зависимостей? Например requirements.txt в питоне. В том что в нем описываются верхнеуровневые пакеты, которые под собой могут тянуть другие пакеты не явным образом. А вот lock файл как раз фиксирует версии всех этих не явных пакетов.
Для того что бы более менее застраховать себя от ломающих обновлений транзитивных зависимостей глубокого уровня есть lock файлы.
Обычно все эти вложенные зависимости скачиваются из соответствующих репозиториев языка. Мы можем разово все собрать, проверить что все работает как надо, и зафиксировать вообще все в lock файле. И тогда при следующей установке мы точно получим все те же версии зависимостей что и при рабочей сборке.
В чем отличие от обычного файлы с списком зависимостей? Например requirements.txt в питоне. В том что в нем описываются верхнеуровневые пакеты, которые под собой могут тянуть другие пакеты не явным образом. А вот lock файл как раз фиксирует версии всех этих не явных пакетов.
👍1
REINSTALL
Иногда легче собрать новую инфру чем переделывать текущую.
Стратегия тут может быть такой:
- Поднимаем нормальную дев инфру
- Настраиваем релизный процесс туда
- Тестируем
- Если все окей поднимаем такую же прод инфру, но с старой бд
- Релизимся
- Тестируем
- Переключаем домен на новый прод
Получится максимально бесшовный процесс, когда пользователи даже не заметят изменений. По необходимости можем настроить миграцию бд на новый сервер, в релизное окно или бесшовно)
Иногда легче собрать новую инфру чем переделывать текущую.
Стратегия тут может быть такой:
- Поднимаем нормальную дев инфру
- Настраиваем релизный процесс туда
- Тестируем
- Если все окей поднимаем такую же прод инфру, но с старой бд
- Релизимся
- Тестируем
- Переключаем домен на новый прод
Получится максимально бесшовный процесс, когда пользователи даже не заметят изменений. По необходимости можем настроить миграцию бд на новый сервер, в релизное окно или бесшовно)
👍1
OBSERVABILITY
Прозрачность должна быть настроена без мусора.
С бизнесовой точки зрения мы должны видеть как запрос пользователя проходит весь процесс, что происходит на каждом шаге.
С технической должны собираться базовые метрики по времени выполнения шага, как изменяются данные и куда делаются запросы.
Это позволит нам оценивать все проблемные места и заниматься реальной оптимизацией там где это правда нужно.
А вот мусорные данные, типа огромных трейсов ошибок или цепочка вызовов методов могут только мешать и засорять информацией при поиске проблем.
Прозрачность должна быть настроена без мусора.
С бизнесовой точки зрения мы должны видеть как запрос пользователя проходит весь процесс, что происходит на каждом шаге.
С технической должны собираться базовые метрики по времени выполнения шага, как изменяются данные и куда делаются запросы.
Это позволит нам оценивать все проблемные места и заниматься реальной оптимизацией там где это правда нужно.
А вот мусорные данные, типа огромных трейсов ошибок или цепочка вызовов методов могут только мешать и засорять информацией при поиске проблем.
👍1
STATELESS
Stateless инструменты чаще просчитывают данные на лету. Тот же самый ansible при запуске обходит сервера, собирает актуальное состояние и потом выполняет только то что нужно.
Мне этот подход нравится куда больше чем statefull, типа тераформа и пулуми. Там где мы обязаны поддерживать сервер таким же, как сохраненный стейт. Ведь если мы изменим сервер сами, или потеряем стейт, то может возникнуть много проблем.
А вот расчет стейта на лету не подводит)
Stateless инструменты чаще просчитывают данные на лету. Тот же самый ansible при запуске обходит сервера, собирает актуальное состояние и потом выполняет только то что нужно.
Мне этот подход нравится куда больше чем statefull, типа тераформа и пулуми. Там где мы обязаны поддерживать сервер таким же, как сохраненный стейт. Ведь если мы изменим сервер сами, или потеряем стейт, то может возникнуть много проблем.
А вот расчет стейта на лету не подводит)
👍1
LINUX
Даже сейчас, с кубером и облакам, без знаний линукса не обойтись.
Есть специфичные задачи которые до сих пор сложно положить на кубер. Например если у нас большая БД на сотни гигов то работать с ней легче всего с обычного сервера. Например сделать систему бекапирования и тестирования самих бекапов. Ведь это последнее место где мы хотим что бы кубер внезапно решил перенести поду на другой сервер и убил его.
Поэтому настроить безопасность сервера и все нужное окружение нужно уметь)
Даже сейчас, с кубером и облакам, без знаний линукса не обойтись.
Есть специфичные задачи которые до сих пор сложно положить на кубер. Например если у нас большая БД на сотни гигов то работать с ней легче всего с обычного сервера. Например сделать систему бекапирования и тестирования самих бекапов. Ведь это последнее место где мы хотим что бы кубер внезапно решил перенести поду на другой сервер и убил его.
Поэтому настроить безопасность сервера и все нужное окружение нужно уметь)
👍1
VARS
Иногда удобнее делать комбинаторные переменки при релизах.
Как пример - бывает необходимость указать в переменках кучу доменов, которые по факту являются поддоменами одного домена. И проделать тоже самое для нескольких стендов.
В таких случаях куда легче сделать набор переменных в таком формате:
и так далее
Это позволит нам добавлять новые стенды просто добавлением одной переменки с нужным енвом, а все остальное сгенерится на лету.
Иногда удобнее делать комбинаторные переменки при релизах.
Как пример - бывает необходимость указать в переменках кучу доменов, которые по факту являются поддоменами одного домена. И проделать тоже самое для нескольких стендов.
В таких случаях куда легче сделать набор переменных в таком формате:
MAIN_DOMAIN = some-prod.com (prod env)
MAIN_DOMAIN = some-dev.com (dev env)
APP_1 = app-one.$MAIN_DOMAIN (all env)
APP_2 = app-two.$MAIN_DOMAIN (all env)
и так далее
Это позволит нам добавлять новые стенды просто добавлением одной переменки с нужным енвом, а все остальное сгенерится на лету.
👍1
BALANCE
Конфигурация сервера должна быть сбалансированна.
Нет смысла брать огромное количество ядер в ущерб скорости диска, сети и ram. По сути почти любой запрос к системе это не только вычисления малого обьема данных на чипе. Чаще нужно сходить в какую то интеграцию, считать что с диска, подержать промежуточный итог в оперативке и тд. А делаю упор только на проц он будет в простое и постоянно ожидать IO. По сути мы просто заплатим за проц который не будет выполнять полезную нагрузку.
Чаще сервер на 4 ядра будет справляться лучше чем сервер на 8, если все остальное у него лучше)
Конфигурация сервера должна быть сбалансированна.
Нет смысла брать огромное количество ядер в ущерб скорости диска, сети и ram. По сути почти любой запрос к системе это не только вычисления малого обьема данных на чипе. Чаще нужно сходить в какую то интеграцию, считать что с диска, подержать промежуточный итог в оперативке и тд. А делаю упор только на проц он будет в простое и постоянно ожидать IO. По сути мы просто заплатим за проц который не будет выполнять полезную нагрузку.
Чаще сервер на 4 ядра будет справляться лучше чем сервер на 8, если все остальное у него лучше)
👍1
SPLIT BRAIN
Чаще это относится к базам данных. Ситуация когда нарушается кворум при сетевых сбоях и в системе может появится два мастера.
Проблема в том куда именно будет писать приложение, при нарушении балансировки может случится ситуация когда запись данных пойдет в два разных места. Опасно это тем что потом будет очень сложно смержить все эти изменения.
Как избежать? Ну для начала сделать нормальную сеть. А так, смотреть на балансировку, в момент времени должен быть только один мастер. При развале кластера по сети старый мастер желательно прям прибить, некоторые физически убивают питание сервера.
Но мне нравится другой вариант. В принципе не включать автопереключение мастера, при сбоях переводить сбор кластера в ручное управление. Тогда можно гарантировать что не случится два мастера.
Чаще это относится к базам данных. Ситуация когда нарушается кворум при сетевых сбоях и в системе может появится два мастера.
Проблема в том куда именно будет писать приложение, при нарушении балансировки может случится ситуация когда запись данных пойдет в два разных места. Опасно это тем что потом будет очень сложно смержить все эти изменения.
Как избежать? Ну для начала сделать нормальную сеть. А так, смотреть на балансировку, в момент времени должен быть только один мастер. При развале кластера по сети старый мастер желательно прям прибить, некоторые физически убивают питание сервера.
Но мне нравится другой вариант. В принципе не включать автопереключение мастера, при сбоях переводить сбор кластера в ручное управление. Тогда можно гарантировать что не случится два мастера.
👍1
CLEAR
Иногда можно перекладывать патерны из программирования на пайплайны.
Например чистые функции. В максимальном приближении в джобах это может быть так:
- Одни входные данные = один результат
- Без побочных эффектов = тут сложно, смысл пайплайнов в изминениях, но можно делать их минимально
- Композиции = собирать джобу из разных шаблонов
- Явность = никаких добавочных данных которые не передавались в саму джобу
- Декларативность = описываем финальный результат
- Ленивость = не вычисляем пока это не нужно
Понятно, это только экстраполяция, сделать джобы на 100 процентов функциональными не получится, это не совсем классический код. Но применять подходы может помочь)
Иногда можно перекладывать патерны из программирования на пайплайны.
Например чистые функции. В максимальном приближении в джобах это может быть так:
- Одни входные данные = один результат
- Без побочных эффектов = тут сложно, смысл пайплайнов в изминениях, но можно делать их минимально
- Композиции = собирать джобу из разных шаблонов
- Явность = никаких добавочных данных которые не передавались в саму джобу
- Декларативность = описываем финальный результат
- Ленивость = не вычисляем пока это не нужно
Понятно, это только экстраполяция, сделать джобы на 100 процентов функциональными не получится, это не совсем классический код. Но применять подходы может помочь)
👍1
IO
В современных системах есть довольно много ожидания ввода и вывода.
Одна фича может не делать много вычислений, но собирать много информации. Например сходить в кеш, в базу, до внешней интеграции и тд. По итогу у нас может быть большое количество одновременных коннектов которые просто ожидают чего либо.
Что из этого следует?
То что важно учитывать это при проектировании инфры. Например:
- Настраивать быстрые кеши ближе к приложению
- По возможности делать быструю сеть
- Паралелизм важнее чем мощные ядра
- Быстрые диски на бд и сторедже
- Кеширование на клиенте
Это поможет просто снизить время ожидания, соответсвенно в целом нагрузку на систему. Мы сможем быстро отдавать клиенту то что он запрашивает.
В современных системах есть довольно много ожидания ввода и вывода.
Одна фича может не делать много вычислений, но собирать много информации. Например сходить в кеш, в базу, до внешней интеграции и тд. По итогу у нас может быть большое количество одновременных коннектов которые просто ожидают чего либо.
Что из этого следует?
То что важно учитывать это при проектировании инфры. Например:
- Настраивать быстрые кеши ближе к приложению
- По возможности делать быструю сеть
- Паралелизм важнее чем мощные ядра
- Быстрые диски на бд и сторедже
- Кеширование на клиенте
Это поможет просто снизить время ожидания, соответсвенно в целом нагрузку на систему. Мы сможем быстро отдавать клиенту то что он запрашивает.
👍2
K8S
Куб можно рассматривать как операционную систему более высокого уровня, распределенную.
По сути роль куба примерно такая же как у обычных ОС. Это запуск приложений и абстрагирование. Да и интерфейс взаимодействия чем то похож на линукс, просто CLI с определенным синтаксисом, которая под копотом делает определенные вызовы системы.
Да, это экстраполяция. Но с такой ментальной моделью мне проще воспринимать куб, как просто один из слоев абстракции от железа)
Куб можно рассматривать как операционную систему более высокого уровня, распределенную.
По сути роль куба примерно такая же как у обычных ОС. Это запуск приложений и абстрагирование. Да и интерфейс взаимодействия чем то похож на линукс, просто CLI с определенным синтаксисом, которая под копотом делает определенные вызовы системы.
Да, это экстраполяция. Но с такой ментальной моделью мне проще воспринимать куб, как просто один из слоев абстракции от железа)
👍2
NET
Сетевые политики это одна из важных частей безопасности.
Тут главная концепция - запрещено все что не разрешено. Сетевые доступы куда либо должны быть открыты только до нужных интеграций.
Например в базу данных могут обратится только те сервисы которые явно должны с ней работать, что бы избежать доступа из скомпромитированных сервисов. Типа что бы завладев одним подом мы не смогли пройтись по всей сети, ограничение поверхности атаки.
Сетевые политики это одна из важных частей безопасности.
Тут главная концепция - запрещено все что не разрешено. Сетевые доступы куда либо должны быть открыты только до нужных интеграций.
Например в базу данных могут обратится только те сервисы которые явно должны с ней работать, что бы избежать доступа из скомпромитированных сервисов. Типа что бы завладев одним подом мы не смогли пройтись по всей сети, ограничение поверхности атаки.
👍1
TMP
Шаблоны пайплайнов и манифестов могут как усложнить жизнь так и сделать ее сильно проще.
Как сделать проще:
- По дефолту все компоненты выключены, включаем только то что нужно
- Никаких жесткий зависимостей компонентов между собой
- Там где можно используем паралельное выполнение
- Включаем дефолтный флоу
- Минимум переменных, все что можно генерим на лету
Так мы сможем быстро включить нужные шаги и компоненты, задать несоклько базовых переменок и сразу полететь уже)
Шаблоны пайплайнов и манифестов могут как усложнить жизнь так и сделать ее сильно проще.
Как сделать проще:
- По дефолту все компоненты выключены, включаем только то что нужно
- Никаких жесткий зависимостей компонентов между собой
- Там где можно используем паралельное выполнение
- Включаем дефолтный флоу
- Минимум переменных, все что можно генерим на лету
Так мы сможем быстро включить нужные шаги и компоненты, задать несоклько базовых переменок и сразу полететь уже)
👍1
CI/CD
На сколько сильно нужно шаблонизировать пайплайны?
Как по мне до уровне что бы запустить джобу нужно добавить 2-3 переменки окружения (не приложения и для джобы).
Потому что если начать шаблонизировать вообще все то что бы запустить джобу нужно будет написать текста почти столько же сколько и для обычной джобы. Да, остается единая точка для исправления пайплайнов везде. Но сильно повышается комбинаторика вариантов, и учесть все будет слишком сложно. Ну и пользоваться этим будет не удобно, теряется быстрый запуск проектов)
На сколько сильно нужно шаблонизировать пайплайны?
Как по мне до уровне что бы запустить джобу нужно добавить 2-3 переменки окружения (не приложения и для джобы).
Потому что если начать шаблонизировать вообще все то что бы запустить джобу нужно будет написать текста почти столько же сколько и для обычной джобы. Да, остается единая точка для исправления пайплайнов везде. Но сильно повышается комбинаторика вариантов, и учесть все будет слишком сложно. Ну и пользоваться этим будет не удобно, теряется быстрый запуск проектов)
👍1
MANUAL
Некоторые вещи нужно оставлять в полу ручном режиме.
Например тестирование бекапов. Я сейчас практикую это так:
- Скрипт поднимает контейнер с бд
- Заливает туда последний бекап
- Итеративно сравнивает количество записей в бекапе и проде по каждой таблице
- Присылает мне отчет
И вот отчет я просматриваю уже своими глазами.
Если оставить это полностью автоматически, типа скрипт просто присылает что ок или не ок то можно легко забыть про это. Может случится что скрипт вообще упадет и перестанет что либо присылать, и про это можно вообще забыть.
А когда ты по графику запускаешь его сам, например раз в 2 недели, то шанс ошибки сильно уменьшается.
Некоторые вещи нужно оставлять в полу ручном режиме.
Например тестирование бекапов. Я сейчас практикую это так:
- Скрипт поднимает контейнер с бд
- Заливает туда последний бекап
- Итеративно сравнивает количество записей в бекапе и проде по каждой таблице
- Присылает мне отчет
И вот отчет я просматриваю уже своими глазами.
Если оставить это полностью автоматически, типа скрипт просто присылает что ок или не ок то можно легко забыть про это. Может случится что скрипт вообще упадет и перестанет что либо присылать, и про это можно вообще забыть.
А когда ты по графику запускаешь его сам, например раз в 2 недели, то шанс ошибки сильно уменьшается.
👍1
OLD SCHOOL
Периодично встречаю странные конфигурации инфры.
На пример:
- Есть только прод, без теста
- Один сервер приложения
- Джанга катится напрямую на сервер
- Поднимается через systemd
- Но при этом используется managed постгрес
- Есть клауд s3
- App Load Balancer на уровне клауда
Странное сочитание современных решений и чего то очень старого)
Периодично встречаю странные конфигурации инфры.
На пример:
- Есть только прод, без теста
- Один сервер приложения
- Джанга катится напрямую на сервер
- Поднимается через systemd
- Но при этом используется managed постгрес
- Есть клауд s3
- App Load Balancer на уровне клауда
Странное сочитание современных решений и чего то очень старого)
👍1
LINUX
Все еще эксперементирую с последней версией fedora десктопной.
Одна из проблем - что бы сделать некоторые вещи нужны расширения, но не всегда они работают стабильно.
Например вчера я захотел сделать сокрытие топ бара при полноэкранном режиме, и что бы он открывался при наведении на него курсора. Как на макке.
И даже нашел несколько расширений. Более менее рабочими оказались два. Но в первом при наведении курсора на топ баре он начинал дрожать и становился нечитаемым, во втором наведение вообще не работало.
И это один из примеров, приходится часто идти на компромисы подобные.
Все еще эксперементирую с последней версией fedora десктопной.
Одна из проблем - что бы сделать некоторые вещи нужны расширения, но не всегда они работают стабильно.
Например вчера я захотел сделать сокрытие топ бара при полноэкранном режиме, и что бы он открывался при наведении на него курсора. Как на макке.
И даже нашел несколько расширений. Более менее рабочими оказались два. Но в первом при наведении курсора на топ баре он начинал дрожать и становился нечитаемым, во втором наведение вообще не работало.
И это один из примеров, приходится часто идти на компромисы подобные.
👍1
OPENSOURCE
Открытые исходники часто дают только илюзию безопасности.
Есть мнение - если код открыт то его проверяет комьюнити, значит он безопасен. Но тут вопрос именно в качестве этой проверки, до сих пор бывают случаи когда находят проблемы которые жили в коде с нулевых.
И да, есть важные открытые проекты, ревью которых могут делать професионала из больших компаний. То же самое ядро линукса, есть куча комерческих компаний которые заинтересованы в том что бы ядро было безопасным. Но даже это не гарантия, даже там могут быть проблемы)
Ну и вопрос, кто когда читал исходники опенсорса в последний раз?)
Открытые исходники часто дают только илюзию безопасности.
Есть мнение - если код открыт то его проверяет комьюнити, значит он безопасен. Но тут вопрос именно в качестве этой проверки, до сих пор бывают случаи когда находят проблемы которые жили в коде с нулевых.
И да, есть важные открытые проекты, ревью которых могут делать професионала из больших компаний. То же самое ядро линукса, есть куча комерческих компаний которые заинтересованы в том что бы ядро было безопасным. Но даже это не гарантия, даже там могут быть проблемы)
Ну и вопрос, кто когда читал исходники опенсорса в последний раз?)
👍1