GH GambleHub

Контейнеризация: Docker и OCI

Контейнеризация: Docker и OCI

1) Базовые понятия и стандарты OCI

OCI Image Spec — формат образов (манифест, конфиг, слои, index для multi-arch).
OCI Runtime Spec — как запускать контейнер (bundle, `config.json`); реализация: runc, а также gVisor, Kata Containers.
OCI Distribution Spec — взаимодействие с реестрами (push/pull, авторизация).

Docker = UX и экосистема вокруг OCI: Dockerfile/BuildKit/CLI/Compose/Hub. В Kubernetes Docker Engine заменен на containerd/CRI-O, но формат образов одинаков.

2) Образы: слои, теги, метаданные

Образ = слои (layered filesystem) + config (entrypoint/cmd/env/labels) + manifest.
Теги: не используйте `:latest` в проде; пинning `:1.21.3`, git-SHA или дата+SHA.
LABEL: владелец, контакт, vcs-url, org.opencontainers. (title, description, revision, source).
Multi-arch: манифест-индекс отдает правильный вариант для `amd64/arm64`.

3) Сборка: Dockerfile, BuildKit, multi-stage

3.1 Принципы

Минимизируйте слои, фиксируйте версии, чистите кеши пакетных менеджеров.
Сначала копируйте manifest/lock-файлы, затем `RUN install deps` — улучшает кэш.
.dockerignore обязателен (исключите `.git`, артефакты, секреты).
Предпочтительны образцы distroless/alpine/минимальные базы.

3.2 BuildKit фишки

Параллельные билды, секреты в сборке (`--secret`), кэш-маунты, buildx для multi-arch.

Пример кэш-маунта:
dockerfile syntax=docker/dockerfile:1. 6
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements. txt

3.3 Multi-stage примеры

Go (statически линкованный, distroless):
dockerfile syntax=docker/dockerfile:1. 6
FROM golang:1. 23 AS build
WORKDIR /src
COPY go. mod go. sum./
RUN go mod download
COPY..
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o /app

FROM gcr. io/distroless/static:nonroot
USER 65532:65532
COPY --from=build /app /app
ENTRYPOINT ["/app"]
Node.js (prod-слой без dev-deps):
dockerfile syntax=docker/dockerfile:1. 6
FROM node:22-alpine AS deps
WORKDIR /app
COPY package. json./
RUN npm ci --omit=dev

FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules./node_modules
COPY..
RUN npm run build

FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules./node_modules
COPY --from=build /app/dist./dist
USER node
CMD ["node","dist/server. js"]
Python (wheel-кеш, non-root):
dockerfile syntax=docker/dockerfile:1. 6
FROM python:3. 12-slim AS base
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
WORKDIR /app

FROM base AS deps
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade pip
COPY requirements. txt.
RUN --mount=type=cache,target=/root/.cache/pip pip wheel --wheel-dir=/wheels -r requirements. txt

FROM base
COPY --from=deps /wheels /wheels
RUN pip install --no-index --find-links=/wheels -r /app/requirements. txt && rm -rf /wheels
COPY..
USER 1000:1000
CMD ["python","-m","app"]
Java (JLink/Layered Spring):
dockerfile syntax=docker/dockerfile:1. 6
FROM maven:3. 9-eclipse-temurin-21 AS build
WORKDIR /src
COPY pom. xml./
RUN mvn -q -e -DskipTests dependency:go-offline
COPY..
RUN mvn -q -DskipTests package

FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /src/target/app. jar /app/app. jar
ENTRYPOINT ["java","-XX:+UseContainerSupport","-jar","/app/app. jar"]

4) Минимальные образы, PID 1 и сигналы

Distroless — меньше поверхность атаки, нет shell/менеджера пакетов.

PID 1 должен корректно проксировать сигналы, иначе «зомби-процессы». Используйте `ENTRYPOINT` в exec-форме и tini/встроенный init:
dockerfile
ENTRYPOINT ["tini","--","/app"]

`HEALTHCHECK` задавайте разумно (частота/таймаут, без лишней нагрузки).

5) Секьюрность контейнеров

5.1 Политики и hardening

Non-root (USER), rootless Docker/containers.
Capabilities: убирайте лишнее (`--cap-drop=ALL --cap-add=NET_BIND_SERVICE` и т. п.).
seccomp/AppArmor/SELinux: включайте профили по умолчанию или строгие.
Read-only FS + `tmpfs` для `/tmp`, no-new-privileges.
Secrets: не в образах; монтируйте из менеджера секретов (K8s/vault/docker secrets).

5.2 Supply chain

SBOM (CycloneDX/SPDX) и сканирование (Trivy/Grype).
Подпись (cosign, sigstore) и политика при pull (verify).
Репетиции обновлений: базовые образы с CVE-патчами регулярно пересобираются.

6) Хранение и файловые драйверы

По умолчанию overlay2 (быстрый и стабильный). В rootless средах часто fuse-overlayfs.
volumes для данных и кэшей, bind-mount для разработки.
Не записывайте в `/` — используйте путь данных (`/data`), отделяйте state от образа.

7) Сеть и DNS

Docker сети: bridge (по умолчанию), host (минимум оверхеда, конфликты портов), none, macvlan/ipvlan (L2/L3 интеграция).
DNS-резолвер Docker берет из хоста/daemon.json; для prod настройте локальные кеш-резолверы.
В K8s сеть управляет CNI (Calico/Cilium/Flannel). Для sidecar/mesh — перехваты (iptables).

