Код в Прод
205 subscribers
7 photos
1 video
12 links
Привет! Меня зовут Илья Лушкевич, я DevOps и автор образовательных курсов в сфере IT.

Stepik - https://stepik.org/users/DevOps/teach
Download Telegram
Как выглядит идеальный CI/CD?

🔥Отличный вопрос для DevOps собесов. Чаще всего в ответ слышу:

Ну там, типа, как-то, собирается, деплоится, всё работает...


🙅‍♂️ Не канает. Я хочу понять, действительно ли ты в теме или просто перезапускал упавший пайплайн, не читая логи.

Вот что лично я жду от ответа:

🔹Глубина: не общие слова, а рассказ, что и почему ты делал. Что было хорошо, а что — больно.
🔹Опыт: как устроен твой пайплайн, какие грабли были, чем гордишься.
🔹Скорость: как ускорял сборку образов или юнит тесты.
🔹Фича-окружения: умеешь под каждую ветку поднимать временное окружение?
🔹DevSecOps: отделение прав доступа, интеграция с Vault, секреты.

💡 Идеальный ответ:

"У нас в прод в пятницу всё само выкатывается. Я настроил процессы, в мониторинги заглядываю изредка. Ща расскажу, как это работает..."

📌 Мини-чеклист для пайплайна из нескольких стадий:

Прогнать тесты, линтеры и проверки безопасности
🐳 Сбилдить Docker image и запушить в registry
⚙️ Прогнать миграции для базы
🚀 Обновить Deployment в кластере

Если эта задача вызывает ступор — значит, в проде пайплайны тебя ещё не сильно били 😉

⚙️ А у тебя в команде пайплайны работают как часы или их нужно подпинывать руками? 🤔
🔥2
🤔 Как безопасно хранить Docker-образы? Делать так, чтобы уязвимости не попадали в прод?

Harbor — топ-1 open-source приватный Docker Registry, который даёт всё для DevSecOps/DevOps:
- Proxy-cache для быстрого pull без лимитов.
- Встроенное сканирование уязвимостей (Trivy).
- Подпись образов (Cosign) от подмены.
- Политики блокировки небезопасных артефактов.
- Retention для автоматической очистки.
- Мониторинг через Kube-Prometheus-Stack.


Новый курс «Harbor — DevSecOps Docker Registry в Kubernetes» — от установки до production-ready Docker Registry.

Если у вас есть базовые знания Docker и Kubernetes, вы DevOps, разработчик или просто хотите изучить топовый инструмент, который в 101% случаев встретится в реальной работе — этот курс для вас.

🆓 Бесплатные доступы для 5 первых учащихся!

1 ссылка
2 ссылка
3 ссылка
4 ссылка
5 ссылка

🚀 Кто пройдет — пишите отзывы, интересно!
👍5
😐 Устали деплоить в Kubernetes через kubectl и бесконечные CI-скрипты? Хотите, чтобы деплой был воспроизводимым, контролируемым и прозрачным?

ArgoCD — де-факто стандарт GitOps для Kubernetes, который используют в крупных компаниях.

🚀 Запустил курс: «ArgoCD: GitOps-деплой и автоматизация в Kubernetes»

В курсе:
- GitOps — что это и зачем он нужен.
- Установка и настройка ArgoCD.
- Application и App of Apps.
- GitOps-деплой приложений.
- ArgoCD Image Updater (автокоммиты новых образов).
- Notifications (Telegram).
- SOPS и шифрование секретов в Git.


Курс подойдёт, если у вас есть базовые знания Docker и Kubernetes, вы DevOps или просто хотите прокачать практический GitOps-навык, который точно встретится в работе.

🆓 Бесплатные доступы для 5 первых участников:

1 ссылка
2 ссылка
3 ссылка

4 ссылка
5 ссылка

🔥 После прохождения — буду рад фидбеку!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
Helm — менеджер пакетов для Kubernetes, который упрощает установку, обновление и управление приложениями, упакованными в Helm-чарты.

Но... Конфликты при apply, CRD которые «поставились один раз и забылись», ресурсы зависли в Pending, а ты не понимаешь почему, плагины для diff и secrets как обязательный набор… Знакомо? 🤬

