Рецепт 23. Управление расширениями через ImageVolume в CloudNativePG

Реальная практика того, что обещали в «Иммутабельном будущем расширений»: PostgreSQL 18 + Kubernetes ImageVolume + CloudNativePG 1.27. Расширения — отдельные OCI-образы (pgvector ~613KB), монтируются в минимальный operand (260MB) без пересборки. Полный пример с pgvector и PostGIS.
Опубликовано:

То, о чём писали в «Иммутабельном будущем расширений» ещё в марте 2025 — теперь полностью работает. PostgreSQL 18 + Kubernetes 1.33 (ImageVolume) + CloudNativePG 1.27 позволяют поставлять расширения отдельными лёгкими OCI-образами, монтируя их в минимальный operand-образ Postgres без пересборки кастомного Docker-image.

«Прощайте, времена, когда расширения Postgres приходилось паковать в основной operand-образ.»

Предусловия

На локальном kind-кластере feature gate надо включить явно при создании кластера.

Стартуем с минимальным CNPG-кластером

Базовый minimal-образ PostgreSQL 18 — 260 МБ (ровно core, без расширений, см. статью про PG 18).

YAML
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: angus
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
  instances: 1
  storage:
    size: 1Gi
Нажмите, чтобы развернуть и увидеть больше

Подключаем pgvector отдельным образом

Главная фишка — новый блок postgresql.extensions. Вместо переключения на тяжёлый кастомный образ — монтируем отдельный extension-образ. Образ pgvector весит всего 613 КБ.

Манифест

YAML
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: angus
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
  instances: 1
  storage:
    size: 1Gi
  postgresql:
    extensions:
    - name: pgvector
      image:
        reference: ghcr.io/cloudnative-pg/pgvector:0.8.1-18-trixie
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
  name: angus-app
spec:
  name: app
  owner: app
  cluster:
    name: angus
  extensions:
  - name: vector
    version: '0.8.1'
Нажмите, чтобы развернуть и увидеть больше

Проверка

Что лежит в смонтированном volume:

BASH
kubectl exec -ti angus-1 -c postgres -- ls /extensions/
Нажмите, чтобы развернуть и увидеть больше

Ожидаем:

PLAINTEXT
pgvector
Нажмите, чтобы развернуть и увидеть больше

Что в БД:

BASH
kubectl cnpg psql angus -- app -c '\dx'
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
                                          List of installed extensions
  Name   | Version | Default version |   Schema |                  Description
---------+---------+-----------------+----------+------------------------------------------------------
 plpgsql | 1.0     | 1.0             | pg_catalog | PL/pgSQL procedural language
 vector  | 0.8.1   | 0.8.1           | public     | vector data type and ivfflat and hnsw access methods
(2 rows)
Нажмите, чтобы развернуть и увидеть больше

Что мы здесь сделали

Три ключевых вещи:

  1. Регистрация на уровне кластера. Блок postgresql.extensions ссылается на конкретный extension-образ с скомпилированными бинарями.
  2. Монтирование через ImageVolume. Оператор сам монтирует содержимое extension-образа в файловую систему Postgres-пода (read-only) — и подкручивает PostgreSQL 18-овский extension_control_path.
  3. Декларативная активация. Ресурс Database.spec.extensions отвечает за CREATE EXTENSION. Поле version позволяет оператору рулить апгрейд-путями (ALTER EXTENSION ... UPDATE TO ...).

Сравните с обычным деплоем pgvector через ресурс Database (без отдельного образа) — Рецепт 18.

Несколько сложных расширений: PostGIS

Настоящая сила подхода видна на сложных расширениях вроде PostGIS, которому нужны companion-расширения и shared library dependencies.

YAML
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: angus
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
  instances: 1
  storage:
    size: 1Gi
  postgresql:
    extensions:
    - name: pgvector
      image:
        reference: ghcr.io/cloudnative-pg/pgvector:0.8.1-18-trixie
    - name: postgis
      image:
        reference: ghcr.io/cloudnative-pg/postgis-extension:3.6.1-18-trixie
      ld_library_path:
      - system
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
  name: angus-app
spec:
  name: app
  owner: app
  cluster:
    name: angus
  extensions:
  - name: vector
    version: '0.8.1'
  - name: postgis
    version: '3.6.1'
  - name: postgis_raster
  - name: postgis_sfcgal
  - name: fuzzystrmatch
  - name: address_standardizer
  - name: address_standardizer_data_us
  - name: postgis_tiger_geocoder
  - name: postgis_topology
Нажмите, чтобы развернуть и увидеть больше

Конфигурация ld_library_path важна: PostGIS требует правильного пути для динамического линкера.

Что в итоге

Подход с ImageVolume в CloudNativePG 1.27+ даёт:

Репозиторий postgres-extensions-containers занимается стандартизацией создания extension-образов. Цель — расширять список поддерживаемых расширений через сообщество, превращая его участников в extension-мейнтейнеров.

См. также:

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша