Привет, Хабр! Меня зовут Андрей Бирюков. Я независимый эксперто в области ИТ и ИБ, преподаю в учебных центрах и пишу книги.
На просторах сети можно найти множество статей, посвященных внедрению DevOps. В них рассказывается о контейнерах, веб серверах, базах данных и прочих корпоративных сервисах, и их реализации.
Цена ошибки в таких сервисах это простой или недоступность системы. Но в промышленной разработке всё иначе. Если ошибка в коде отправит стрелу экскаватора в нештатное положение или остановит конвейер на автозаводе — простой стоит десятки тысяч долларов в час. А перепрошивка парка из двух тысяч контроллеров вручную может занять месяц.

Но разработчики промышленного оборудования тоже хотят DevOps «как в Google», только при этом у них RS-485 и «голое железо без ОС». В этой статье мы на реальных примерах посмотрим, как можно внедрить DevOps для разработки промышленного оборудования.
Три проклятия промышленной разработки
Прежде чем строить конвейер, признайте некоторые ограничения, с которыми веб‑девопс не сталкивается. Начнем с того, что железо не виртуальное резиновое. Ваш контроллер, возможно, работает на процессоре с частотой 200 МГц и 64 мегабайтами оперативной памяти. Никакого Docker‑демона, раннера GitLab или Python‑скрипта вы туда не поставите. Там есть только последовательный порт и протокол Modbus.

И что же нам с этим делать? Принять как факт: агенты непрерывной доставки не живут на целевом железе, они живут рядом. Вы строите шлюз обновлений — отдельное устройство или сервис, который через промышленный протокол (например, OPC UA или MQTT) передает образ прошивки кусками и подтверждает целостность.
Рассмотрим пример из практики. У одного заказчика были контроллеры на FreeRTOS без сетевого стека. Они сделали шлюз на Raspberry Pi (да, попахивает бытовым DIY, но дешево и сердито), который физически подключался к отладочному разъему JTAG через самодельный переходник. Шлюз получал бинарник из Artifactory по HTTPS и прошивал контроллер. Оператор просто нажимал кнопку на веб‑интерфейсе шлюза вместо того, чтобы ехать на склад с ноутбуком.
Следующее проклятие — сертификация не прощает перемен. Если ваше устройство выходит в медицинскую или авиационную серию, каждая прошивка должна быть сертифицирована. Процесс занимает месяцы, и в это время вы не можете деплоить каждое изменение. Ваш релизный цикл — это не пять минут, а три месяца.
Для решения этой проблемы можно разделить пайплайн на два контура. Контур разработки — быстрый, частый, без сертификации. Он работает только на стендах разработчиков и HIL‑стендах. Контур релиза — редкий, строгий, со всеми проверками и подписями. И главное: автоматизируйте не деплой, а подготовку к сертификации.
Ваш пайплайн должен генерировать пакет документов: список всех зависимостей с версиями, результаты каждого теста с временными метками, разницу между этой версией и предыдущей на уровне строк кода.
Так, например, в проекте медицинского томографа сертификация занимала четыре месяца. Сократить этот срок нельзя, но можно сократить время подготовки к сертификации с трех недель до двух часов. Пайплайн собирал всю доказательную базу: протоколы статического анализа (MISRA), отчеты о покрытии тестами на HIL‑стенде, SBOM в формате SPDX. Когда приезжал сертификационный орган, инженер просто открывал папку с артефактами конкретного релиза.
И, наконец, офлайн — это норма. Промышленные сети часто физически изолированы и в них нет интернета. Нет доступа к вашему приватному Docker Registry. Нет возможности дернуть зависимость с GitHub.

