Линковка образов вглубь
Что нужно знать перед уроком
- M3.04 — Линковка образов — нужна базовая модель dependencies/imports и targetBuildArg перед углублением
Что нужно знать перед уроком
M3 урок 4 — базовая модель линковки образов через dependencies/imports. Этот урок открывает M8 — модуль, посвящённый продвинутым техникам Werf, которые не нужны на старте, но становятся критичными по мере роста сложности пакета Application.
Теория
Четыре типа передаваемой информации: ImageName/ImageTag/ImageRepo/ImageDigest
В M3 уроке 4 рассматривался ImageDigest — самый частый случай (передать неизменяемую ссылку на образ). Полный список типов, которые можно передать через targetBuildArg:
| Тип | Что передаётся | Когда использовать |
|---|---|---|
ImageName | Полное имя образа (registry/repo:tag или по дайджесту) | Когда Dockerfile сам решает, как использовать образ (например, как base image в multi-stage) |
ImageTag | Только тег образа | Редко — когда важен именно человекочитаемый тег, а не полный путь |
ImageRepo | Путь к репозиторию без тега | Когда Dockerfile собирает полное имя самостоятельно, комбинируя с собственным тегом |
ImageDigest | Неизменяемый content-based дайджест | Наиболее частый случай — гарантия, что при пересборке зависимого образа перестроится и тот, что от него зависит |
Паттерн: несколько независимых образов передают данные в общий сборочный контекст
Реальный пример из документации Werf — сценарий, где auth и controlplane (два независимых, самостоятельно собираемых образа) оба передают своё имя и дайджест в третий, общий образ app:
| |
Итоговый Dockerfile образа app получает четыре build-аргумента одновременно — по два (имя + дайджест) от каждого из двух независимых образов. Это позволяет, например, встроить в конфигурацию app полные ссылки на образы auth/controlplane, которые сам app будет запускать как sidecar-процессы или к которым будет обращаться напрямую по полному имени.
Где это нужно в Application с несколькими компонентами
Для Application, состоящего из нескольких логически связанных, но независимо собираемых компонентов (например, основное приложение + отдельный воркер очереди задач, как в реальных пакетах вроде Vikunja, где есть API-сервер и опциональный отдельный воркер уведомлений), этот паттерн решает задачу «главный компонент должен знать, как называется и где лежит образ вспомогательного компонента» — критично, если, например, Deployment главного приложения генерирует манифест CronJob для воркера прямо в своих шаблонах Helm, и имя образа воркера должно быть согласовано на уровне сборки, а не только на уровне values.yaml.
Частые ошибки и подводные камни
- Передавать
ImageNameвместоImageDigestтам, где нужна гарантия пересборки при изменении зависимого образа.ImageNameможет содержать мутабельный тег (например,:latest) — изменение содержимого образа под тем же тегом не вызовет автоматическую пересборку зависимого образа.ImageDigest, будучи неизменяемым отпечатком содержимого, гарантированно меняется при любом изменении зависимого образа, что запускает корректную инвалидацию кэша. - Забывать, что каждый
import— это отдельная запись в списке, даже если они относятся к одному и тому же образу. Если нужно передать и имя, и дайджест одного и того же образа, требуются два отдельных элементаimportsс разнымиtypeиtargetBuildArg. - Не объявлять
ARGв самомDockerfileдля каждогоtargetBuildArg. Простое указаниеtargetBuildArg: AUTH_IMAGE_DIGESTвwerf.yamlне создаёт автоматически соответствующийARG AUTH_IMAGE_DIGESTвDockerfile— это по-прежнему обычный Docker build-аргумент, который должен быть объявлен явно.
Практика в кластере
Практики в кластере в этом уроке нет — материал относится к стадии сборки (Werf), а не к состоянию кластера.
Практика разработки
Добавьте в werf.yaml пакета Vikunja третий образ notifications-worker (заглушка, использующая тот же базовый образ, что и API), и настройте передачу его ImageName+ImageDigest в основной образ api через dependencies/imports, аналогично примеру auth+controlplane→app из теории.
Шпаргалка команд урока
| |
Полная сводная таблица — 📋 werf .
Вопросы для самопроверки
ImageTag может оставаться неизменным (например, :latest) при изменении содержимого, ImageDigest — нет.
Источник: Werf — документация — типы import
Это паттерн для приложений с несколькими логически связанными, но самостоятельно собираемыми компонентами.
Источник: Werf — документация — паттерн нескольких независимых образов
werf.yaml лишь передаёт значение — сам Dockerfile должен ожидать этот аргумент через ARG.
Источник: Werf — документация — targetBuildArg
Каждый import — это отдельная пара тип+целевой аргумент.
Источник: Werf — документация — структура imports
Рекомендуемая литература
Официальная документация
Статьи и блоги
- Вышла werf 2.0: новый движок развёртывания Nelm — Flant на Habr.
- werf v1.2 — Stapel и инкрементальная сборка — Flant на Habr.
- GitLab + K8s + Werf — Habr.
Книги
- Nigel Poulton. Docker Deep Dive. 2023. ISBN 978-1916585206.
Связанные материалы
- Предыдущий модуль: M7.09 — Четыре известных подводных камня.
- Следующий урок: M8.02 — Cache-репозитории.
✓ Урок пройден — все вопросы самопроверки отвечены верно