본문 바로가기
WIKI 기술 지식 베이스

PostGIS

원문 보기 위키 갱신

PostGIS는 매우 인기 있는 PostgreSQL 오픈소스 확장으로, 데이터베이스에 GIS(Geographic Information Systems) 객체를 저장하고 SQL로 조회할 수 있게 해줘요. CloudNativePG에서 PostGIS 데이터베이스를 가진 PostgreSQL 클러스터를 만드는 방법(이미지 볼륨 확장 / PostGIS 오퍼랜드 이미지)을 알려 드릴게요.

출처: 문서

본문

PostGIS는 PostgreSQL용으로 매우 인기 있는 오픈소스 확장으로, 데이터베이스에 GIS(Geographic Information Systems) 객체를 저장하고 SQL로 조회할 수 있게 해줘요.

:::info[Important] 이 섹션은 PostGIS에 익숙하다고 가정하며, CloudNativePG를 통해 Kubernetes에서 PostGIS 데이터베이스를 가진 새 PostgreSQL 클러스터를 만드는 방법에 대한 몇 가지 기본 정보를 제공해요. :::

지원되는 설치 방법 (Supported Installation Methods)

환경(PostgreSQL 버전, Kubernetes 버전, CloudNativePG 버전)에 따라 PostGIS를 프로비저닝하는 두 가지 주요 방법이 있어요:

  1. 이미지 볼륨 확장 (Image Volume Extensions): 확장 바이너리를 OCI 이미지에서 읽기 전용 볼륨으로 직접 마운트해요 (PG 18+ 및 Kubernetes 1.35+ 권장).

  2. PostGIS 오퍼랜드 이미지 (PostGIS Operand Images): PostGIS 라이브러리를 이미 포함한 사전 빌드된 PostgreSQL 이미지를 사용해요.

아래 방법 중 하나로 시스템에 PostGIS를 프로비저닝한 후에도, 데이터베이스 안에서 확장을 활성화하고 관리해야 해요 (아래 "확장 활성화" 섹션 참고).

방법 1: 이미지 볼륨 확장 (Image Volume Extensions)

PostgreSQL 18 및 Kubernetes 1.35부터 (ImageVolume 기능 게이트가 활성화된 1.33과 1.34 포함) 이미지 볼륨 확장을 활용할 수 있어요.

이는 확장을 관리하는 현대적인 방법이에요. 공식 최소 PostgreSQL 이미지를 사용하면서 런타임에 PostGIS를 "플러그 인"할 수 있고, 확장의 OCI 이미지 내용을 읽기 전용 볼륨으로 Postgres 컨테이너에 직접 마운트할 수 있기 때문이에요. 이렇게 하면 확장 수명 주기를 기본 PostgreSQL 이미지에서 분리해서 오퍼랜드 이미지를 가볍고 안전하게 유지할 수 있어요.

CloudNativePG 커뮤니티는 postgres-extensions-containers 리포지토리를 통해 PostGIS용 독립 확장 컨테이너 이미지를 배포해요.

이미지 카탈로그를 통한 방법 (CloudNativePG 1.29+용)(Via an image catalog)

CloudNativePG 1.29부터 이미지 볼륨 확장과 함께하는 이미지 카탈로그를 활용해 이 버전들의 관리를 자동화할 수 있어요.

PostgreSQL 클러스터에 확장을 추가하는 방법은 이미지 볼륨 확장 페이지를 참고하고, 반드시 postgis 키를 사용하세요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-postgis
spec:
  # ... <snip>
  imageCatalogRef:
    apiGroup: postgresql.cnpg.io
    kind: ClusterImageCatalog
    name: postgresql-minimal-trixie
    major: 18

  postgresql:
    extensions:
      # ... <snip>
      - name: postgis
      # ... <snip>

Cluster 리소스에서 직접

다음 예시는 PostgreSQL 18 클러스터에 PostGIS 3.6.2를 추가하는 방법을 보여주며, Cluster 리소스에서 직접 확장을 로드해요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-postgis
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:18.6-minimal-trixie
  instances: 1

  storage:
    size: 1Gi

  postgresql:
    extensions:
    - name: postgis
      image:
        reference: ghcr.io/cloudnative-pg/postgis-extension:3.6.2-18-trixie
      ld_library_path:
      - system

:::note 이 확장의 최신 버전과 지침은 postgres-extensions-containers 프로젝트를 참고해 주세요. :::

방법 2: PostGIS 오퍼랜드 이미지 (PostGIS Operand Images)