Есть инструмент, после которого возвращаться к классическому Helm уже не захочется.

😳 Знакомьтесь — Nelm. Разработка компании Flant, современная альтернатива Helm, полностью совместимая с вашими текущими Helm-чартами и релизами.

🤔 Коротко: Helm, каким он должен был быть в 2026 году:

Полная совместимость и простая миграция — Nelm построен на Helm, ничего переписывать не нужно.

Вместо проблемного клиентского 3-Way Merge применяется Kubernetes Server-Side Apply.

Контролируемый порядок деплоя — Nelm строит граф зависимостей ресурсов, а не надеется на хуки. Порядок можно явно задать аннотациями.

UX при деплое — Nelm во время установки/обновления выводит удобный прогресс, постоянно показывая статусы ресурсов, логи контейнеров и события (и даже автоматически откатывается при сбоях).

nelm release plan — точный план изменений перед применением (как terraform plan, но для Kubernetes).

Секреты из коробки — шифрованные values без плясок с плагинами.

Расширенное управление ресурсами — Nelm улучшил работу с CRD и политику жизненного цикла. Например, CRD из папки crds/ обновляются при каждом upgrade (в Helm они устанавливаются только однажды).

🎥 На видео — обычный nelm release plan и nelm release install: посмотрите, как Nelm генерирует план изменений, а во время установки в реальном времени показывает готовность ресурсов, подтягивает логи подов и выводит NOTES.

Helm после такого выглядит… ну, вы поняли 😅

📌 Инструмент новый, но если вы живёте в Kubernetes и вам важен контроль деплоя, Nelm точно стоит попробовать и положить в свою DevOps-копилку.

🍴 Попробуешь Nelm или Helm пока и так норм? 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
😎 Сегодня пятница, а что это значит? Правильно — в прод не деплоим. А ещё новая большая и продуманная программа: «Профессия: DevOps-инженер»

Сделали её совместно с Pragmatic Programmer и Rotoro cloud!

💗 На 3 дня объявляем неприличные скидки! Все курсы в программе по отдельности стоят 15 088 руб.

Но по промокоду: FIRST_3_DAYS_MAX_OFF, сегодня-завтра-послезавтра можно забрать всю программу за 4 974 руб! (он уже вшит в ссылку).

😎 Только тсс... об этом лайфхаке никому не рассказывайте!

А что внутри?

Внутри 7 топовых практических курсов для становления DevOps-инженером в 2026 году:

Linux
Docker
Hello, DevOps!
Git + GitHub
Kubernetes
GitLab CI
Prometheus

🥹 390+ уроков, 30 часов видео и 600+ тестовых и интерактивных задач!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
⌨️ Что такое траблшутинг и почему это самый важный навык инженера?

Представьте: понедельник, самый разгар рабочего дня. Сервис падает. Пользователи жалуются. Партнёры пишут в чат. В логах — сплошной хаос из ошибок.

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

🤔 Что это вообще такое?

Траблшутинг — это не просто «на 7 бед — один резет». Это системная детективная работа:

Замечаешь симптом.
Выдвигаешь гипотезы.
Проверяешь их по одной.
Находишь настоящую причину.
Устраняешь с минимальным риском.

В Linux у вас всегда есть улики (нагрузка, логи, сетевые соединения, открытые файлы), подозреваемые (процессы, сервисы, конфиги) и инструменты (ps, top, journalctl, tcpdump). Задача — собрать улики так, чтобы они указывали на одного виновника.

Главные правила бойцовского клуба:

😤 Не паниковать. Паника — худший советчик.
Паника превращает расследование в хаотичное дёрганье за рычаги. Проблема уже произошла — ваши эмоции не ускорят решение.

🧠 Симптом ≠ причина. Копай глубже.
Высокий CPU — это не проблема. Медленные запросы — это не диагноз. Это симптомы. Задача траблшутера — выстроить цепочку: от симптома к реальному источнику.