8) Ресурсы и QoS (cgroups v2)

Ограничения: `--cpus`, `--memory`, `--pids-limit`, `--cpuset-cpus`.
Устанавливайте requests/limits (в K8s) → влияет на планирование и QoS.
Мониторьте OOMKilled, throttling, latency spikes из-за GC/IO.

Примеры запуска:
bash docker run --cpus=1. 5 --memory=512m --pids-limit=256 --read-only --tmpfs /tmp:rw,size=64m...

9) Логи и наблюдаемость

Драйверы логов: `json-file` (с ротацией), `journald`, `gelf`, `awslogs`, `syslog`.

Настройте ротацию:
json
{ "log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"5"} }

Метрики: Docker Engine API, cAdvisor, node-экспортеры; трассировка через агент в контейнере или sidecar.

10) Регистры и аутентификация

Частные реестры: ECR/GCR/ACR/Harbor/GitHub Container Registry.
Rate-limits Docker Hub; используйте зеркала/кеши (registry-cache).
Политика retention/immutable tags, репликация между регионами.
`docker login` не храните в скриптах; используйте CI-секреты и OIDC-федерацию.

11) docker-compose vs оркестраторы

Compose — локальная разработка/интеграционные стенды.
Прод: Kubernetes (Deployment/StatefulSet/DaemonSet, Ingress, Secrets, PVC) с containerd/CRI-O; политики безопасности и rollout-стратегии.
Swarm устарел для больших продов, годится для простых кластеров.

Пример compose (стенд):
yaml version: "3. 9"
services:
api:
build:.
ports: ["8080:8080"]
environment: ["DB_URL=postgres://pg/DB"]
depends_on: ["pg"]
pg:
image: postgres:16-alpine volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: {} }

12) Healthcheck, старт/стоп, graceful shutdown

Используйте `HEALTHCHECK` с таймаутами и ограничениями по `retries`.
Корректный graceful: ловите SIGTERM, завершайте входящие, закрывайте соединения, затем выход.
В K8s: `preStop` hook + `terminationGracePeriodSeconds`, readiness перед liveness.

13) Best practices по языкам/стекам (сводка)

Node: `npm ci`, `NODE_ENV=production`, выключить dev-deps в runtime, `--heapsnapshot` off, `uWS/GZip` за L7-прокси.
Python: wheels, `gunicorn --graceful-timeout`, `GTHREADS`/`UVICorn` по CPU, не хранить venv внутри общего слоя без нужды.
Go: CGO off (если можно), `-ldflags="-s -w"`, distroless/static, `GOMAXPROCS` по cgroups.
Java: слойный JAR, `-XX:MaxRAMPercentage`, CDS/Layered JAR для кэша.

14) Supply chain и политика образов

Генерите SBOM на CI, сохраняйте рядом с артефактом.
Сканируйте образы на каждом пуше; гейт на критические CVE.
Подписывайте образы (cosign), включите policy controller (в K8s — Kyverno/Conftest/Gatekeeper).
Разделяйте build и run учетки/сети; кэшируйте зависимости в приватном реестре.

15) Анти-паттерны

`:latest` в проде; отсутствие иммутабельных тегов.
Сборка «внутри прод-хоста» без изоляции; хранение секретов в Dockerfile.
Запуск под root, `--privileged`, широкие capabilities.
Толстые образы (>1–2 ГБ), отсутствие.dockerignore.
Логика init в ENTRYPOINT через shell-форму → проблемы с сигналами.
Писать постоянные данные в слой контейнера вместо volume.
Healthcheck, делающий дорогие запросы к прод-БД.

16) Чек-лист внедрения (0–45 дней)

0–10 дней

Стандартизировать Dockerfile (multi-stage,.dockerignore, LABEL, pinned base).
Включить BuildKit/buildx, кэш-маунты для менеджеров пакетов.
Перейти на non-root и `seccomp`/AppArmor/SELinux профили по умолчанию.

11–25 дней

Минимизировать runtime-образы (alpine/distroless), навести порядок с логами (ротация).
Настроить лимиты ресурсов, healthchecks, корректный PID 1/tini.
Поднять приватный реестр/кеш, подключить сканер CVE и генерацию SBOM.

26–45 дней

Ввести подпись образов и политику допуска в кластер.
Организовать multi-arch (amd64/arm64) для нужных сервисов.
Документировать runbook сборки/релиза, отчет по размерам/уязвимостям/времени сборки.

17) Метрики зрелости

Иммутабельные теги и воспроизводимые сборки для ≥ 95% сервисов.
Средний размер runtime-образа < 200–300 МБ (по стеку).
100% prod-контейнеров — non-root, с ограниченными capabilities и read-only FS.
SBOM и сканирование CVE на каждый push; критичные CVE → блокируются.
Подпись образов и policy-enforcement в окружениях.
Время холодного старта контейнера ≤ целевого SLO (напр., 2–5 сек), корректный graceful shutdown.

18) Заключение

Контейнеризация по-взрослому — это стандарты OCI + дисциплина сборки + безопасность по умолчанию + наблюдаемость и политика поставки. Используйте multi-stage и BuildKit, минимизируйте runtime-образы, запускайте non-root под строгими профилями, фиксируйте теги, сканируйте и подписывайте, держите логи/ресурсы/сеть под контролем. Так контейнеры станут предсказуемой и управляемой основой вашей платформы — от девелопмента до продакшена.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Telegram
@Gamble_GC
Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.