전용 postgis-containers 레지스트리를 계속 사용하고 싶은 사용자, 또는 이미지 볼륨 확장을 지원하지 않는 이전 버전의 PostgreSQL이나 Kubernetes를 사용하는 사용자를 위해, 커뮤니티는 PostGIS가 미리 설치된 이미지를 계속 유지 관리해요 ((PostgreSQL Container images 위에 빌드됨).

자세한 내용은 아래를 참고해 주세요:

이 방법을 사용하려면 .spec.imageName을 원하는 PostGIS-활성화 이미지로 지정하세요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-postgis
spec:
  instances: 1
  imageName: ghcr.io/cloudnative-pg/postgis:18.6-3.6.2-system-trixie
  storage:
    size: 1Gi

확장 활성화 (Enabling the Extension)

바이너리가 (위 두 방법 중 하나로) 프로비저닝되면 데이터베이스에서 확장을 활성화해야 해요.

Database 리소스를 사용하면 버전 업그레이드를 포함한 확장 수명 주기의 선언적 관리를 할 수 있어요.

:::info 자세한 내용은 "데이터베이스에서 확장 관리하기" 섹션을 참고해 주세요. :::

apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
  name: cluster-postgis-app
spec:
  name: app
  owner: app
  cluster:
    name: cluster-postgis
  extensions:
  - name: postgis
    version: '3.6.2'
  - name: postgis_raster
  - name: postgis_sfcgal
  - name: fuzzystrmatch
  - name: address_standardizer
  - name: address_standardizer_data_us
  - name: postgis_tiger_geocoder
  - name: postgis_topology

:::tip extensions 스탠자에서 version을 지정하는 것을 적극 권장해요. CloudNativePG는 이 버전을 데이터베이스에 현재 설치된 버전과 비교하고, 다르면 필요한 ALTER EXTENSION ... UPDATE TO ... 명령을 자동으로 실행해요. :::

검증 (Verification)

app 데이터베이스에 연결해 PostgreSQL 카탈로그를 조회하면 컨테이너에 있는 PostGIS의 사용 가능한 버전을 쉽게 확인할 수 있어요. 예를 들어:

kubectl cnpg psql cluster-postgis -- app -c \
  "SELECT * FROM pg_available_extensions WHERE name ~ '^postgis' ORDER BY 1"

다음과 비슷한 결과가 반환돼요 (이 문서의 값과는 다른 값을 얻을 수도 있어요):

           name           | default_version | installed_version |                          comment
--------------------------+-----------------+-------------------+------------------------------------------------------------
 postgis                  | 3.6.2           | 3.6.2             | PostGIS geometry and geography spatial types and functions
 postgis-3                | 3.6.2           |                   | PostGIS geometry and geography spatial types and functions
 postgis_raster           | 3.6.2           | 3.6.2             | PostGIS raster types and functions
 postgis_raster-3         | 3.6.2           |                   | PostGIS raster types and functions
 postgis_sfcgal           | 3.6.2           | 3.6.2             | PostGIS SFCGAL functions
 postgis_sfcgal-3         | 3.6.2           |                   | PostGIS SFCGAL functions
 postgis_tiger_geocoder   | 3.6.2           | 3.6.2             | PostGIS tiger geocoder and reverse geocoder
 postgis_tiger_geocoder-3 | 3.6.2           |                   | PostGIS tiger geocoder and reverse geocoder
 postgis_topology         | 3.6.2           | 3.6.2             | PostGIS topology spatial types and functions
 postgis_topology-3       | 3.6.2           |                   | PostGIS topology spatial types and functions
(10 rows)

다음 단계는 Database 리소스에 나열된 확장이 app 데이터베이스에 올바르게 설치되었는지 확인하는 것이에요:

kubectl cnpg psql cluster-postgis -- app -c '\dx'

이 명령은 다음과 같은 결과를 반환해요:

                                        List of installed extensions
             Name             | Version | Default version |   Schema   |                  Description
------------------------------+---------+-----------------+------------+------------------------------------------------
 address_standardizer         | 3.6.2   | 3.6.2           | public     | Used to parse an address into constituent ...
 address_standardizer_data_us | 3.6.2   | 3.6.2           | public     | Address Standardizer US dataset example
 fuzzystrmatch                | 1.2     | 1.2             | public     | determine similarities and distance between...
 plpgsql                      | 1.0     | 1.0             | pg_catalog | PL/pgSQL procedural language
 postgis                      | 3.6.2   | 3.6.2           | public     | PostGIS geometry and geography spatial type...
 postgis_raster               | 3.6.2   | 3.6.2           | public     | PostGIS raster types and functions
 postgis_sfcgal               | 3.6.2   | 3.6.2           | public     | PostGIS SFCGAL functions
 postgis_tiger_geocoder       | 3.6.2   | 3.6.2           | public     | PostGIS tiger geocoder and reverse geocoder
 postgis_topology             | 3.6.2   | 3.6.2           | public     | PostGIS topology spatial types and functions
(9 rows)

마지막으로:

kubectl cnpg psql cluster-postgis -- app -c 'SELECT postgis_full_version()'

다음과 같은 결과를 반환해요:

                                                    postgis_full_version
------------------------------------------------------------------------------------------------------------------------
 POSTGIS="3.6.2 08d9b9f" [EXTENSION] PGSQL="180" GEOS="3.13.1-CAPI-1.19.2"
 SFCGAL="SFCGAL 2.0.0, CGAL 6.0, BOOST 1.83.0"
 PROJ="9.6.0 NETWORK_ENABLED=OFF URL_ENDPOINT= USER_WRITABLE_DIRECTORY=/tmp/proj"
 (compiled against PROJ 9.6.0)
 GDAL="GDAL 3.10.3, released 2025/04/01 GDAL_DATA not found"
 LIBXML="2.9.14" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)"
 TOPOLOGY RASTER
(1 row)