Секция distroless в info.yaml

Общие поля info.yaml описаны в разделе Формат спецификаций в org. Здесь перечислены только поля секции distroless, которые управляют сборкой минимального rootfs.

Наличие секции distroless включает DistrolessImage во всех организациях, кроме org/k8s-core.

from

Финальный базовый образ:

distroless:
  from: "{{ registry }}{{ branch }}/distroless-base:latest"

Если from не задан, используется scratch.

Примеры:

  • scratch в distroless-static;
  • distroless-static в distroless-base;
  • distroless-base в distroless-cc, distroless-gotop, distroless-devel;
  • distroless-cc в distroless-python3.

builder.reinstall_packages

Пакеты, которые надо установить в builder-стадии перед сборкой rootfs:

distroless:
  builder:
    reinstall_packages:
      - gotop

Renderer превращает это в apt-get install -y ....

Несмотря на имя reinstall_packages, текущий renderer вызывает apt-get install, а не apt-get reinstall. Название поля сохраняет исторический смысл: обеспечить наличие свежих файлов пакетов в builder-стадии.

builder.install_packages

Поле встречается в distroless-builder и distroless-busybox, но стандартный helper distroless_reinstall() его не использует. Эти образы имеют custom Dockerfile.template, который сам вызывает обычный helper install_packages(...).

Для нового стандартного distroless-образа обычно используйте builder.reinstall_packages.

rootfs.files

Добавляет конкретные файлы в rootfs:

rootfs:
  files:
    - /bin/true

Symlink'и по умолчанию разворачиваются с учётом назначения. Для библиотек бинарника это поле не подходит: используйте library_files или full_files.

rootfs.library_files

Добавляет указанные файлы и библиотеки, найденные через ldd:

rootfs:
  library_files:
    - /usr/bin/vim

Если бинарник статический или ldd не может его обработать, сборка упадёт. Для таких файлов используйте files.

rootfs.full_files

Удобное сокращение: файл попадёт и в files, и в library_files.

rootfs:
  full_files:
    - /usr/bin/python3

Это нужно для динамически связанных исполняемых файлов: сам бинарник попадёт в rootfs, а его runtime libraries будут найдены через ldd.

rootfs.packages

Добавляет обычные файлы из rpm-пакетов:

rootfs:
  packages:
    - glibc-core
    - tzdata

rootfs.packages нужен, когда нужно забрать из rpm-пакета обычные runtime-файлы целиком, а не перечислять их вручную. Это удобно для пакетов, где важны не один-два бинарника, а набор данных, конфигов, сертификатов, Python-модулей, timezone-файлов, metadata и т.п.

Разница такая:

  • rootfs.files - забрать конкретные файлы. Пример: /bin/true, /etc/localtime.
  • rootfs.library_files - забрать указанный бинарник/файл и библиотеки, которые нужны ему по ldd. Пример: /usr/bin/gotop.
  • rootfs.packages - забрать обычные файлы из перечисленных rpm-пакетов. Это шире и грубее, зато надёжнее для runtime-пакетов со множеством связанных файлов.
  • rootfs.full_files - короткая запись для динамического исполняемого файла: указанный путь одновременно попадает в rootfs.files и в rootfs.library_files. В результате в rootfs попадает сам файл и библиотеки, которые нужны ему по ldd.

Например, для distroless-python3 rootfs.packages оправдан: Python runtime это не только /usr/bin/python3 и .so из ldd. Нужны стандартная библиотека, Python modules, CA/cert files и runtime data. Перечислять это вручную через files было бы хрупко.

Для distroless-true наоборот rootfs.packages не нужен: достаточно одного /bin/true, и библиотеки не нужны.

Практическое правило:

  • один бинарник или один конфиг -> rootfs.files;
  • бинарник с динамическими библиотеками -> rootfs.library_files;
  • runtime-пакет с деревом файлов -> rootfs.packages;
  • distroless-слой, где пакет целиком и есть смысл слоя -> rootfs.packages.

rootfs.library_packages

Добавляет пакеты, которым принадлежат библиотеки указанных бинарников:

rootfs:
  library_packages:
    - /usr/bin/my-binary

Это специализированный механизм. Он вызывает ldd, затем rpm -qf для найденных библиотек.

rootfs.timezone

Создаёт /etc/localtime в builder-стадии и добавляет его в rootfs:

rootfs:
  timezone: Europe/Moscow

Так сделан distroless-base.

env

Рендерится в ENV:

env:
  LANG: C.UTF-8
  SSL_CERT_FILE: /etc/pki/tls/certs/ca-bundle.crt

user

Рендерится в USER:

user: nonroot

Пользователь должен существовать в rootfs или базовом образе. В цепочке flowforge пользователь nonroot создаётся в distroless-builder и попадает в distroless-static.

workdir и workingdir

Оба имени поддерживаются. Рендерятся в WORKDIR:

workdir: /home/nonroot

entrypoint

JSON ENTRYPOINT финального образа:

entrypoint:
  - /usr/bin/python3

cmd

JSON CMD финального образа:

cmd:
  - /bin/bash

Для distroless-образов shell-form использовать нельзя, если shell не добавлен в rootfs явно.