Примеры из org/base
Этот раздел показывает, какие паттерны уже используются в org/base.
distroless-static
distroless-static строится от scratch и задаёт самый маленький базовый rootfs:
binary_packages:
source_images:
- base/distroless-builder
distroless:
from: scratch
rootfs:
files:
- /bin
- /etc
- /usr
- /var
# в оригинальном файле список файлов намного длиннее
user: nonroot
workdir: /home/nonroot
Главная идея: rootfs задаётся минимальным набором каталогов и системных файлов. Этот образ подходит для статически связанных программ или как основа для образов, которым не нужен glibc runtime.
distroless-base
distroless-base добавляет динамический runtime:
binary_packages:
- glibc-core
- glibc-pthread
- glibc-timezones
- libselinux
- libssl3
- tzdata
- zlib
source_images:
- base/distroless-builder
- base/distroless-static
distroless:
from: "{{ registry }}{{ branch }}/distroless-static:latest"
rootfs:
packages:
- glibc-core
- glibc-pthread
- glibc-timezones
- tzdata
- zlib
timezone: Europe/Moscow
Здесь появляется важный паттерн: binary_packages может быть шире, чем rootfs.packages.
Часть пакетов нужна для отслеживания обновлений и builder-стадии, но в rootfs может попадать
только выбранный набор файлов.
distroless-cc
distroless-cc добавляет C/C++ runtime-пакеты целиком:
В этом и следующем примере используется сокращение @binary_packages; его смысл описан в
формате спецификаций.
binary_packages:
- libgcc1
- libgomp1
- libstdc++6
source_images:
- base/distroless-builder
- base/distroless-base
distroless:
from: "{{ registry }}{{ branch }}/distroless-base:latest"
builder:
reinstall_packages: "@binary_packages"
rootfs:
packages: "@binary_packages"
Это хороший шаблон для runtime-слоя, где нужно добавить несколько rpm-пакетов целиком.
distroless-python3
Python runtime строится поверх distroless-cc:
binary_packages:
- ca-certificates
- ca-trust
- python3
- python3-base
- python3-modules-curses
- python3-modules-sqlite3
- libpython3
source_images:
- base/distroless-builder
- base/distroless-cc
distroless:
from: "{{ registry }}{{ branch }}/distroless-cc:latest"
builder:
reinstall_packages: "@binary_packages"
rootfs:
full_files:
- /usr/bin/python3
library_files:
- /usr/lib64/python3*/lib-dynload/*.so
packages: "@binary_packages"
env:
LANG: C.UTF-8
SSL_CERT_FILE: /etc/pki/tls/certs/ca-bundle.crt
user: nonroot
workdir: /home/nonroot
entrypoint:
- /usr/bin/python3
Здесь используются сразу три механизма rootfs:
full_filesдля/usr/bin/python3;library_filesдля Python extension modules;packagesдля файлов из runtime-пакетов, перечисленных вbinary_packages.
Dockerfile дополнительно создаёт symlink /usr/bin/python -> python3, если его нет.
distroless-gotop
Простой пример динамического бинарника:
binary_packages:
- gotop
source_images:
- base/distroless-builder
- base/distroless-base
distroless:
from: "{{ registry }}{{ branch }}/distroless-base:latest"
builder:
reinstall_packages:
- gotop
rootfs:
full_files:
- /usr/bin/gotop
entrypoint:
- /usr/bin/gotop
Для похожих утилит это один из лучших стартовых шаблонов.
distroless-devel
distroless-devel не является минимальным runtime. Это отладочный образ:
distroless:
from: "{{ registry }}{{ branch }}/distroless-base:latest"
rootfs:
full_files:
- /bin/bash
- /usr/bin/curl
- /usr/bin/gdb
files:
- /etc/alternatives/links/*
- /usr/bin/vim
library_files:
- /usr/bin/vim
- /usr/bin/ss
packages:
- coreutils
- findutils
- glibc-utils
- iproute2
cmd:
- /bin/bash
Используйте этот образ как пример, когда нужен shell, диагностика и инструменты. Не копируйте его как базу для production runtime без необходимости.
distroless-busybox
distroless-busybox отличается от стандартных distroless-образов. В нём есть секция
distroless, но Dockerfile написан вручную:
FROM {{ registry }}{{ branch }}/{{ alt_image }}:latest AS prepare
{{ install_packages("busybox") }}
RUN mkdir -p /rootfs/usr/bin && \
cp -aL /usr/bin/busybox /rootfs/usr/bin/busybox && \
/usr/bin/busybox --list | while read -r applet; do \
[ "$applet" != busybox ] || continue; \
ln -sf busybox "/rootfs/usr/bin/$applet"; \
done
FROM {{ registry }}{{ branch }}/distroless-base:latest
COPY --from=prepare /rootfs /
CMD ["/usr/bin/sh"]
Такой подход допустим, если helper'ов DistrolessImage недостаточно. Но для новых образов
сначала попробуйте стандартный шаблон с distroless_add().
Образы вне org/base на базе distroless
Не все образы, которые используют distroless runtime, обязаны создаваться через
DistrolessImage. Например org/k8s-extra/kube-rbac-proxy может оставаться обычным
AltImage, если в info.yaml нет секции distroless, но финальная стадия его Dockerfile
наследуется от distroless-base:
FROM {{ registry }}{{ branch }}/{{ alt_image }}:latest AS prepare
{{ install_packages("kube-rbac-proxy") }}
RUN mkdir -p /rootfs/usr/bin && cp -aL /usr/bin/kube-rbac-proxy /rootfs/usr/bin/kube-rbac-proxy
FROM {{ registry }}{{ branch }}/distroless-base:latest
COPY --from=prepare /rootfs /
ENTRYPOINT ["/usr/bin/kube-rbac-proxy"]
В info.yaml это фиксируется через source_images:
target_package: kube-rbac-proxy
binary_packages:
- kube-rbac-proxy
source_images:
- alt
- base/distroless-base
Такой способ подходит, если образу достаточно вручную скопировать несколько файлов из
prepare-стадии. Если нужен автоматический сбор rootfs по rpm-пакетам, ldd, ENV, USER,
WORKDIR, ENTRYPOINT и CMD из info.yaml, добавьте секцию distroless и используйте
renderer DistrolessImage.