🔍 Работай гипотезами, а не рандомными командами.
Не «попробую эту команду, если не поможет — следующую». А: сформулировали → поняли, что должно быть правдой → проверили. Ошибочная гипотеза — не провал, а шаг, который сделал картину чуть яснее.

💡 Каждый шаг должен сужать круг поиска.
Каждый шаг должен либо подтверждать гипотезу, либо исключать целый класс причин. Это как идти с фонариком в тёмной комнате — вы не освещаете всё сразу, вы постепенно делаете тьму меньше.

Почему это один из самых ценных навыков?

Инженер, который умеет системно разбирать инциденты:

Сокращает время простоя — меньше денежных и репутационных потерь.
Меньше зависит от помощи коллег.
Видит точки улучшения: где добавить мониторинг, что автоматизировать.
Прокачивает мышление, применимое далеко за пределами Linux

Именно это отличает человека, который выполняет задачи, от человека, которому доверяют сложные системы.

Со временем приходит важное ощущение: инцидент — это не катастрофа. Это задача. Иногда сложная, иногда неприятная — но у неё всегда есть причина и решение.

Умение это чувствовать — и есть настоящий траблшутинг 😉

👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Ставишь Nginx Ingress Controller в Kubernetes — и получаешь два балансировщика.

В облаке появился свой балансировщик, а в неймспейсе ingress-nginx крутится под с Nginx.

Знакомо? А зачем два?

Отличный вопрос с реального DevOps собеседования! Звучит просто, но на практике большинство спотыкается об это. 💀

Попробуйте проверить себя с помощью небольшого теста ниже. После ответа вы можете отобразить объяснение и сравнить свой ответ.

🗒 Варианты ответов:

1️⃣ Облачный балансировщик обеспечивает внешний доступ и маршрутизирует трафик в соответствии с конфигурациями Ingress, а Nginx используется только как прокси внутри кластера.

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

3️⃣ Облачный балансировщик принимает внешний трафик на уровне IP и портов, а Nginx внутри кластера маршрутизирует его по хостам и путям на основе правил Ingress.

4️⃣ Облачный балансировщик обрабатывает HTTP, а Nginx — HTTPS, вместе они обеспечивают полную TLS терминацию.

💡 Объяснение:

При установке Ingress Controller создаётся сервис с типом LoadBalancer — это сигнал облаку создать балансировщик с публичным IP.

Облачный балансировщик работает на L4 уровне — знает только IP и порт, больше ничего. Его задача — принять трафик снаружи и отправить на сервис ingress-nginx, который уже направляет трафик на поды Nginx.

Nginx делает умную работу на L7 уровне — читает Ingress-конфигурации и направляет трафик на нужные сервисы внутри кластера по имени хоста (
api.example.com) и пути (/api/v1/bananas).

Правильный ответ: 3️⃣

👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Какой ответ верный?
Anonymous Quiz
11%
1
11%
2
74%
3
3%
4
🐧 Ты создал облачный сервер. Добавил туда SSH-ключ… как тебе казалось.

Пытаешься зайти:
ssh foo@158.165.43.21

Permission denied.


😭 Отлично. Единственный доступ, который у тебя остаётся — serial console от облака.
Serial console — это доступ к серверу через системную консоль: ты подключаешься не по SSH, а напрямую к инстансу, как будто через физический терминал, только в браузере.

Но проблема... Copy-paste в нём работает очень плохо, и просто скопировать и вставить ключ не получится.

Хитрый вопрос с реального DevOps собеседования! Подумай, как бы ты выкрутился? 🤔

💡 Решение:

1. Можно временно включить доступ по паролю, подключиться к серверу по SSH из своего терминала и добавить ключ в ~/.ssh/authorized_keys.

👉 Способ рабочий, но важно не забыть потом отключить вход по паролю.

2. Если у вас есть аккаунт на GitHub, можно использовать его как источник публичных ключей:

curl
https://github.com/<ваш логин>.keys >> ~/.ssh/authorized_keys

GitHub хранит ваши публичные SSH-ключи, и их можно получить одной командой без ручного копирования.


👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
👩‍💻 Что такое Docker-образ на самом деле?

Откройте любое видео «Docker за 5 минут» — и вам почти наверняка скажут что-то из этого:

