Files
airflow-greenplum/plans/greenplum-pxf-custom-image-plan.md
T

9.6 KiB
Raw Blame History

План работ: свой образ Greenplum с интегрированным PXF

Контекст и проблема

Иногда (и у нас воспроизводится стабильно) контейнер greenplum падает при старте с ошибкой:

chown: changing ownership of '/docker-entrypoint-initdb.d/10_pxf_bookings.sh': Read-only file system

Причина: init-скрипт pxf/init/10_pxf_bookings.sh проброшен в контейнер как bind-mount :ro, а entrypoint базового образа пытается сделать chown файлов в /docker-entrypoint-initdb.d/.

Цели

  • Greenplum стабильно стартует после любого restart/up (без “иногда не стартует”).
  • PXF готов к работе после каждого запуска контейнера.
  • Не меняем права/владельца файлов в репозитории на хосте (никаких “файл стал root’ом / не редактируется”).
  • Для студентов всё остаётся простым: make build (явная сборка) + make up (поднимает стенд; если образа нет — Docker Compose соберёт сам).

Выбранный подход (высокоуровневый дизайн)

  1. Делаем свой образ Greenplum на базе woblerr/greenplum:6.27.1.

  2. Встраиваем в образ “seed” для PXF:

    • JDBC-драйвер (JAR),
    • конфиг сервера bookings-db (jdbc-site.xml),
    • скрипт “ensure”, который идемпотентно гарантирует, что файлы лежат в PXF_BASE (на persistent volume).
  3. Запускаем “ensure” на каждом старте контейнера через wrapper-entrypoint, а затем передаём управление оригинальному entrypoint базового образа.

  4. PXF_BASE по умолчанию остаётся на volume (/data/pxf), чтобы настройки переживали рестарты.

План работ (по шагам)

Шаг 1. Разведка базового образа

  • Проверить, где находится оригинальный entrypoint и как он запускается (путь, параметры, пользователь).
  • Понять, как GREENPLUM_PXF_ENABLE=true влияет на старт (чтобы wrapper не ломал поведение).

Результат: фиксируем в README “как устроен старт” (1–2 абзаца).

Шаг 2. Новый Dockerfile для Greenplum

  • Добавить Dockerfile.greenplum:
    • FROM woblerr/greenplum:6.27.1
    • COPY seed-артефакты в образ (например, в /opt/pxf-seed/...)
    • COPY wrapper-entrypoint в образ
    • настроить права/владельца внутри образа так, чтобы старт был без ошибок

Результат: образ собирается локально через make build и/или автоматически через make up.

Шаг 3. Wrapper-entrypoint (каждый старт)

  • Добавить скрипт entrypoint-обёртки (например, greenplum/entrypoint-wrapper.sh или pxf/entrypoint-wrapper.sh):
    • на старте вызывает ensure-скрипт;
    • затем делает exec оригинального entrypoint базового образа с теми же аргументами.

Важно: wrapper не должен “перехватывать” логику инициализации кластера — только добавлять шаг подготовки PXF.

Шаг 4. Переписать текущий init-скрипт в “ensure” (идемпотентный)

  • Превратить pxf/init/10_pxf_bookings.sh в скрипт, который можно безопасно выполнять на каждом запуске:
    • не опираться на ~/.bashrc;
    • PXF_BASE вычислять через env (PXF_BASE, GREENPLUM_DATA_DIRECTORY, fallback /data/pxf);
    • seed-копирование делать “если файла нет”;
    • добавить понятные логи (что сделано / что пропущено);
    • pxf cluster sync:
      • выполнять, только если команда доступна,
      • не валить контейнер при ошибке (но писать предупреждение).

Дополнительно (опционально, но полезно для стенда):

  • env-переключатель PXF_SEED_OVERWRITE=1 — принудительно перезаписывать конфиг из образа в volume (для обновлений без удаления volume).

Шаг 5. Обновить docker-compose.yml

  • Для сервиса greenplum перейти на build: (и при желании оставить image: как тег).
  • Убрать bind-mount’ы PXF (jar/config/init-скрипт), т.к. теперь всё в образе.
  • Оставить greenplum_data:/data и ./sql:/sql:ro.
  • Исправить healthcheck Greenplum (сейчас конструкция вида ... || echo 1 делает healthcheck “вечно успешным”):
    • healthcheck должен возвращать ненулевой код, если БД не готова;
    • добавить start_period, чтобы не ловить ложные падения на холодном старте.

Шаг 6. Обновить Makefile и README

  • Makefile:
    • убедиться, что make build собирает также Greenplum-образ (если введём build для сервиса);
    • оставить make up как есть (Compose сам соберёт образ, если его нет).
  • README.md:
    • зачем свой образ (устойчивость, права на хосте, меньше mount’ов),
    • как пересобрать образ,
    • как обновить PXF-конфиг (через rebuild + PXF_SEED_OVERWRITE=1 или через очистку volume).

Проверка и критерии готовности

  • docker compose up -d greenplum → контейнер остаётся Up, не падает.
  • docker compose restart greenplum повторить 10–20 раз → без падений.
  • Healthcheck Greenplum становится healthy (не “вечно healthy” и не “вечно starting”).
  • Поднятие всего стека (make up) приводит к старту Airflow (scheduler/webserver), т.к. depends_on: condition: service_healthy начинает работать корректно.

Риски и как их снизить

  • Стартап может замедлиться, если pxf cluster sync делать каждый раз: поэтому скрипт должен быть быстрым, а sync — не фатальным при ошибках.
  • Обновление конфигов: так как PXF_BASE на volume, изменения в образе сами не перетрут файлы — поэтому нужен PXF_SEED_OVERWRITE=1 или понятная инструкция “как обновить”.

Откат

  • Вернуться к использованию image: woblerr/greenplum:6.27.1 в docker-compose.yml.
  • Вернуть mount’ы PXF, если нужно (но это вернёт риск с :ro).

Статус (реализовано)

  • Добавлен кастомный образ Greenplum: Dockerfile.greenplum (seed PXF + startup wrapper).
  • Ensure‑скрипт перенесён в образ и стал идемпотентным: pxf/init/10_pxf_bookings.sh.
  • Стартовый скрипт контейнера включает ensure и создаёт EXTENSION pxf: pxf/init/start_greenplum_with_pxf.sh.
  • В docker-compose.yml:
    • greenplum собирается через build: Dockerfile.greenplum;
    • добавлен hostname: gpdbsne;
    • убраны PXF bind-mount’ы (jar/config/init);
    • healthcheck ждёт не только GPDB, но и готовность PXF.
  • Обновлены инструкции: README.md, .env.example.
  • Проблема с генератором demodb (пустая bookings.bookings) зафиксирована в TODO.md.

Проверка (как воспроизвести)

Команды для ручной проверки:

  • Пересобрать и перезапустить Greenplum:
    • make build
    • docker compose up -d --force-recreate greenplum
  • 310 рестартов:
    • docker compose restart greenplum
    • дождаться healthy в docker compose ps
  • Проверить PXF:
    • docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/pxf/bin/pxf cluster status'"
  • Проверить DAG, который использует PXF:
    • docker exec -i gp_airflow_scheduler airflow dags test bookings_stg_ddl

Текущий результат:

  • bookings_stg_ddl проходит (PXF и protocol pxf доступны).
  • bookings_to_gp_stage падает не из-за PXF, а из-за пустого источника (demo.bookings.bookings = 0 строк). Это отдельная задача (см. TODO.md).