В таких случаях проектируйте ваш DevOps‑конвейер как отказоустойчивый офлайн‑терминал, возможно даже в форм факторе, аналогичном представленному на рисунке выше. Все артефакты должны лежать внутри периметра.
Все зависимости — кэшироваться локально. Причем кэш должен быть не «прозрачным прокси», а полной копией с проверкой контрольных сумм. И ещё один совет: всегда храните компилятор и все тулчейны внутри системы контроля версий или артефакториума. Через три года вы не найдете ту версию GCC для MSP430, а прод показать надо.
Вот еще небольшой пример. У заказчика из нефтегаза площадка находилась в тундре, связь — спутник с лагом 700 миллисекунд и лимитом трафика 500 мегабайт в месяц. Пайплайн в такой инфраструктуре был сделан двухэтапным.
В центральном офисе собирался «кит» — образ виртуальной машины со всеми средами, зависимостями, тулчейнами и последними стабильными прошивками. Этот образ записывался на NVMe‑накопитель и уезжал с вахтовиком на вертолете. На площадке разворачивали локальный GitLab Runner и всю инфраструктуру внутри одного сервера.
Архитектура промышленного пайплайна
Теперь перейдем к конкретной структуре. Здесь нам придется забыть про классическую тройку Dev — Test — Prod, так как для промышленности она работает иначе. Здесь у нас будет несколько слоев, каждый из которых будет использоваться для определенных задач.

Слой ноль: Sandbox — рабочая станция разработчика.
На этом слое всё разрешено. Эмуляция QEMU, падения в kernel panic, отладчики, профайлеры. Разработчик собирает код у себя, накидывает юнит‑тесты, проверяет статику. Этот этап должен занимать не больше десяти минут, иначе разработчик начнет коммитить неотлаженный код «на сервер, пусть там проверят».
Здесь мы настраиваем автоматическую сборку при каждом сохранении файла (например, через act или локальный nektos), также поднятие эмулятора периферии и запуск быстрых модульных тестов.
Слой первый: Hardware-in-the-Loop — реальное железо в тепличных условиях.
На этом слое у нас уже стоит реальный контроллер (или несколько) на столе в лаборатории. На него подаются тестовые сигналы от генератора. Он управляет не реальной установкой, а её эмулятором — второй платой или симулятором нагрузки.
Небольшой пример из жизни разработчиков лифтового оборудования. Стенд состоял из двух промышленных ПЛК. Один был тестируемым (наш софт), второй — эмулятором шахты (подвигал моторчики, замыкал датчики дверей). Между ними — электрическая развязка на реле. В пайплайне после каждого пул‑реквеста запускался сценарий: «открой дверь, загрузи кабину на 300 кг, поезжай на третий этаж». Если лифт ошибался этажом — тест падал.
Здесь стоит отметить, железа всегда меньше, чем разработчиков. Поэтому HIL‑стенды — ресурс ограниченный. И для работы с ними нужно внедрить очередь на запуск. Pull request не запускает тесты мгновенно, а встает в очередь. А вот merge в основную ветку — уже обязательно запускает полный набор на всех доступных стендах, даже если это займет ночь.
Слой второй: FAT (Factory Acceptance Testing) — приёмочные испытания.
Этот этап проходит уже не разработчик, а технолог или сервисный инженер. Собрана полная система: несколько контроллеров, панель оператора, реальные датчики и исполнительные механизмы (но без нагрузки на производстве). Здесь код не обновляется автоматически. Только по команде человека.
На этом слое DevOps необходимо автоматизировать подготовку окружения для FAT. Ваш пайплайн по тегу релиза (например, v2.3.0-fat) должен:
собрать прошивки для всех типов контроллеров (главный пульт, удалённая станция, датчики давления);
запаковать их в единый архив c манифестом;
сгенерировать инструкцию по обновлению с чек‑листом для технолога;
записать лог сборки и контрольные суммы каждого бинарника.
Технолог берёт этот архив, загружает на ноутбук, идёт к стенду и прошивает всё по инструкции. Он делает это руками. Потому что, если что‑то пойдёт не так во время FAT, он обязан видеть процесс.
Слой третий: Production — железо на реальном объекте.
Здесь действует принцип «pull, а не push». Система не деплоит обновления принудительно. Вместо этого каждое устройство (шлюз, контроллер) периодически опрашивает специальный сервер: «Есть новая подписанная версия для моей модели и ревизии?». Если есть — устройство само скачивает, проверяет подпись, сверяет совместимость и применяет обновление (не всегда по сети — иногда через тот самый шлюз по RS-485).
Как это выглядит в коде. У вас есть Git‑репозиторий релизов. Каждый релиз — это тег вида release/2025.03.18/tomograph-2.4.1. В папке manifests лежит YAML‑файл:
device_model: "Tomograph-X7"
hw_revision: "Rev.C"
firmware_version: "2.4.1"
sha256: "a7f3c9e1..."
signature: "RSA:... (подписано закрытым ключем)|
url: "https://updates.internal.company/firmwares/tomograph_x7_v2.4.1.bin"
min_compatible_hw: "Rev.B" # можно обновлять с Rev.B, но не с Rev.AУстройство скачивает этот манифест, проверяет подпись публичным ключом, зашитым в неизменяемую память, и если всё ок — тянет бинарник.
Главный принцип: вы не управляете обновлением принудительно. Вы объявляете наличие новой версии. Когда её установить — решает владелец производства. Иногда — никогда, и это тоже нормально.
Автоматизация безопасности
Веб‑разработчик думает о безопасности как о защите от взлома. Промышленный разработчик думает ещё и о безопасности как о защите от дурака. Здесь нужно усвоить простое правило: без цифровой подписи нет деплоя.
Каждый бинарник, который попадает на реальное железо (и даже на HIL‑стенд), должен быть подписан. Ключ подписи — на отдельном HSM‑модуле, доступ к которому есть только у ответственного за релизы. Причём подписывается не один файл, а вся сборка целиком. Если кто‑то заменит прошивку контроллера, но не подпишет заново манифест — устройство отвергнет обновление.
Для реализации в пайплайне добавьте шаг sign artifacts после всех тестов, но перед архивацией. Он работает только для тега release/* и не работает для веток разработки. Подпись ложится в отдельный файл .sig рядом с бинарником. При этом, на устройстве проверка занимает микросекунды.
По мимо цифровой подписи, для каждого релиза должен быть разработан SBOM (Software Bill of Materials). Это список всех компонентов: библиотек, фреймворков, даже фрагментов кода из сторонних репозиториев. Для промышленности это критично: если завтра найдут уязвимость в вашей версии FreeRTOS, вы должны мгновенно сказать, на каких устройствах она установлена.

Для генерации SBOM в конце пайплайна запускается инструмент (например, FOSSA или простой скрипт, анализирующий зависимости linker'a). Он создаёт файл в формате CycloneDX XML. Этот файл ложится в артефакты релиза и подписывается тем же ключом. Через полгода при аудите вы просто показываете папку со всеми релизами и SBOM к ним.
Пример из практики. В нефтегазовом проекте регулятор потребовал отчёт по библиотеке с критической уязвимостью. У заказчика было 3000 контроллеров на трёх площадках. Скрипт, который за три минуты перебрал все манифесты, нашёл 42 устройства с уязвимой версией и сгенерировал задачу для сервисной бригады. Без SBOM пришлось бы объезжать каждый шкаф вручную.
Что делать с Legacy‑проектами
Да, легаси в промышленности хоть отбавляй, но избавиться от устаревших решений здесь еще сложнее, чем в корпоративе. Допустим, у вас есть система, которой десять лет. Сборка — через Makefile, который ничего не кэширует, бинарники распространяются флешками, документация в Word‑файлах на общем диске. DevOps там не внедрить, скажете вы. На самом деле внедрить можно, но не целиком.
Для начала уберите людей из цикла сборки. Сейчас ваш инженер собирает прошивку локально, потом копирует её на флешку. Сделайте скрипт сборки (оберните ваши инструкции в bash‑скрипт), который запускается на выделенном сервере по команде из чата. Артефакт складывается в общую папку с датой и коммитом. С точки зрения автоматизации это уже прогресс.
Затем добавьте автоматическую проверку после сборки. Простейший тест: «бинарник не превышает 512 килобайт? Есть ли в нём секция.text?». Если провалилось — сборка считается неудачной, на флешку не копируется.
На следующем шаге введите контроль версий для прошивок. Заведите простой SQLite или даже текстовый файл, где записываете: дата сборки, версия прошивки, от какого коммита, на каких устройствах установлена. Это уже база данных конфигураций.
В результате через три месяца у вас будет не DevOps, но «хорошо организованная рутина», а это 80% пути.
Организационные ловушки и как их обойти
Техническая часть — половина дела. Вторая половина — убедить людей работать по‑новому. И на этом пути нас подстерегают некоторые ловушки.

Ловушка первая: «у нас тут особенные требования, автоматизация не подходит». Обычно это говорит главный технолог или safety‑инженер. Они правы в том смысле, что автоматизация не должна ломать процессы валидации. Но они не правы, что автоматизация невозможна.
Для решения этой проблемы пригласите их участвовать в проектировании пайплайна. Пусть они пропишут правила: «прежде чем собрать релизную прошивку, должна выполниться проверка А, Б и В». Вы реализуете эти правила в коде пайплайна. В итоге их требования не игнорируются, а становятся жёсткими, воспроизводимыми шагами. И инженеры перестают бояться.
Следующая ловушка, а точнее, классическое заблуждение: «мы всё равно не можем деплоить часто, зачем нам CI/CD?»
DevOps в промышленности измеряется не частотой релизов, а временем восстановления после сбоя и стоимостью сертификации. Покажите цифры: сколько человеко‑часов в месяц тратится на сборку прошивок руками. Сколько раз инженер забыл включить оптимизацию в компиляторе и прошил debug‑сборку, которая тормозит. Во сколько обходится простой, потому что «нужный HEX‑файл уехал на том ноутбуке у Петрова в командировку».
Еще одной серьезной проблемой является нехватка времени. Автоматизация требует инвестиций сейчас, а отдача — через полгода. Для промышленности характерны проекты с длительным циклом.
Для решения берите не проект целиком, а одну больную точку. Самую больную. Ту, где инженеры проклинают текущий процесс каждый день. Автоматизируйте только ее. Не стройте идеальный пайплайн — сделайте уродливый скрипт, который решает 80% проблемы, но запускается одним кликом. Когда все увидят, что стало легче, дальше пойдет само.
Что в сухом остатке
Весь этот гайд можно свести к одному тезису: в промышленном DevOps скорость — не метрика. Метрика — это предсказуемость. Вы должны точно знать, какой код лежит на каждом устройстве, как он был собран, кто его подписал, какие тесты он прошёл, и как откатить на версию годичной давности, если новые датчики не пришли на склад.
Начинайте с малого. Возьмите один тип контроллера, один стенд, одну прошивку. Автоматизируйте её сборку. Добавьте цифровую подпись. Напишите скрипт, который проверяет подпись перед прошивкой. Это уже победа.
И помните: через пять лет кто‑то будет поддерживать вашу систему. И этот кто‑то скажет спасибо, если ваши прошивки лежат в артефакториуме, а не на забытой флешке в ящике стола уволившегося инженера.

Если хотите продолжить тему DevOps, автоматизации и надежной инфраструктуры, присмотритесь к открытым урокам OTUS. Их бесплатно проводят в рамках онлайн-курсов преподаватели — можно познакомиться с экспертами и задать вопросы.
3 июня, 20:00 — «Internal Developer Platform: self-service-инфраструктура за один вечер». Записаться
Разберем, как упростить работу разработчиков через внутреннюю платформу и self-service-инфраструктуру.4 июня, 20:00 — «Продвинутый Bash». Записаться
Поговорим о скриптах и приемах автоматизации, которые помогают убрать ручную рутину из инженерных процессов.
Больше мероприятий — в календаре уроков OTUS. А еще подписывайтесь на канал OTUS в MAX, чтобы не пропускать новые материалы и анонсы.

