🔹 «Образ — это как ISO-образ диска».
🔹 «Dockerfile — это рецепт, а образ — готовое блюдо».
🔹 «Это коробка, в которой лежит ваше приложение».

Для первого знакомства — сойдёт. Но за этими метафорами полностью теряется то, чем образ является технически. А там всё устроено понятно и логично.

Если коротко: Docker-образ — это просто набор файлов, собранных по стандарту OCI. Внутри лежат слои с файлами, а к ним — описание, что и куда складывать. Давайте просто вскроем образ руками и посмотрим, что внутри.

1️⃣ Скачиваем образ без Docker

Возьмём skopeo — это утилита для работы с образами напрямую в registry: умеет копировать, инспектировать и перекладывать образы между хранилищами, без запущенного Docker-демона. Выгрузим образ прямо в директорию:

mkdir nginx-image
skopeo copy docker://docker.io/nginx:1.29 dir:nginx-image


nginx-image/
├── 20d41cd6829d...
├── 382a36159731...
├── 38a7e44929f3...
├── ... (ещё несколько таких же)
├── manifest.json
└── version


Никакого «диска» и никакой «коробки». Просто набор файлов с sha256-именами и manifest.json. С него и начнём.

2️⃣ Открываем manifest.json — оглавление образа

cat manifest.json


{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:5dfe511714e1fa9a9d1074193a6cc7fa0feab5d680be166336817a5fb57f4cbd",
"size": 9085
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:57fb71246055257a374deb7564ceca10f43c2352572b501efc08add5d24ebb61",
"size": 29780226
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:38a7e44929f3a02caf5d606403b9c7f843cf5fd963a30bd77d9a4deea44cc4e0",
"size": 33157664
},
...


Сам манифест не хранит данные. Это просто оглавление: ссылки (в поле digest) на конфиг образа и на слои.

3️⃣ Находим конфиг образа (image config) — паспорт образа

Возьмём digest из .config и откроем соответствующий файл:

cat 5dfe511714e1f... | jq '.'


Внутри — метаданные образа: какая команда запускается (CMD), переменные окружения (ENV), история сборки слоёв. Это все те инструкции, которые вы описывали в Dockerfile.

4️⃣ Вскрываем слой

Самое интересное — слои. Возьмём digest любого слоя из манифеста. В поле mediaType уже видно: ...tar+gzip. То есть слой — это обычный gzip-архив. Попробуем его распаковать:

mkdir layer
tar -xzvf 38a7e44929f... -C layer


docker-entrypoint.d/
etc/
usr/
var/


Внутри слоя — просто кусок файловой системы. Никакой магии, обычные файлы и директории, упакованные в tar.gz. Образ целиком — это несколько таких слоёв, которые при запуске накладываются друг на друга.

📌 Итого: Docker-образ — это аккуратная адресуемая структура по стандарту OCI: манифест говорит что где лежит, конфиг образа хранит метаданные сборки, а слои — это tar.gz-архивы.

👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥7👍6
👩‍💻 Как проверить сеть, если под рукой нет сетевых утилит?

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

А там голый образ. Ни curl, ни nc, ни telnet, и поставить нельзя — пользователь непривилегированный, да и интернета нет.

И как теперь быть?

А вот так:
exec 3<>/dev/tcp/10.244.1.15/8000

Но что тут вообще происходит?

Это старый трюк bash, о котором знают немногие — разберём по частям.

1️⃣ /dev/tcp/<IP>/<port> — не файл

Кажется, что это обычный путь. Но стоит проверить:
~$ ls /dev/tcp

ls: cannot access '/dev/tcp': No such file or directory

Файла нет и не было.

Это специальный путь, который перехватывает bash: вместо того чтобы открыть файл на диске, он открывает TCP-соединение. Есть и брат-близнец /dev/udp/... — для UDP.

2️⃣ 3<> — а это что за тройка с ромбиком?

Это файловый дескриптор — неотрицательное число, через которое процесс обращается к чему-то открытому: файлу, сокету, пайпу.

Базовые три всегда заняты:
0 → stdin   (ввод)
1 → stdout (вывод)
2 → stderr (ошибки)

