Линковка образов вглубь

Уровень: expert ~45 мин Практика: Vikunja (продолжение M3/M4) (AGPL-3.0)

Что нужно знать перед уроком

  • 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
project: my-app
configVersion: 1
---
image: auth
dockerfile: Dockerfile.auth
context: ./auth
---
image: controlplane
dockerfile: Dockerfile.controlplane
context: ./controlplane
---
image: app
dockerfile: Dockerfile
context: .
dependencies:
  - image: auth
    imports:
      - type: ImageDigest
        targetBuildArg: AUTH_IMAGE_DIGEST
      - type: ImageName
        targetBuildArg: AUTH_IMAGE_NAME
  - image: controlplane
    imports:
      - type: ImageDigest
        targetBuildArg: CONTROLPLANE_IMAGE_DIGEST
      - type: ImageName
        targetBuildArg: CONTROLPLANE_IMAGE_NAME

Итоговый 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), а не к состоянию кластера.

Практика разработки

🧩 Практика урока: Vikunja (продолжение M3/M4) · лицензия AGPL-3.0

Добавьте в werf.yaml пакета Vikunja третий образ notifications-worker (заглушка, использующая тот же базовый образ, что и API), и настройте передачу его ImageName+ImageDigest в основной образ api через dependencies/imports, аналогично примеру auth+controlplaneapp из теории.

Шпаргалка команд урока

1
2
werf config render --require-built-images .    # проверить итоговую конфигурацию с учётом dependencies
werf config graph                               # напечатать граф зависимостей образов (dependsOn/import) без сборки

Полная сводная таблица — 📋 werf .

Вопросы для самопроверки

Какой тип import гарантированно меняется при любом изменении содержимого зависимого образа, вызывая корректную инвалидацию кэша?

ImageTag может оставаться неизменным (например, :latest) при изменении содержимого, ImageDigest — нет.

Источник: Werf — документация — типы import

Может ли один образ получать imports от НЕСКОЛЬКИХ независимых образов одновременно?

Это паттерн для приложений с несколькими логически связанными, но самостоятельно собираемыми компонентами.

Источник: Werf — документация — паттерн нескольких независимых образов

Нужно ли объявлять ARG в Dockerfile для каждого targetBuildArg из werf.yaml?

werf.yaml лишь передаёт значение — сам Dockerfile должен ожидать этот аргумент через ARG.

Источник: Werf — документация — targetBuildArg

Сколько записей в imports нужно, чтобы передать и имя, и дайджест одного и того же образа?

Каждый import — это отдельная пара тип+целевой аргумент.

Источник: Werf — документация — структура imports

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Nigel Poulton. Docker Deep Dive. 2023. ISBN 978-1916585206.

Связанные материалы