А дальше номера свободны — можно открывать свои.

Запись 3<> означает «открой на чтение и запись и привяжи к дескриптору 3». Так наш TCP-сокет получает номер 3.

Команда exec закрепляет дескриптор за текущим процессом bash, а не за дочерним — поэтому сокет остаётся открытым для следующих команд.

3️⃣ Пусть номер выберет система

При ручном выборе дескриптора можно словить конфликт — занял 3, а он уже где-то используется. Поэтому отдадим выбор bash:
exec {fd}<>/dev/tcp/10.244.1.15/8000
echo "$fd" # bash сам выдал свободный номер, например 10

Вместо фиксированной цифры пишем {fd} — bash сам найдёт свободный дескриптор и положит его номер в переменную.

📌 Как понять, что проверка сработала?

Сам по себе exec 3<>/dev/tcp/... ничего не выводит — просто пытается открыть сокет. А если порт фильтруется (пакеты молча отбрасываются), команда зависнет.

Поэтому оборачиваем в timeout и явно говорим, что считать успехом:
timeout 3 bash -c 'exec 3<>/dev/tcp/10.244.1.15/8000' && echo CONNECTED || echo FAILED

Если соединение установилось за 3 секунды — CONNECTED. Иначе — FAILED: порт закрыт, недоступен или не ответил за таймаут.

👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍6
🐧 Заходишь на сервер, чтобы протестировать новый скрипт, а у chmod кто-то убрал x бит:
-rw-r--r-- 1 root root 63864 Jun 14 11:00 /bin/chmod


Пытаешься вернуть как было:
~$ chmod +x /bin/chmod

-bash: /bin/chmod: Permission denied

🥲 А chmod больше не запускается — ведь у него самого теперь нет права на выполнение.

И как починить chmod, если chmod сломан? 🤔

На самом деле есть довольно красивый способ, но сначала разберёмся, как Linux вообще запускает программы.

Большинство привычных программ в Linux — динамически слинкованные. Это значит, что они используют внешние библиотеки (.so), которые не лежат внутри самого бинарника.

Проще говоря, динамическая линковка — это когда программа говорит: «мне нужна вот эта книга, она лежит в общей библиотеке». А при статической линковке всё необходимое уже находится внутри самого бинарника.

Поэтому одна и та же libc, например, может использоваться сразу множеством программ, а не храниться отдельной копией внутри каждой.

Когда вы запускаете динамически слинкованную программу, ядро Linux запускает динамический загрузчик для неё.

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

Посмотреть, какой загрузчик нужен бинарнику, можно через ldd:
~$ ldd /bin/chmod

linux-vdso.so.1 (0x00007fff16ff5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f776111d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7761327000)

Вот он: /lib64/ld-linux-x86-64.so.2. И самое интересное — его можно вызвать вручную.

А значит, можно попросить загрузчик запустить наш chmod:
/lib64/ld-linux-x86-64.so.2 /bin/chmod +x /bin/chmod

Готово. Мы только что запустили chmod, у которого не было x бита, и с его помощью вернули этот самый x бит.

Проверяем:
~$ ls -l $(which chmod)

-rwxr-xr-x 1 root root 63864 Jun 14 11:00 /bin/chmod

Но почему это вообще сработало?

Ядро проверяет x бит у того файла, который запускают. А запустили мы ld-linux — у него с правами всё в порядке.

Дальше сам ld-linux открывает /bin/chmod и загружает его код в память. Поэтому x у самого chmod здесь уже не требуется.

И это работает не только с chmod — если случайно убрать x у другого динамически слинкованного бинарника, его тоже можно запустить через ld-linux.

Кстати, восстановить права можно и без этого трюка.

Например, если в системе есть Python:
python3 -c 'import os; os.chmod("/bin/chmod", 0o755)'


Или командой install — она умеет выставлять права при копировании:
install -m 755 /bin/chmod ./chmod
mv ./chmod /bin/chmod


Но мы сделали чуть интереснее: починили chmod с помощью самого chmod, который не был исполняемым. 😎

👨‍💻 Код в Прод
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2🤯2